Debugging into MFC header code does not work with Visual Studio 2019 - c++

TL;DR: Debuigging into MFC (CString) header code does not work on both my machines and as far as I can tell this is due to the peculiar way these headers are compiled.
Stepping through MFC header code when entered via disassembly works, but setting brealpoints does not work.
I'm looking for a workaround or at least acknowledgement of my analysis.
System:
Visual Studio 2019 Professional 16.9.6
Windows 10 / 1809 Enterprise LTSC
Setup: (I do apologize for this being rather long.)
Create a Visual Studio 2019 Example MFC Application Project (SDI App)
Make sure Enable Just My Codeis off under Options -> Debugging -> General.
Set the build configuration to Debug/x64 (does not make a difference, but let's all stay on the same page)
Navigate to MFCApplication1.cpp -> CMFCApplication1App::InitInstance()
Insert a CString init like this:
...
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance(); // please put breakpoint 1 here
// Add this line and set breakpoints
CString this_is_text(L"Debugging into CString Header does not work!"); // breakpoint 2 here
Now, you can start the program under the debugger, and you should stop at the first breakpoint:
Now, make sure all symbols are loaded, easiest done via the Call Stack:
Just select all lines in the call stack window and hit Load Symbols in the context menu. Afterwards the call stack should look roughly like this:
> MFCApplication1.exe!CMFCApplication1App::InitInstance() Line 75 C++
mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 37 C++
MFCApplication1.exe!wWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 26 C++
MFCApplication1.exe!invoke_main() Line 123 C++
MFCApplication1.exe!__scrt_common_main_seh() Line 288 C++
MFCApplication1.exe!__scrt_common_main() Line 331 C++
MFCApplication1.exe!wWinMainCRTStartup(void * __formal=0x000000c2b7084000) Line 17 C++
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
Now, you can try stepping-into (possibly F11) the CWinAppEx::InitInstance() function, which should work without a problem, landing you in mfc140ud.dll!CWinApp::InitInstance() Line 394 - this is OK.
Step out again, and then then try to step-into the CString ctor:
This DOES NOT work on my machine(s)!
What I can do however, is (from the point above) switch to disassembly view, step into the calls there and get into the header code this way:
I can then successfully step through (but never into) the MFC header code. Trying to set a breakpoint will result in the error:
The breakpoint will not currently be hit. No executable code of the debugger's code type is associated with this line.
Possible causes include ...
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h
And this is where I'm at.
Analysis:
What we can see from the MFC code is that we can step into "regular" cpp code, but as soon as we try to step into (or set breakpoint) code that is inside this CStringt.h it breaks.
Peculiar here: This is template header code, and still the executed code (as shown by the disassembly) is not in the user module but in the mfc###.dll! I think they do some clever tricks with the preprocessor (see defined(_MFC_DLL_BLD) and somesuch) which enables this multi use of the header file, and maybe, possibly this is also what breaks the debugger.
Question:
Is this a known problem, does this happen with all VS2019 installs, is there something peculiar to my setup?
Maybe fixed in a newer VS version?
Iff this is actually broken, what would be a useable workaround, other than constantly switching to disassembly view when into the MFC headers.
The most interesting answer here would actually be as to WHY this breaks - where does the debugger get confused? Is this a general problem with re-define-ing code when debugging library code?

The source shipped with MSVC does not match.
I think this happen, as DLLs got updated with Windows Update or a new vcredist, but Visual Studio includes are not updated. If you build with /MT or /MTd and link MFC statically, the problem does not persist.
Probably this can be reported to http://developercommunity.visualstudio.com if you care.
Workaround 1
Do steps described by #selbie:
Set a breakpoint on the line of code I want to step into.
When
the breakpoint is reached, right click in the editor window and select
"Go To Disassemly".
In disassembly mode, step over until you get to
a call statement. [...] You
can flip out of disassembly mode by right-clicking again and selecting
"go to source code".
(skipped the part not relevant to this issue)
Then pick up the location of the header manually, the debugger will tell that it does not match. The difference seem to be insignificant though, so the header is usable.
Workaround 2
Link MFC statically, compile with /MT or /MTd
Workaround 3
ATL has a similar CString that does not suffer from the issue:
#include <atlbase.h>
#include <atlstr.h>
int main() {
ATL::CString this_is_text("Debugging into CString header works");
}

Analysis went sideways at some point, but we finally found one part of the problem here:
The Require source files to exactly match the original version option:
was the problem, but in a very peculiar way:
When you do NOT require source files to match (that is, disable this default option), then the erroneous behavior of the OP occurs: The debugger can no longer match the symbols to the cstringt.h file.
Unfortunately, I had this disabled on both machines. Pulling in a third machine showed that we could set breakpoints (though F11 still does not work) and by comparing the xml export of the VS settings we found that this was different.
So, long story short: For us, to be able to set breakpoints in the (unmodified!) MFC header, requires us to enable the Require source files to exactly match .. option.
If the option is disabled, which would imply a more lenient behavior by the debugger, it no longer works.
And, yes, we double checked it's always the same source file at C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h
The mystery with step-into/F11 persists, but I guess this would better be taken to a separate question.

Uncheck the Enable Just My Code option in Tools->Options->Debugging
I know that works for c++ std:: library code debugging. The other technique I do, when I forget to uncheck this option, is similar to what you describe above.
Set a breakpoint on the line of code I want to step into.
When the breakpoint is reached, right click in the editor window and select "Go To Disassemly".
In disassembly mode, step over until you get to a call statement. That's typically the std library. Eventually, you'll navigate into a mix of assembly and system code sources. You can flip out of disassembly mode by right-clicking again and selecting "go to source code".

Related

Issue setting breakpoint in Visual Studio (C++)

I have a Visual Studio 2012 project in release mode. I cannot convert it to debug mode for some reason.
When I'm debugging and I try to put a break point on function A, I cannot put it there - The breakpoint moves itself to function B which is exactly the same in content (i.e. function A and funciton B are exactly same just have different names).
I do understand that it must have optimized out the code, but I am using an option called as /od which means it should have suppressed code movement.
How can I put a breakpoints on function A?
You can try disabling the optimization options.
- Right-click on the project->properties.
- Configuration Properties
- C/C++
- Optimization
- Optimization-> Select Disabled(/Od)
This should avoid that the compiler remove code.
But, still, in release mode you are not sure if the displayed data is correct.

What's the cause of a D8049 error in visual studio?

I'm creating a project with openframeworks (the full source is here: https://github.com/morphogencc/ofxAsio/tree/master/example-udpreceiver), and the empty project seems to compile fine.
I added the ASIO library, and a few header classes, and now the project seems to be give me the following error:
1>------ Build started: Project: example-udpreceiver, Configuration: Debug x64 ------
1> main.cpp
1>cl : Command line error D8049: cannot execute 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\c1xx.dll': command line is too long to fit in debug record
1>cl : Command line error D8040: error creating or communicating with child process
I couldn't find any examples of error D8049 on stackoverflow or even on Microsoft's pages, and google turned up painfully few results. The only remotely useful one was this github issue:
https://github.com/deplinenoise/tundra/issues/270
But I'm still not sure what's causing the problem. Is anyone familiar with this error, and can recommend a method for troubleshooting what's causing it?
thanks in advance!
For me, working with UE4, this was an intermittent error.
I added "bLegacyPublicIncludePaths = false;" to the innermost block of project.Build.cs and recompiled without errors.
Then I removed that line and compiled again w/o errors.
The error message suggested adding "DefaultBuildSettings = BuildSettingsVersion.V2;" to project.Target.cs which worked.
This is a bit of a weird sounding error, as it is from essentially internally generated data. However, you do have control over that. Taking the error message at face value, you probably have many/lots of defined symbols passed in on the command line (or the the ones you do have have lengthy definitions), or you may have some lengthy file paths.
If you look under the project properties, one of the selections under the C++ section is "Command Line", which will show you exactly what gets passed to the compiler. When you view that you can see where you have many or lengthy parameters, and then make changes to shorten them.
Too many defines? Put them in a header (possibly stdafx.h) and include them that way.
Long file paths? Shorten the paths, put the files somewhere else, or set up file system aliases to your real directories that use shorter paths.

C++ Error RC2104 trying to compile PuTTY-PSCP (for Windows) on Visual Studio 6.0

I was about to use PuTTY Development source code for Windows to create my own client application (found here: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) but as I tried to compile the PSCP project (SCP Client), I got the following error :
C:\work\2015\Putty\windows\version.rc2 (18): error RC2104 : undefined
keyword or key name: BINARY_VERSION
I've been going through the various posts involving this error but didn't find anything working :
error RC2104: undefined keyword or key name: DS_SETFONT :
On this post I noticed that the version of MSVC was brought up so I figured maybe something has to be done to get PuTTY to work on VC 6.0 ?
Also I tried to add #include <windows.h> in both version.rc2 (version.rc2 is used for inclusion in all .rc files) and pscp.rc, none worked.
I'll be quick to answer if you need any information (project properties, source code...)
USING Visual Studio 6.0 with SP6 on Windows 8.1
Probably, wrong version.h is seen.
Correctly, the file version.h in the project folder should be seen.
Please try to modify version.rc2:
#include "version.h"
to
#include "..\\..\\..\\version.h"
At least, resource compiler will end successfully.
If you search through the PuTTY source files, you'll notice that BINARY_VERSION is defined in version.h and used in windows/version.rc2, which #includes version.h.
Since your version.rc2 isn't seeing version.h, try to figure out why: Is version.h still present and does it still contain BINARY_VERSION? Are your include paths correct? Is there another version.h somewhere else in your include path that's getting picked up by mistake?
Which source code are you using ?
I tested latest(0.64) "Release source code for Windows".
direct link is
http://the.earth.li/~sgtatham/putty/latest/putty-src.zip
I had tried to compile using VC++ 6.0 Professional with SP6, on my PC,
running Windows XP SP3.
After extracting putty-src.zip to somewhere with keeping folder
structures, did you correctly opened 'putty.dsw' in "putty-src\windows\MSVC" folder?
You should be find in 7 projects in 'FileView' tab of the workspace
in Visual Studio 6.0.
You can switch active project to 'pscp' with context menu via
right button click on 'pscp' project.
With modified version.rc2, resource compiler finished successful.
But two (sshshare.c, winsftp.c) C source files failed compiling
with 20 errors. in 'pscp' project.
Errors while compiling 'winsftp.c' is caused 'TIME_POSIX_TO_WIN'
and 'TIME_WIN_TO_POSIX' macros.
'ull(unsigned long long)' is a 64-bit integer-suffix, newly defined in C99. Since C99 standard is not support on VC6, then caused errors.
I had temporally modified
11644473600ull ------> ((ULONGLONG)11644473600)
10000000ull ---------> ((ULONGLONG)10000000)
and confirmed errors are cleared. (Sorry, no validation the code is correctly generated)
3 errors while compiling 'sshshare.c' is also caused another macro.
I cannot understand why you got 116 errors.

F11 Debug line by line only my .cpp?

I am developing an OpenCV application and I need to debug my code (Visual studio 2010, opencv with cmake).
I would like to debug line by line to see where exactly my app crashes. I am trying to use F11 the problem is that F11 shows me external code (opencv libraries, std libraries etc).
Is there any other way to don't put lots of breakpoint all over my code?
int main(void) {
vector<int> myVec;
myVec.push_back(1);
//> Do other stuff
}
If I try F11 with this code, visual studio will debug the vector library files too, and I want to avoid that. I just want to follow the flow of the code inside my main();
Hi as already mentioned in my comment in VS2010 the only way to avoid stepping into STL code is to modify a registry key, as described in this post.
With VS2012 there is another way by using Visualizers.
You cannot go into external code (unless maybe showing it as assembly).
You should use F10 to step to the next instead of going inside such a function.
You also can use Shift + F11 to return to the next line (after the current function), if you are inside such external function code.

How to repair Visual Studio locals/watches in C++ (Debug build)

Sometimes VS autos/locals/watches break and instead of variables/values all I have is different kinds of:
CXX0029: Error: not struct pointer
CXX0033: Error: error in OMF type information
CXX0072: Error: type information missing or unknown
CXX0025: Error: operator needs class/struct/union
Rebuilding project, cleaning PDB/NCB etc doesn't solve it. What can I do?
Look at this Microsoft support note on: FIX: CXX0033 Error in OMF Type from Forward Class Declaration
Once you fix the PCH problem cited in the support note, I think all your errors will go away.
There is in fact a solution that lets you keep using precompiled headers: check out this more recent KB article and the documentation of the /Yl switch - which seems specifically tailored to this error.
Just add to the stdafx.cpp (or your own custom /Yc file) command line '/Ylxxxx', where xxxx stands for an arbitrary function name in your lib.
I recently faced symptoms identical to yours (in VS2010), and that solved it for me.
Are you trying to debug the "release" build? If so, many local variables will not exist as "debuggable" elements. You can get around this (if you must debug the release build) by debugging at the assembly level and look at the register values (vs. stack values, where auto/local would be in the debug build) and cast them appropriately in the "watch window".
Otherwise, build the Debug build and debug that build version. You'll get assertions where preconditions are not met, relevant/irrelevant stuff dumped to your output window, and more straight-forward debug single stepping.
It helped me to switch from using a program database (/ZI) to "c7 compatible" (/Z7). Switching off precompiled headers did not make a difference. Neither did rebuilding.