Breakpoints not being hit in Visual Studio 2012 - c++

I have seen this question asked several times and I have tried all the nonsense that I have read, but I can't make it work.
I use Visual Studio 2012, in Debug mode. I compile the simple code
#include<iostream>
int main()
{
std::cout << "Hi" << std::endl;
system("pause");
return 0;
}
I put a break-point in line 4 (std::cout...) and I press F5 to execute.
The break-point is ignored and there is an exclamation mark next to it saying that "The breakpoint will not currently be hit. No symbols have been loaded for this document".
EDIT: In the output window after building I get a warning:
main.obj : warning LNK4099: PDB 'vc110.pdb' was not found with 'main.obj' or at 'Z:\Projects\Tools\DebugTest\Debug\vc110.pdb'; linking object as if no debug info DebugTest.vcxproj -> Z:\Projects\Tools\DebugTest\Debug\DebugTest.exe
However, if I go to Properties > Configuration Properties > Linker > Debugging, in "Generate Program Database file" I believe I have the correct "$(OutDir)$(TargetName).pdb" so I don't understand why the pdb file is not being created.

Try rebuild application.
Make sure it's in the debug configuration.
This can happen when the debug info files (.PDB) are out of sync with the real compiled binary.

Here is how I made the breakpoints work, in case this helps anybody, although I don't really understand what I am doing.
In project properties > C/C++ > General, in Debug Information Format setting, I changed "program database" to "C7 compatible". Symbols are now loaded and breakpoints are hit.
It would be great if somebody could elaborate on why this causes the symbols to load, whereas the former option did not.

Related

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

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".

What is the symbol `myLibrary!__scrt_stub_for_is_c_termination_complete+0x12345`

The symbol myLibrary!__scrt_stub_for_is_c_termination_complete+0x12345 appears in the stack trace of a crashed application. It is C++ compiled with MSVC2015 and heavily uses Qt.
myLibrary does not explicitly implement anything of that name.
Google shows some hits on this name, so apparently it is not particular to this one application. But I cannot find an explanation of it.
That is a "no idea where it crashed" diagnostic. The +0x12345 offset is far too large. Not uncommon at all, you need good PDBs to get accurate stack traces. Without them it doesn't know anything about the code you wrote and can only go by named DLL entrypoints.
Since the crash appears to be detected in the C runtime library, you might well get lucky by enabling the Microsoft Symbol Server and let it produce the PDB you need. Assuming you opened the minidump in VS, use Tools > Options > Debugging > Symbols to enable the server. General and WinDbg advice is available in this MSDN page.
Is a library name : myLibrary
Is a function name : __scrt_stub_for_is_c_termination_complete
Is a distance from function offset : +0x12345
If you enter the disassembly mode, then you can see a function's address
Also you can see in the (quick)watch to function name, same as disassembly
you can assuming exception raised from specific function and which line.
Watch out : If you debug in Release build , it would be hard to find which code raise the
exception. In this case you can compare your assembly between Debug and Release (I cannot explain how it works 'til describing.). Use Debug Build to ease to Debug.
Happy Coding :)

how to debug a c++ excel plugin's exception during excel exiting

I have an excel xll plug-in built in c++ (and with the help of xlw), which, runs pretty well except, when excel exits, exception happens occasionally.
My headache is that though it looks like some destructor issue, I can't see where it went wrong.
Excel window just closes then a Windows system error message pops out.
Even if I run it in Visual Studio debug mode, when the exception happened, it's already in the STL c++ code, also I can't see which part of my code, such as a destructor, is the root cause of the failure.
To be precise, Call Stack shows
[External Code] -> Excel.Exe -> [External Code] -> MSO.DLL ... repeat... OART.DLL... repeat ... ntdll.cll -> [External Code] -> _cexit() -> common_exit -> __acrt_lock_and_call -> ...
The first step with source visible is exit.cpp in C:\Program Files (x86)\Windows Kits\10\Source\10.0.16299.0\ucrt\startup\exit.cpp,
extern "C" void __cdecl _cexit()
{
common_exit(0, _crt_exit_full_cleanup, _crt_exit_return_to_caller);
}
Have you tried setting a conditional breakpoint in Visual Studio settings to break on any exception (or the specific exception you are getting)? You can enable this just before you exit Excel. This might help track down the problem and give you the call stack in the call stack window when the breakpoint hits.
Also make sure to check if your symbol files (.pdb) are getting loaded for your code and any third party dependencies. Another thing that can help is to specify the Microsoft public symbol servers so that the Microsoft system pdb’s are loaded as well as mentioned in this article.

CRT library: wrong version

During the compilation process of my application (Debug mode), I am getting the following error, related to the CRT library:
16>libcpmt.lib(stdhndlr.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in poStat.obj
According to the Microsoft MSDN topic, I need to set the runtime library to /MTd in order to append the correct library compiled with debug mode. I also have to define a _DEBUG flag - and thats exactly what I have done.
Even though I have did everything it requires to use the CRT with debug mode, its still trying to use one without the debug mode (libcpmt.lib instead of the libcpmtd.lib).
How can I fix this?
Update
When I go to the C:\Program Files\Microsoft Visual Studio 11.0\VC\lib and change the name of libcpmtd.lib to the libcpmt.lib (had to temporary remove the existing libcpmt.lib) it builds successfully in a debug mode.
As Hans Passant already pointed out, the reason you have this is because some of the .lib or .obj files you are linking were compiled with Release settings, and some with Debug. The real question for you now is how to find which libraries or object files need to be fixed. Here is one way to do this
link /dump /all "Path_To_Lib_or_Obj" | findstr /L "\/DEFAULTLIB"
This will print out all default libraries, including CRT. This command has to be executed for each .lib and .obj that appears on your linker build command. For Debug you should see something like:
/DEFAULTLIB:msvcprtd
/DEFAULTLIB:MSVCRTD
/DEFAULTLIB:OLDNAMES
...
and for Release:
/DEFAULTLIB:msvcprt
/DEFAULTLIB:MSVCRT
/DEFAULTLIB:OLDNAMES
...

Grabbing functions from dlls using GetProc and stepping into them?

I have the following code:
GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)lib.GetProc("GetNumberOfFormats");
if (getNumberOfFormats != NULL)
{
RINOK(getNumberOfFormats(&numFormats));
}
The function GetProc does this:
GetProcAddress(module, proceName)
when the function 'getNumberOfFormats' is called the debugger does not step into it, even if I press 'F11' on it. It also doesn't tell me I missed a callstack.
The function exists in a separate project and it links to that projects copmiled DLL. Any ideas why I can't step into the code?
Visual Studio can't find debug symbols for your DLL. Check whether PDB file is generated for your DLL and exists.
You can check the symbol loaded information while debugging from Debug->Windows->Modules. Right click on the desired DLL and configure the proper symbol if not properly loaded.