3
votes

I am writing a C program with Visual Studio 2015.

My C executable links to a .lib file, which is built separately from my executable.

The .lib file is also written in C. And it is built with:

cl.exe flags:

/nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Od /GL- /Gy /EHs-c- /GR- /GF /Z7 /Gm- /Gw

link.exe flags:

/NOLOGO /LTCG


My executable is built with:

cl.exe flags:

/GS- /TC /W4 /Zc:wchar_t Z7 /Gm /O1 /Fd"C:\source\TEST2.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /Gd /MTd /Fa"x64\Debug\" /Fo"C:\source\x64\Debug\" /Fp"x64\TEST2.pch" /c /WX- /GS- /W4 /Gs32768 /D UNICODE /Od /GL- /Gy /EHs-c- /GR- /GF /Z7 /Gm- /Gw /wd4054 /wd4477 /U_DEBUG

link.exe flags:

/OUT:"C:\source\x64\Debug\TEST2.exe" /MANIFEST /NXCOMPAT /PDB:"C:\source\x64\Debug\TEST2.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL:NO /PGD:"C:\source\x64\Debug\TEST2.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\TEST2.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib


When I debug through the whole application, I encountered below error for some breakpoints in the lib.

enter image description here

So I did some experiment.

In the .c file that has above issue, I tried to add break-point pair to the beginning curly bracket and ending bracket of all the C functions within that file.

I noticed that for some functions, the break-point pair can be hit. Like below:

enter image description here

But then I encountered a function where the break-point at the ending bracket cannot be hit. Like below:

enter image description here

And all the subsequent functions suffer from the same issue.

I checked this thread.

I tried clean rebuild, no use.

I use the /Z7 so there's no PDB files. I guess all debug info are embedded in the lib file.

I had /Od so I guess the optimization is not in my way.

Then what could be wrong?

Could any one shed some light? Thanks.

1
PDB doesn't get embedded in a lib (or other object file). Without a valid PDB, you cannot put breakpoints at the source level. The fact that it allows it at the braces is perhaps due to recognized entry/exit code. - Michael Chourdakis
@Michael Thanks. But for some functions in that lib, the breakpoint can work at locations other than the beginning/ending of the body. At least seemingly. - smwikipedia
@Michael How to generate a PDB file for a lib? And since the lib is statically linked to the executable, can its PDB still be useful? - smwikipedia
The PDB contains only symbols and other stuff needed for debugging. It is not related to static/dynamic linking (all executable formats can have a PDB which is only useful for the debugger, not for running whatsoever). Try the /Zi option. - Michael Chourdakis
@Michael According to MSDN (msdn.microsoft.com/en-us/library/958x11bc.aspx): /Z7: Produces an .obj file containing full symbolic debugging information for use with the debugger. - smwikipedia

1 Answers

1
votes

(This is not an answer yet. This is an answer now. I post my investigation here so the original post won't be too long.)

Try 1

I tried to use /Zi for my lib. And it produces a vc140.pdb file. (btw, the lib file size is much smaller than the /Z7 situation)

Then I debug my application. I tried to put this vc140.pdb file in the symbol file window as below:

enter image description here

But it didn't work. (This is kind of expected because how could VS2015 know this pdb file is for the statically linked lib, which is just a part of the executable now.)

Try 2

There are 3 similar scenarios where a break-point cannot be hit.

Scenario 1:

The breakpoint will not currently be hit. No executable code of the debugger's target code type is associated with this line.

enter image description here

Scenario 2:

The breakpoint will not currently be hit. No Symbols have been loaded for this document.

enter image description here

Scenario 3:

The breakpoint will not currently be hit. The source code is different from the original version.

enter image description here

During the investigation, I was lucky enough to encountered all 3 of them.

To fix 2, check here: http://www.wwwlicious.com/2016/02/28/how-to-load-debug-symbols-during-debugging/

To fix 3, double check that your file is of correct version.

For 1. Based on the its very description, I believe the debug symbol must have been loaded in 1, which is not the same as 2. But somehow, the debug symbol info is corrupted somewhere in the middle, which causes break points for some functions are OK while others are BAD.

Try 3

According to the error description, there can be 2 most likely reasons:

  • Conditional Compilation
  • Compiler Optimization

I focus on Compiler Optimization for now.

I set /Od for cl.exe to disable optimization.

I set /GL- for cl.exe to disable whole program optimization.

I remove the /LTCG to disable link time code generation, which is also a kind of whole-program optimization.

Seems still not work.

Try 4 --- Issue Solved!!!

(Finally, my mom's blessing saved the day!)

The root cause turns out to be the line ending style!

Visual Studio keeps prompting me for the C file which contains the unreachable break points. As below:

enter image description here

After I normalize the line endings, all break points work fine now!

Below is a previously unreachable break point.

enter image description here


BTW, I really didn't expect that Microsoft Visual Studio sticks to the CR LF style so strictly.

Does it hurt to be a little bit more benign/intelligent?