How to generate MSVC solution with debugging information using scons? - c++

I'm writing scons script for a c++ project that is intended to be cross-platform. In windows, the script generates msvc solution. The script snippet is as follows:
ENV={'PATH':os.environ['PATH']}
if build_type=='Release':
CCFLAGS=['/Ox','/EHsc','/DNDEBUG','/W3']
else:
CCFLAGS=['/Zi','/EHsc','/W3']
ENV['TMP']=os.environ['TMP']
if os_architecture=='32bit':
arc='x86'
else:
arc='amd64'
env=Environment(CCFLAGS=CCFLAGS,CPPPATH=include_path,LIBPATH=lib_path,RPATH=lib_path,LIBS=libs,ENV=ENV,MSVS_ARCH=arc,TARGET_ARCH=arc)
In debug mode the solution file is supposed to contain debugging information. However when I debug code in debug mode, I get "cannot find debugging information or debugging information mismatch" warning. Cannot figure out why. There is one ".pdb" file generated.

The Zi parameter will tell VS to create a pdb's during the compile time phase, however, you still need to specify the link-time pdb generation (yeah, its quite redundant, but there is probably some reason for the ultra fine-grained control). If the PDB your seeing is named vc###.pdb (where ### is your vc compiler version) then that is the compile-time pdb for your obj files, -not- your debuggable link-time pdb for your actual dll.
Anywho, I added the following line to scons and now I have a debuggable proper .pdb:
# Produce one .PDB file per .OBJ when compiling, then merge them when linking.
# Doing this enables parallel builds to work properly (the -j parameter).
# See: http://www.scons.org/doc/HTML/scons-man.html section CCPDBFLAGS
#
env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
Which I got from the following very very helpful sample SConscript
http://www.scons.org/wiki/MsvcIncrementalLinking

Related

How to set up C++ Testmate in VS Code

Ok, n00b question. I have a cpp file. I can build and run it in the terminal. I can build and run it using clang++ in VSCode.
Then I add gtest to it. I can compile in the terminal with g++ -std=c++0x $FILENAME -lgtest -lgtest_main -pthread and then run, and the tests work.
I install the C++ TestMate extension in VSCode. Everything I see on the internet implies it should just work. But my test explorer is empty and I don't see any test indicators in the code window.
I've obviously missed something extremely basic. Please help!
Executables should be placed inside the out or build folder of your workspace. Or one can modify the testMate.cpp.test.executables config.
I'd say, never assume something will "just work".
You'll still have to read the manual and figure out what are the names of config properties. I won't provide exact examples, because even though I've only used this extension for a short time, its name, and therefore full properties path, has already changed, so any example might get obsolete quite fast.
The general idea is: this extension monitors some files/folders, when they change, it assumes those are executables created using either gtest or catch2. The extension tries to run them with standard (for those frameworks) flags to obtain a list of test suites and test cases. If it succeeds, it will parse the output and create a nice list in the side panel. Markers in the code are also dependent on the exactly same parsed output, so if you have one, you have the other as well.
From the above, you need 3 things to make this work:
Provide correct path (or a glob pattern) for finding all test executables (while ignoring all non-test executables) in the extension config. There are different ways to do this, depending on the complexity of your setup, they are all in the documentation though.
Do not modify the output of the test executable. For example, if you happen to print something to stdout/stderr before gtest implementation parses and processes its standard flags, extension will fail to parse the output of ./your_test_binary --gtest-list_tests.
If your test executable needs additional setup to run correctly (env vars, cwd), make sure, that you use the "advanced" configuration for the extension and you configure those properties accordingly.
To troubleshoot #2 and #3 you can turn on debug logging for the extension (again, in the VSCode's config json), this will cause an additional "Output" tab/category to be created, where you can see, which files were considered, which were run, what was the output, and what caused this exact file to be ignored.
This messed with me for a while, I did as Mate059 answered above and it didn't work.
Later on I found out that the reason it didn't work was because I was using a Linux terminal inside windows (enabled from the features section) and I previously had installed the G++ compiler using the linux terminal so the compiler was turning my code into a .out file, for some reason TestMate could not read .out files.
Once I compiled the C++ source file using the powershell terminal it created a .exe file which I then changed the path in the setting.json as Mate059 said and it showed up.
TL;DR
Mate059 gave a great answer, go into settings.json inside your .vscode folder and modify "testMate.cpp.test.executables": "filename.exe".
For me it also worked using the wildcard * instead of filename.exe but I do not suggest to do that as in that might mess up something with the .exe from the main cpp file and what not.

