3
votes

I have a Native C Dll that is dynamically loaded by a legacy application. The intent of this dll is to allow overriding of application behavior based on certain application events. I have a C# dll that contains functions that I call from the Native C dll through the mixed mode C++/CLI dll to enhance these application events. The application using this architecture works flawlessly on Windows 2000.

The application also runs on Windows XP but unfortunately the application crashes(Unhandled Exception) once the Native C dll is loaded at application startup. It appears that it crashes when it is attempting to load the mixed mode dll. I have removed all dependencies to the mixed mode dll from the Native C dll and the application boots up fine. But once the dependency is added, the crash occurs. The code on Windows 2000 is the same as what is used on Windows XP. I don't have access to the application code but do have access to the Native C dll code but can't get the debugger to stop as the crash occurs before intialization has completed. I suspect it is something to do with CLR initialization and OS loader differences but am not certain. I'm looking for suggestions on how to go about resolving this. I am using VS2005 using the 2.0 Framework. I appreciate any help you could give.

The exception and stack trace is not real helpful:

Unhandled exception at 0x775125f6 in MyApplication.exe: 0xC0000005: Access violation reading location 0x775125f6.

775125f6()  
user32.dll!7e418734()   
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
user32.dll!7e418816()   
user32.dll!7e428ea0()   
user32.dll!7e42ce7c()   
ntdll.dll!7c90e473()    
user32.dll!7e42e389()   

...

2
...continue to scratch my head on this one... I wrote a little test harness to dynamically load the Native C dll and call an entry point similar to the what the application code performs. I am successfully able to do this. A bit confused on this one. Any ideas?user204534
came up with a solution after trying numerous items ... thought I would post my solution. The native C dll was previously statically linked to the managed C++/CLI dll - which would cause the access violation. Not sure if it was a form of the loaderlock problem - or CRT intialization?? Anyways, I removed the static link and am now dynamically loading the managed C++/CLI dll and calling the entry functions which then call into my .NET assembly. Works like a gem. I would still appreciate any ideas on how I might get this to work with the static link.user204534

2 Answers

2
votes

I've had this exact problem. I provided some additional information and workarounds on this question. But I'm happy to summarize and provide an answer here as well.

The basic problem you're encountering is there seems to be a bug or some variability in how the linker does it's job when linking native applications to mixed mode dlls and unmanaged dlls. It appears that this only happens when you have both mixed mode dlls and unmanaged dlls being linked by an unmanaged executable.

  • Option 1: Set the mixed mode dll to be Delay Loaded.
  • Option 2: Make the unmanaged exe a mixed mode executable, by having at least one file in it CLR aware. The file can be empty, it just has to be present to allow things to link correctly in the executable.
  • Option 3: Update the unmanaged executable so that it links the mixed mode library before linking any unmanaged libraries.

I've ended up using Option 3 to solve this problem, because it seemed the safest. Just go to the Project Properties dialog, select Linker->Input tab. Specify the lib file for the mixed mode dll in the Additional Dependencies field. Ensure that the mixed mode lib is the first lib listed in that field.

Set the Additional Dependencies field Like this: mixedmode.lib;unmanaged.lib;unmanaged2.lib.

This seems to resolve the issue with the unmanaged application crashing. If you rearrange the order of the lib's so an unmanaged.lib is first you'll end up back at the crash.

I hope this helps!

1
votes

Seems to me the symbol is not setup correctly. You might want to do the following first:

  1. install Debugging Tools for Windows http://www.microsoft.com/whdc/devtools/debugging/default.mspx
  2. open command prompt, change to the folder, run WinDBG -I
  3. run your program, let it crash, WinDBG will be triggered
  4. type .symfix
  5. type .sympath+
  6. type .loadby sos clr
  7. type !CLRStack -a
  8. type kb

Step 7 and 8 should get you a much more meaningful stack to debug with