I have a severe problem with mixed debugging in MSVC2013. After a call to a COM method from a native C++ DLL, debugger does not stop at breakpoints any more.
Code structure
The picture above presents the overall structure of the code.
I have a single solution with about ten C# projects, about fifty C++ native projects, and one C++/CLI project serving as a bridge between managed and native worlds. Startup project is a C# WPF project (GUI Application), it calls C++/cli project (Bridge) internally, which in turn calls various native C++ Dlls (Various libraries). Alternatively, I can make a C++ console application (Service console app) as startup project for testing purposes only.
I have implemented a library to import some information from Autodesk Inventor document files. Inventor Apprentice COM server (Inventor Apprentice on picture) is used to achieve it, which was freely downloaded alongside with Inventor View 2015. As a first step, the import was implemented in a standalone native C++ console application, and everything worked fine. Then it was adapted to be used in the whole infrastructure as a native C++ dll (Import library), and the debugging hell started.
Symptoms
"debugging broken". In a debug build, after calling the following COM method in Import library:
auto pComponentDefinitions = pDocument->GetComponentDefinitions();
breakpoints in C++ code are no longer hit. Even if I set a breakpoint in the code of another DLL, it is not hit. Breakpoints still visualize as full red circles, so this is not related to PDB issues.
The application itself continues to execute, and some time later I can see the correct results of data import visible in GUI, meaning that Import library has executed correctly. After that, I can pause the GUI Application with Break All button, in which case the main thread is shown stuck deeply inside one of the Inventor's dlls (rse.dll), which cannot be true because that thread has finished import and has even returned correct results.
In the Output window, I can see the following messages, appearing during the problematic COM method call (access violations seem to be normal in Apprentice):
First-chance exception at 0x000007FEDD451F0C (rse.dll) in GUIApplication.exe: 0xC0000005: Access violation writing location 0x000007FFFDE3AFCC.
The Common Language Runtime cannot stop at this exception. Common causes include: incorrect COM interop marshalling and memory corruption. To investigate further use native-only debugging.
First-chance exception at 0x000007FEDD455F6C (rse.dll) in GUIApplication.exe: 0xC0000005: Access violation writing location 0x000007FFFDE3EE6C.
I have tried to embed breakpoints into the code at the moment of compilation, by inserting __debugbreak() before and after the problematic import code. The first one is hit (if debugging is not yet broken), but the second one is not. On the other hand, debugger clearly notices it, because it writes the following message to Output window:
The process hit a breakpoint the Common Language Runtime cannot continue from.
This may be caused by an embedded breakpoint in the native runtime or a breakpoint set in a can't-stop region.
To investigate further, use native-only debugging.
Google gives no results at all for this diagnostic message. It sounds like MSVC thinks it is debugging managed code, which is actually native.
"crashes in call". In case of release build, running the application in mixed debugging mode results in a crash inside rse.dll during the problematic COM call.
Reproducibility
I use MSVC 2013 update 4. Project is built in x64 mode. Net Framework v4.0 is used. Inventor Apprentice from Inventor 2015 is used.
Experimentation shows that:
Everything is OK when no debugger is attached.
Everything works correctly (including debugging), when native-only debugging is used (either via Service console app or after attaching to already running process in native only mode).
In mixed (i.e. native + managed) debugging mode the problem reproduces regardless of whether GUI application was started with debugging or debugger was attached to a working process.
There is a problem both in debug and release modes, but it acts differently. In debug build crazy debugging issues arise ("debugging broken"), but in release it simply crashes somewhere inside ("crashes inside").
Full list of runs performed can be seen here.
The main question
Has anyone seen similar behavior before? What may be the cause of such behavior? Is there a way to fix it?
Disabling the new managed debugging engine of MSVC has helped to fix the issue. It can be done by going to Tools > Options > Debugging > General > tick "Use Managed Compatibility Mode".
While trying to find a workaround for the issue, I have posted the following question. Hans Passant has posted not only a workaround, but also a solution to my main problem. It seems that new debugging engine is not properly working in case of C++/CLI interop.
P.S. Given that the symptoms are quite unique and crazy, I decided to post the full question with the answer, hoping that this information may help some people with similar problems in future.
Related
I've got a C# DLL with native exports, which is called from some Delphi 2009 code. The Delphi code uses LoadLibrary and GetProcAddress to access the exported functions. I'd like to debug the managed part of the code at runtime, but I'm running into trouble.
When I launch the application, the breakpoints appear properly, but fail to be hit.
My current setup is the following:
C# DLL project in Visual Studio 2010
Project's debug settings set to "Start external program", pointing at the Delphi executable.
Enabled unmanaged code debugging is switched off.
Just My Code is enabled in the debug options (this seems to make no difference)
I've tried enabling unmanaged code debugging, but that causes an error saying "binary was built without debug information". If I continue, all breakpoints are disabled.
When I checked the modules list, the executable shows as having no debug symbols. Delphi doesn't generate a PDB (it can't, since it's a closed-spec proprietary format) but it generates a MAP file instead. I had a look around for MAP-to-PDB converter tools, but it seems there's only a tool for doing the reverse of what I need.
I'm not really interested in debugging the Delphi code from Visual Studio, since I can already do that in the CodeGear Delphi IDE, but is there a way to debug the managed code at runtime in this situation?
Ok, I found a solution. The issue wasn't with debug symbols, but rather the type of code being debugged. If you launch an application from your project startup settings, the debugger starts in mixed mode, which requires native symbols to be available in order to catch C# code invoked from native code.
I wasn't able to get Visual Studio to accept the pdb files created by tds2dbg, so I found a workaround. In order to ensure that the debugger launches in managed mode, attach to the process instead of launching it, like so:
Debug -> Attach to process...
Select the running process.
Click the "Select..." button to the right of "Attach to".
Select "Debug these code types"
Check Managed (v2.0, v1.1, v1.0) for .NET 3.5 or less, or Managed (v4.0) for .NET 4.0 or later. Not sure why v3.5 is excluded from the naming here.
Click OK, click Attach.
After this, all breakpoints should work nicely :)
There is a "tds2pdb" you can try to create a .pdb file:
http://code.google.com/p/map2dbg/downloads/detail?name=tds2pdb102.zip
Note: it's not a complete .pdb file (specs aren't available) but at least it is working for stack traces. However, not all symbols (classes, variables, parameters) are exported. But you can always try...
I have the following three projects in my solution:
1. C# library
2. C++/CLI managed code
3. C++ unmanaged code
I did check "Enable Unmanaged Code Debugging" in my C# project, and built both C++ projects in Debug/Win32. However, I cannot step into unmanaged code - when I F11 on the call of any unmanaged method, it shows me some random/wrong code then exits.
Because my unit tests pass, I know that my unmanaged code does execute.
What am I missing?
When I've had this problem it has come from one of these things:
1) Enable unmanaged code debugging not checked. You already fixed this.
2) Built the EXE as x64 or Any CPU (they say x64 works, but it doesn't). I think you already fixed this.
3) "Just my code" being turned on sometimes causes trouble with unmanaged code debugging (Tools, Options, Debugger, Just My Code)
4) Incorrect debug options in the C++ project settings
5) Missing, corrupted or mismatched PDB files. You can check for this by trying to set a breakpoint in your C++ code while running in the debugger. If the breakpoint turns into a hollow circle, something is wrong with your debug info. Also check your output window as you run in debug mode -- it should tell you whose symbols got loaded.
I've seen this issue going the "other" way from time to time (ie, from native C++ to C++/CLI) and it's usually caused by the debugger not really picking up that it's supposed to debug both native and managed code.
Usually for me, setting the Debugger Type in Configuration Properties -> Debugging in your startup project from 'Auto' to 'Mixed' solves the problem.
My main startup project is in c++. the solution involves also managed c# code.
When I debug - I have breakpoints only on the unmanaged sections (on managed breakpoint it states : "The breakpoint will not currently be hit. invalid file line "
I checked the reference and saw that there is dll and pdb there.
What could it be?
how to set mixed-mode debugging
http://msdn.microsoft.com/en-us/library/kbaht4dh(v=vs.100).aspx
And don't miss the link in the bottom.
If, like me, you are trying to debug a C++/CLI from a native C++ project (i.e. you've set /CLR on a single file), and it never hits breakpoints and can't be stepped into. Well my friends, in VS2015 go to
Tools->Options->Debugging->General
and tick the little box that says:
Enable .NET Framework source stepping
I believe you also need to set it to mixed-mode debugging ala the answers above, but that alone was not enough for me. With that box ticked I can go "step into" from my unmanaged C++ into managed code... there is a crazy amount of technology going on under the hood here...
You have to enable mixed-mode debugging. I can't recall where that is, offhand.
I have had many issues with mixed mode debugging. Indeed, some programs get instable (Excel interop mainly for me), and you cannot Edit and Continue any more.
One good way to debug managed and unmanaged mode at the same time is to setup a new dummy project, which will attach a unmanaged debugger to your application. You can debug the managed code with your old project, detach it and attach the native debugger when you want to debug the native code. This way, you also have edit and continue for both codes.
Instructions on setting this up are there.
I am writing a Windows CE application in C# that references a native C++ DLL (that I am also coding) using the following method:
[DllImport("CImg_IP_CE.dll")]
public static unsafe extern void doBlur(byte* imgData, int sigma);
This actually works fine but I am unable to debug the DLL. When I check the debug modules that are loaded after running the EXE, CImg_IP_CE.dll is not one of them. Even after calling functions successfully from the DLL it still does not show up in the modules list.
Upon looking around, it seems that the LoadLibrary() function might work, but I cannot find any examples of using this in a C# Windows CE application. How would I do this or is there a better way to make sure the DLL loads up for debugging?
I found the answer through this post:
http://www.eggheadcafe.com/conversation.aspx?messageid=31762078&threadid=31762074
In summary, the same question was asked and the response was:
No, you can't step from managed code through a P/Invoke call into native
code in the Smart Device debugger. You might be able to use Attach to
Process to do the native debugging (with the native DLL project loaded into
that instance of VS2005), or simply write debug information from the native
DLL to a serial port or something. This really doesn't come up very often,
though, where you actually need to step from one to the other.
Further along in the thread, someone figured out how to accomplish this:
A quick test shows that the easiest way to handle this is to 'run' your DLL.
That is, set the debugging options to start the managed code EXE that will
use your DLL and set your breakpoints in the DLL (all from the DLL project,
of course). Naturally, when the EXE starts, your DLL won't be loaded, so
you'll see the breakpoints as hollow circles with ! on them, but, when you
call any of the native functions in your DLL, the DLL will be loaded (it's
not loaded on startup), and the breakpoints will be set.
So strangely, when you run the C# program and make a call to the native DLL code, it still does not show as loaded in the debug modules window. However, if you set the DLL project as the startup project, and then set the Remote Executable as the EXE file in the Debugging options, now when you first call the DLL, it will load up in the debugger. Okay... whatever works!
Unfortunately, it seems that WinCE mixed mode debugging is not supported. That is, you can debug your process either as managed (so you can step through and set breakpoints in your C# code), or as native (so you can do the same for native code, including this DLL), but not both at the same time.
To run debugging in native mode on a C# project, you can do this: start application without debugging (Ctrl+F5 or Debug -> Start Without Debugging), then Debug -> Attach to Process, set "Transport" to "Smart Device", select the emulator from the "Qualifier" dropdown, click on "Select" button on the "Attach to" field, and check "Native". You will observe that it won't let you check both at the same time, but if you only need to debug the DLL, it may be sufficient...
If you are able to call the function in the DLL without it throwing an application, you are most likely loading the DLL. You may need to make sure that unmaanged debugging is enabled in your project properties though.
Unable to set breakpoints in C DLL used by C++/CLI called from C#
I am using a third-party DLL. For some particular cases, a function in the DLL is throwing an exception. Is it possible to debug the DLL in the Visual Studio?
After the answer from Andrew Rollings, I am able to view the code, but is there any easy way to debug through the code in Visual Studio?
If the DLL is in a .NET language, you can decompile it using a tool like .NET Reflector and then debug against the source code.
Or you could ask the vendor if source code is available. That's probably the easiest way.
Building on Andrew's answer, you just treat the decompiled source code as a new library within your project and set breakpoints in the source. Remove all references to the 3rd party DLL so that it is the decompiled code that is executing.
Other things:
You may be breaking the law by decompiling the code, or breaching a licensing agreement with the 3rd party vendor. Make sure to review this with someone.
You will want to make sure that you remove references to your decompiled version if you are shipping to other developers, or checking into a larger source tree. Easy to forget this!
There are two methods I've come across:
1) Accessing the DLL project from the using project.
This involves building the DLL in a separate instance of Visual Studio and then accessing the DLL through a different project in Visual Studio (this assumes you have the source code).
There a number of ways to accomplish this:
You can add Trace.WriteLine
statements in the DLL that will show
up in the 'Output' window in Visual Studio.
You can add System.Diagnostics.Debugger.Break() statements to the DLL code. When
running the calling project in Visual Studio,
program execution will stop there.
From here you can add access the
call stack (including all function
calls in DLL itself) and set break
points (although the icon for
the breakpoint will appear disabled
and the hover text for the break
point will read "The breakpoint will
not currently be hit. No symbols
have been loaded for this document").
If the DLL is throwing an exception (which you can see from
the 'Output' window if the exception
is caught and handled by the DLL)
you can tell Visual Studio to always break when
that type of exception is thrown.
Hit Ctrl + Alt + E, find the type of
exception being thrown, and click
the 'Throw' column for that
exception. From here it is exactly
as if you had used
System.Diagnostics.Debugger.Break()
(see above).
2) Attaching a using process to the DLL project.
This involved hooking the Visual Studio debugger into a running process.
Open the DLL project in Visual Studio.
Run an application that uses the DLL (this
application can't be run from
another instance of Visual Studio since the
process will already have a debugger
attached to it).
From here you can add break points and step through
the DLL code loaded in Visual Studio (although
the break point will appear disabled
the same as in method 1).
Something that has worked for me with debugging a couple of third-party libraries as well as .NET itself is WinDbg. It is an awesome debugger from Microsoft that I have used to troubleshoot some sticky problems that were occuring deep inside the framework.
You need to use the Son of Strike (SOS) extensions if it is a managed DLL. It can debug native also. You will need to know a bit about callstacks and assembly/CIL instructions to be good at using it. You should be able to determine the exception and what is causing it. We have used WinDbg/SOS to find for instance that in HttpWebResponse, if you are using Gzip compression to download a page and the server returns a bad Gzip header, .NET runs the decompression in the threadpool and a crash will take out your process. Happy debugging.
One more option we should mention here is dotPeek 1.2 (a free decompiler from creators of ReSharper). Here is a nice post describing how to configure VS symbol server and dotPeek 1.2 to debug decompiled code from VisualStudio: http://blog.jetbrains.com/dotnet/2014/04/09/introducing-dotpeek-1-2-early-access-program
As Cesar Reyes mentioned in Stack Overflow question Visual Studio - Attach source code to reference, ReSharper 5 (and later) has this capability.
.NET Reflector 6 comes with a Visual Studio Addin that lets you use Visual Studio's step-through-debugging on assemblies that you don't have the source code for.
Have a look at this blog post:
http://www.simple-talk.com/community/blogs/alex/archive/2009/09/22/74919.aspx for more details.
This is still a very early build. So no guarantee that it'll work, and it might break your visual studio configuration or project configuration. Make sure you have backups (or source control) for any projects you use this on.
Download here:
http://www.red-gate.com/MessageBoard/viewforum.php?f=109
I thought .NET Reflector got some debugging plugins. That'd be a so much better idea because decompiling and recompiling code generally fails, and you need to do so many changes in the code to fix it.
Give .NET Reflector debugger a try. It might help you a lot.