PDB doesn't match .exe

I am using VS2015 debugger on my C++ app. When I start the app, debugger gives the message
Loaded 'C:\MyDir\Working\x64\Debug\MyApp.exe'. Cannot find or open the PDB file
As a consequence, I cannot set breakpoints.
There is a .pdb file in the same directory as the .exe, but it doesn't match, according to VS debugger, and also according to WidDBG Symchk. Symchk does not provide the reason for the mismatch, even with /v option.
Complete rebuild does not make this problem go away. It is only occurring for debug build, and it just started today. Before today, there was no problem with mismatched pdb's, either for debug or release builds.
The VS options I am using are:
C++: Debug Information Format=Program Database (/Zi), Program Database File Name=$(IntDir)%(Filename).pdb;
Linker: Generate Debug Info=Optimize for debugging (/DEBUG), Generate Program Database File=$(OutDir)MyApp.pdb, Generate Full Program Database File=Yes.
The pdb files for the individual objects appear in the intermediate directory, and MyApp.pdb appears in the output directory, along with MyApp.exe.
Now, here's the weird part: when delete the existing MyApp.pdb and then relink, a new .pdb file appears in the output directory with a current mod time. While the linker is running, the pdb file grows to be large (~70 MB), but as the linker completes, the pdb file suddenly becomes small (~4 MB), and the mod time changes to a few hours earlier today. This is very suspicious, and probably accounts for the pdb mismatch.
The linker's final output lines are
Finished searching libraries
MyApp.vcxproj -> C:\MyDir\Working\x64\Debug\MyApp.exe
MyApp.vcxproj -> C:\MyDir\Working\x64\Debug\\MyApp.pdb (Full PDB)
How can I force VS to produce a matched and correct pdb file for the debug build?
UPDATE: The problem was that there is a pdb file MyApp.pdb created in the intermediate directory (it is the pdb file created by the compiler for MyApp.cpp). For some reason, the linker replaces the "real" pdb file with this one at the end. Since they have the same name, MyApp.pdb, Symchk doesn't show a name mismatch (although there may be a timestamp mismatch that isn't evident).
It is not obvious how the debugging info for MyApp.cpp can be included in the final MyApp.pdb.

Why the code doesn't break at the breakpoint in code blocks

