0

I have a 32-bit application and I have a problem with it on Windows 7 x64. I'm loading a DLL. LoadLibraryW succeeds and the subsequent call to GetProcAddress fails with the error code 127 ("procedure not found" or something like that).

The funny part is that I know for a fact the function is exported by the DLL. I made no typos in the GetProcAddress call. I can see the function with Depends.exe and DllExp.exe. The exact same application binary successfully loads the function from the exact same DLL on Windows 10 x64, but not on Windows 7 x64.

Some more details: the library is dbghelp.dll and the "missing" function is MiniDumpWriteDump.

And the fun bit: dbghelp.dll provides API for inspecting the modules loaded into the process and for enumerating functions exported by those modules. So, first I took the HMODULE for this problematic dbghelp.dll and ran

auto ptrSymInitialize = (decltype(&SymInitialize))GetProcAddress(hDbgHelpDll, "SymInitialize");

It worked, this function did load! Then I loaded SymEnumSymbols, written the enumerator callback and finally ran the following to enumerate all the functions in this very `dbghelp.dll":

ptrSymEnum(GetCurrentProcess(), 0, "dbghelp*!*", &Enumerator, nullptr);

And what do you know, MiniDumpWriteDump is, in fact, listed there. Go figure.

Thoughts?

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • @downvoter: how is this question off-topic? – Violet Giraffe Feb 24 '17 at 15:11
  • `successfully loads the function from the exact same DLL on Windows 10 x64` - same by name ? our you copy your dll from win 7 to win 10 ? – RbMm Feb 24 '17 at 15:16
  • If you are not currently, try loadlibrary with the absolute path to the syswow64 copy to ensure the version you are loading is what you expect (and verify it has not has not already been loaded into your process by a debugger or some such). – Alex K. Feb 24 '17 at 15:16
  • general solution for this kind of problems set `ntdll.ShowSnaps` to -1 and look under debugger what happes – RbMm Feb 24 '17 at 15:22
  • Clearly the DLL does not import that function. – David Heffernan Feb 24 '17 at 16:06
  • 1
    It doesn't actually contain that function on Win10, dbgcore.dll does. A forwarder makes that detail invisible. Do keep in mind that it is easy to look at the wrong dbghelp.dll file, there are two (32-bit and 64-bit). And I suspect it could get corrupted by a wonky installer because it didn't used to be included with the OS. And watch out for a stray copy that got loaded instead of the one from c:\windows. I'll stop guessing now. – Hans Passant Feb 24 '17 at 16:19
  • @RbMm: I've copied this DLL file to the Win 7 system and loaded it by full path to make sure I load this one and not the one from syswow64. I have also verified with the Visual Studio debug output module loading message that my `LoadLibrary` call indeed loads the right DLL. What's `ntdll.ShowSnaps`? No idea what you mean. – Violet Giraffe Feb 24 '17 at 16:20
  • @DavidHeffernan: you mean doesn't export it? Clearly you're wrong and didn't read the whole question. – Violet Giraffe Feb 24 '17 at 16:20
  • Error code 127 can't be argued with. The module you pass to GetProcAddress doesn't export that function. How hard can it be to understand that. – David Heffernan Feb 24 '17 at 16:22
  • 1
    @HansPassant: thank you very much! I have checked some of the concerns you mentioned (but not some others), and I am now 99% sure that the problem is this `dbgcore.dll` which I did not copy to the Win 7 system nor included in my installation. – Violet Giraffe Feb 24 '17 at 16:22
  • @DavidHeffernan: want a a screenshot from Depends.exe where you can clearly see that it _does_ export it? And how do you explain that the same .dll file exports a function on Win 10 but not Win 7? I think Hans Passant nailed it. – Violet Giraffe Feb 24 '17 at 16:23
  • 1
    @VioletGiraffe - yes `MiniDumpWriteDump` is forward export to `dbgcore.MiniDumpWriteDump` if `dbgcore.dll` is missing - this explain all – RbMm Feb 24 '17 at 16:24
  • 1
    Oh please. The module you passed to GetProcAddress doesn't export the function. Some other dll might but you didn't load that dll did you. You think GetProcAddress is lying to you? – David Heffernan Feb 24 '17 at 16:26
  • @DavidHeffernan: Is Depends.exe lying to me? Is `SymEnumSymbols`? – Violet Giraffe Feb 24 '17 at 16:26
  • 1
    No. But they presumably are reporting on a different dll. – David Heffernan Feb 24 '17 at 16:32
  • MSDN lists both DLLs as potential providers of the function. I'm guessing they want you to try each in succession until you get the function you want. This is the conclusion I would have reached anyway, given the information in this question, since they don't document the conditions for which includes which. So no, it's likely nothing is truly wrong :/ If anything, Microsoft should change the language from "DbgHelp.dll and Dbgcore.dll" to "DbgHelp.dll or Dbgcore.dll" if `GetProcAddress()` doesn't handle forwards... – andlabs Feb 24 '17 at 20:05
  • @andlabs - GetProcAddress() of course handle forwards – RbMm Feb 24 '17 at 22:19
  • @HansPassant: would you care to post your comment as an answer? – Violet Giraffe Feb 25 '17 at 11:23
  • I have no idea what the actual answer looks like, I just posted a bunch of guesses. It actually sounds like you've been copying the Win10 version of dbghelp.dll to a Win7 machine. Pretty bad idea, use the redistributable version instead. – Hans Passant Feb 25 '17 at 11:32
  • @HansPassant: that's exactly what I've been doing, and I didn't bring `dbgcore.dll` along. Why is it a bad idea? Will it not work? – Violet Giraffe Feb 25 '17 at 11:39

2 Answers2

2

I can see your intent is to use MiniDumpWriteDump. We also make minidumps in our product, and I'm the one to support this.

I would suggest against using dbghelp.dll supplied with OS. First, they tend to be outdated and not support the latest minidump capabilities, which you would want to have. Second, they have proven to be rather unreliable. I believe they simply lack too many bugfixes.

What I found to work quite well is to take dbghelp.dll from Debugging Tools for Windows package (currently part of Windows SDK) and ship it along with our product. This way, I can be sure minidumps will have all the latest features and it works reliably on all OS. It has been some 8 years now, with OS ranging from WinXP to Win10, and I didn't have any issues.

I'm not exactly sure which version of SDK I used to extract the currently used dbghelp.dll, probably it was Win7 SDK. I simply didn't have a reason to update since then. However, we do use Debugging Tools for Windows package from Win10 SDK on Win7 without any issues, so I guess you can use Win10 version as well.

Codeguard
  • 7,787
  • 2
  • 38
  • 41
  • Thanks for the answer. Curious: do you manage to actually get useful information out of these minidump files obtained from a release application build outside of your dev machine? For me, it always either fails to display any symbols at all, or it does load symbols and points to a specific line of code that's clearly wrong (yay release compiler optimizations). So my question is: what kind of useful info did you manage to get? I'm not asking about your know-how, just what is principally possible. – Violet Giraffe Feb 25 '17 at 17:12
  • I'm a C++ developer, and that's sorts of different world. Optimizations (sometimes) obscure stack/local variables, but it's totally possible to find everything with enough effort. Also, stack is usually pretty reliable, and often this along with exception info is enough without extra digging. – Codeguard Feb 25 '17 at 18:26
  • The other option is to disable optimization. Can sound silly, but in fact this is merely a question of what poses a bigger problem for you: slower applications (for many applications, it won't even be noticable!) or debugging optimized code – Codeguard Feb 25 '17 at 18:32
  • If you're a C++ developer, then you should do fine (with some training) debugging optimized code. I suggest to see how it goes first, and read some WinDBG / assembly tutorials. – Codeguard Feb 25 '17 at 18:54
1

that's exactly what I've been doing, and I didn't bring dbgcore.dll

This was just a plain bad idea. Microsoft makes no effort to make the DLLs that are included with the OS to be backwards compatible. They don't have to. In their implementation, only the interface needs to be compatible. They do take advantage of new capabilities or design changes to improve the implementation.

Like you saw here, a side-effect of the MinWin project. There is no reasonable guess where that ended, if it happens to work now on the Win7 machine then you got lucky. Maybe you won't be so lucky on a Win7 machine without SP1, maybe some minwin glue DLLs are missing on a clean install, maybe the minidump itself is affected negatively some way. Impossible to predict.

So never do this. Afaik you should not be doing this at all, a Win7 machine already has dbghelp.dll available. Not 100% sure, it has been too long and Win7 is rapidly turning into the new XP. If you find it to be necessary then always use the redistributable version. Included with the SDK's Debugging Tools for Windows. Copy it into the same folder as the EXE that needs it so you don't mess up a machine.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536