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.
Related
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".
Is there any way to turn off asserts instead of switching to Release mode. I need to debug a code which make assertions really often and it slows down my work.
These asserts are not related to the issue i am trying to solve, so for now they only slow down my progress, because they are called very often in one of my base classes.
Now I don't have the time to improve their design, so can someone tell me if there is a way to turn off asserts while being in debug mode and using it's capabilities.
User _CrtSetReportMode
int iPrev = _CrtSetReportMode(_CRT_ASSERT,0);
// Start Operation with no ASSERTs
...
// Restore previous mode with ASSERTs
_CrtSetReportMode(_CRT_ASSERT,iPrev);
Instead of using 0, you can use _CRTDBG_MODE_DEBUG only.
You can use _set_error_mode or _CrtSetReportMode (see xMRi's answer) to alter failure reporting method and avoid modal dialog box. See code snippet there:
int main()
{
_set_error_mode(_OUT_TO_STDERR);
assert(2+2==5);
}
Also note that assert failures are typically for a reason, and you want to fix code, not just suppress the report. By removing them from debug builds completely you are simply breaking good things built for you.
#define NDEBUG before #include <assert.h> to disable assert macro.
You may so add this to pre-processor definition in project settings.
I don't have Visual Studio 2013, but the following works for me in Visual Studio 2015, so maybe the same or something similar works for VS 2013, too.
In your main() function, call
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
In Visual Studio, go to Debug / Windows / Exception Settings. In the Exception Settings, go to Win32 Exceptions / 0xc0000420 Assertion Failed. Uncheck the box in front of that entry.
I need both of the above to suppress assertion pop-ups in Debug mode.
You can add an compiler flag /DNDEBUG to turn off asserts. I feel this is cleaner since you don't have to change anything in your code.
Fromm the MSVC documentations:
You can turn off the assert macro without modifying your source files by using a /DNDEBUG command-line option.
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.
I am writing assembly-level optimized code, and I need to make sure that the C++ compiler is working with it correctly in Release-Mode.
I used to be able to get Release-Mode programs to break on breakpoints in VS 2002 (and display the raw disassembly as I stepped through it), but I can't remember how I got that to work. Does VS 2010 have any options that might allow this to happen?
Compile with /Zi and link with /DEBUG and you'll be able to set breakpoints.
Under a project's Properties dialog:
/Zi can be enabled in C++ --> General --> Debug Information Format
/DEBUG can be enabled in Linker --> Debugging --> Generate Debug Info
If you want to use the debugger to view the disassembly, you can place a __debugbreak() intrinsic call right before the code which you want to view.
If you're writing straight assembly, you can just use INT 3. When you place a breakpoint using the debugger, it actually changes the code to that (0xCC in binary) so the debugger will get called when it's executed.
You can also call one of the functions that do that for you like zr suggested. The Windows one is DbgBreakPoint(). If you disassemble it, you could easily see it's nothing but INT 3.
These used to be methods of causing breakponts:
_asm
{
int 3
}
or
_asm
{
_emit 0xcc
}
or was it
_emit 0xcc
I'm not sure of the syntax (it's been a while) but hopefully something can be made of it.
Is there a compiler option in VS 2008 (C++) to expose uninitialized variables? I'm trying to debug a problem where the "release" build of a DLL does not work but the "debug" build of the DLL does work.
iirc, setting warning level to 4 will help with this
cl.exe sample.cpp /analyze
here's the link on MSDN
You're looking for warning number C6001
My normal debug builds seem to have this warning enabled:
warning C4700: uninitialized local variable 'xxx' used
and the warning is not present in a release build.
I don't know if this is still relevant but I was just looking for the same thing and found a solution.
You can manually change the warning-level for single warnings. In your case you have to set the level for this particular warning at least as low as your configured level of default-warnings (usually 1 or 2).
Within the project-settings within the C/C++ settings enter a manual command-line switch:
/wYxxxx
with Y being the warninglevel (e.g. 1)
and xxxx being the warningnumber in this case you should enter
/w14701
Cheers