I followed the instruction from this video to run the code line by line:
http://www.youtube.com/watch?v=6CGH9Z19dS8
However, after I pressed F8, it just ran without going to the breakpoint(I couldn't see the yellow triangle). In addition, I also tried "attach to process", and it was the same.
Did I miss anything?(btw, there are multiple files in my project, but I guess that won't be the problem, right? cuz I could do this easily in VS studio. Perhaps, I am not that familiar with codeblocks)
Thanks for help!
If you are interested, this is the debugger log:
Building to ensure sources are up-to-date
Selecting target:
Release
Adding source dir: C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\
Adding source dir: C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\
Adding file: C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\bin\Release\lattice_boltzmann.exe
Changing directory to: C:/Users/liuca_000/Documents/Lattice_Boltzmann_code/lattice_boltzmann/.
Set variable: PATH=.;C:\Program Files (x86)\CodeBlocks\MinGW\bin;C:\Program Files (x86)\CodeBlocks\MinGW;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Python27;C:\Python27\DLLs;C:\Python27\Scripts;C:\Python27\Lib\site-packages\vtk;C:\Python27\gnuplot\binary;C:\Python27\Lib\site-packages\osgeo;C:\Program Files (x86)\pythonxy\SciTE-3.3.2-3;C:\Program Files (x86)\pythonxy\console;C:\MinGW32-xy\bin;C:\Program Files (x86)\pythonxy\swig;C:\Program Files (x86)\pythonxy\gettext\bin;C:\Program Files\MATLAB\R2012b\runtime\win64;C:\Program Files\MATLAB\R2012b\bin;C:\Program Files\TortoiseSVN\bin;C:\Program Files\MiKTeX 2.9\miktex\bin\x64;C:\Program Files (x86)\Windows Live\Shared;C:\Users\liuca_000\AppData\Roaming\MiKTeX\2.9\miktex\bin\x64;.;\
Starting debugger: C:\Program Files (x86)\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname -quiet -args C:/Users/liuca_000/Documents/Lattice_Boltzmann_code/lattice_boltzmann/bin/Release/lattice_boltzmann.exe
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Reading symbols from C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\bin\Release\lattice_boltzmann.exe...(no debugging symbols found)...done.
Debugger name and version: GNU gdb (GDB) 7.5
Child process PID: 16672
[Inferior 1 (process 16672) exited normally]
Debugger finished with status 0
Even if you have had marked -g compiler option the problem may be spaces in path to the project file. Moving to place with no spaces in path solved the problem in my case.
See that: http://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks#Path_with_spaces
I think this part of your log says why:
(no debugging symbols found)
build a debug version of your code - no optimisation, debug symbols included or built and try again.
Spent quite a while working through this today trying:
"Make sure using "debug" instead of "release"
"No spaces in directory names"
"-g ticked, -s unticked"
"download a nightly"
None worked until, I figured I had been making a very novice mistake unfamiliar with the IDE and to debug so it stops at the break points you have to run with the red arrow not the green one. So anyone as silly as me hopefully this helps! xD
You seem to have found a solution that is the wrong solution and likely
to have adverse consequences. (Apologies if I am mistaken)
Your were unable to set breakpoints because your build contained no debugging
information (as you now know); and the build contained no debugging information
because you were trying to debug a Release build and not a Debug build.
You can see this in the build log:
Adding file: C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\bin\Release\lattice_boltzmann.exe
and also:
Reading symbols from C:\Users\liuca_000\Documents\Lattice_Boltzmann_code\lattice_boltzmann\bin\Release\lattice_boltzmann.exe...(no debugging symbols found)...done.
The executable generated by a Release build will be <project_dir>\bin\Release (as it is), and the executable
from a Debug build will be in <project_dir>\bin\Debug
It appears that you have "solved" the problem by going to Build Options -> Compiler flags and ticking
the checkbox Produce debugging symbols.
But if you go back there and look at the tree control at the left of the window I expect you
will see:
lattice_boltzmann
Debug
Release
with Release selected. That means you have now configured your Release build
to contain debugging information. You don't want that because:-
Although you will now get debugging symbols in the executable and the debugger will be able to use them, the Release build is still configured with high optimisation by default (as it should be) and you are very likely to find that the behaviour of the debugger is at times strangely puzzling, because the optimized object code doesn't always properly match up with the source code.
Your Release executable will be vastly inflated in size by the debugging information.
What you should have done is simply to ensure that the build you tried to debug was
a Debug build. To do that:
Navigate from the top menu bar Build -> Select Target
Uncheck Release. Check Debug
Then Rebuild the project (i.e. clean and build) and you will be able to debug it
properly. Code::Blocks default options for a Debug build are perfectly fine.
Don't forget to go back and remove the -g option from the Release configuration.

How to avoid symbols and source paths in iOS binary?

When I compile the release version of my iOS app (based on standard Apple supplied iOS app template), look into the resulting executable binary, I see all sorts of symbols and even local cpp source and header paths in there. I'm really stumped why this is (I haven't enabled RTTI*). Especially the source file paths make me feel uncomfortable sending this app across the globe (why should everyone be able to see the directory layout of my development machine?).
Here's are two (randomly picked, moderated) excerpts:
TS/../ACTORS/CActorCanvasCharPart.cpplastMeshcapVerticesOFF BOUNDSupload VERTICES: %d
20CActorCanvasCharPartgrassscrub/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_grass.cppbaseShadowmowerstartmowerloopmowermowerCharcutGrassChargrassStuffgrassParticles/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_grass.h17CStateGame2_grasssinwriteStroke/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_flowers.hflowerBedsandTrailclickstart3inplace2sandDrag/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame
And here are a lot of symbols for self-defined types and structs:
CAssetMgr="_vptr$CMgrBase"^^?"pMain"^{CMain}"inited"B"curveCount"S"curveSpecs"^{CCurveSpec}"gameSpecs"[23{CGameStateSpec="header"{SpecDiskHeader="type"i"version"S}"gameID"C"backgroundColor"{CRGBAcolorf="r"f"g"f"b"f"a"f}"clickPointColor"{CRGBAcolorf="r"f"g"f"b"f"a"f}"clickPointIconColor"{CRGBAcolorf="r"f"g"f"b"f"a"f}"hintColor"{CRGBAcolorf="r"f"g"f"b"f"a"f}}]"currentFont"^{CCharset}"userCharParts"^^{CCharPart}"words"{CDataSet<CName4,CCharArray>="_vptr$CObjectBase"^^?"pMain"^{CMain}"count"i"data"*"dataSize"l}"sets"{CDataSet<CName16,CCharArray>="_vptr$CObjectBase"^^?"pMain"^{CMain}"count"i"data"*"dataSize"l
Can this be avoided, how?
*UPDATE: I just found out that RTTI is on by default. So I cleaned the target, disabled RTTI (GCC_ENABLE_CPP_RTTI = NO) and recompiled. I still see a lot of symbols and source paths in the binary.
UPDATE 2: I checked a few other apps from the app store, and many of them also have their source file paths show up. Pretty scary, if you ask me:
Joined Up Lite
/Users/lloydy/Documents/Development/iPhone/ABC Joined Up/main.m
/Users/lloydy/Documents/Development/iPhone/ABC Joined Up/Classes/SettingsView.m
Crayon Physics
/Users/smproot/Desktop/unzip/CrayonPhysics/v104/Classes/crayon/src/ceng/gameutils/killspriteslowly/killspriteslowly.cpp
/Users/smproot/Desktop/unzip/CrayonPhysics/v104/Classes/crayon/src/ceng/tasks/task/sdl/mixer/ctaskaudiosdlmixer.cpp
Wall Times
/Users/fred/_WORK/ZDNDRP/WallTimes/main.m
/Users/fred/_WORK/ZDNDRP/WallTimes/Classes/SystemCategories.m
Jumbo Calculator
/Users/Christopher/Documents/Development/JumboCalculator 1.0.3/main.m
/Users/Christopher/Documents/Development/JumboCalculator 1.0.3/Classes/CalculatorFaceViewController.m
The file paths are most likely from assert macros which stringify __FILE__ as part of their failure message. iOS's implementation of assert(3) does this, as do the NSAssert macros.
You can remove asserts in release builds by defining NDEBUG (for the C asserts) and NS_BLOCK_ASSERTIONS (for NSAsserts).
In Xcode set Deployment Prostprocessing to Yes in order to trigger Xcode to call the strip command during build process. Then you don't see any source path via nm -a.
However, I still see the source paths of some m files via the strings command :/
What worked for me was setting Generate Debug Symbols to No for release builds. This is under the Apple LLVM 7.0 - Code Generation in Xcode 7.2.
Have ticked the strip debug symbols in the build settings? You can do this (or not) depending on the configuration (build/release). Also you can look into Objective-C Code Obfuscation (which is long winded). From what I gather, you cannot completely remove objective-c information as all method calls are done dynamically, so the library has to have information about your classes/method names in order to function. A useful tip here.
If you have c++ code then you can use the gcc strip utility, although I'm not sure how it like Objetive-C++, if it doesn't you could compile all you cpp into a lib, strip that and link against it in your iOS project.

vtune - no symbols available

I have used vtune several times in the past, usually without too much trouble. Unfortunately the gaps between each use are often so long that I forget some aspects of how to use it each time. I know that the line number and symbols information needs to be stored somehow. I thought that all that was required was to compile your exe with "Program Database" (/Zi), but I have just done a sampling and found that vtune reports there are no symbols available.
Is there anything I missed?
There are two options for debugging (check $> cl /?):
/Zi enable debugging information
/ZI enable Edit and Continue debug info
Make sure that you have .pdb and manifest file (if generated).
It's not related but maybe turn off optimizations as well.
Like Bua mentioned, you definitely need to be compiling with debugging information enabled. If the pdb files are in the same directory as the exe that you're profiling, then it should be able to find them. If not, you can also try explicitly adding the path to the pdbs in config -> options -> directories. alt text http://software.intel.com/file/21331 Add an item with your symbols directory. You might also want to add a symbol server and symbol cache, because then you'll get symbols for all of Microsoft's public binaries. The image above shows how to add a symbol server with a symbol cache at c:\websymbols. Generally, the format for a "symbol server" is a string of the form:
an example:
SRV*C:\MySymbolCache\*http://msdl.microsoft.com/download/symbol
of the form:
SRV * [CACHE] * [SYM SERVER PATH]
Hope this helps!
The problem has been solved: It turned out that it was a mistake in setting the working directory; "/Zi" appears to be all that is required after all. I don't need to switch off optimization.