Debugger doesn't locate symbols in source when INTERPROCEDURAL_OPTIMIZATION is enabled - c++

I've been switching a project to CMake and VSCode on my Mac, and encountered a baffling problem: when I enable LTO/IPO, VSCode's C++ debugger doesn't highlight the execution line when breaking. This appears to affect any build target for which I enable IPO.
Here's a minimum example demonstrating the problem:
[main.cpp]
#include <iostream>
int main()
{
std::cout << "This is some text!" << std::endl;
__asm__("int $3"); // Alternatively, use a breakpoint
return 0;
}
[CMakeLists.txt]
cmake_minimum_required(VERSION 3.23.0)
project(TestLTODebugging)
include(CheckIPOSupported)
check_ipo_supported()
add_executable(example main.cpp)
set_target_properties(example PROPERTIES
INTERPROCEDURAL_OPTIMIZATION TRUE
)
I'm using Clang and Ninja, using quick-debugging via VSCode's CMake Tools extension. When run, the app appears to pause as expected, but the line is not highlighted:
And if all I do is turn off IPO/LTO, the issue goes away:
Anyone know where to look for the problem? I'm new to CMake and using VSCode for C++, but this seems super basic and I can't find anything online about this problem. I've had no problems with this when generating an Xcode project with the same source.
While I'm primarily going to be debugging without optimizations, the project I'm working on requires working with optimizations enabled a lot of the time, and I want the debugger to work. I appreciate any help or advice.
EDIT: I've confirmed that this issue does not occur on my PC, where I also tested with Ninja, Clang, and the VSCode debugger. So the problem is either with my Mac environment or is Mac-specific?
EDIT 2: I've now confirmed this affects me with both Ninja and Make files on my Mac. Additionally, both Ninja.build and compile_commands.json (when using Make) show that the only difference between enabling and disabling IPO is the addition of the -flto=thin flag. The -g flag is never removed, and using nm in Terminal shows that the debug symbols are still being generated. I'm now more confident that this is a bug with VS Code or CMake Tools.

I faced a similar problem -- in my case I source annotations for Instruments were missing.
From here:
Note
On Darwin, when using -flto along with -g and compiling and linking in separate steps, you also need to pass -Wl,-object_path_lto,<lto-filename>.o at the linking step to instruct the ld64 linker not to delete the temporary object file generated during Link Time Optimization (this flag is automatically passed to the linker by Clang if compilation and linking are done in a single step). This allows debugging the executable as well as generating the .dSYM bundle using dsymutil(1).
Additional information here.
TL;DR: just add -Wl,-object_path_lto,lto.o to your linker options -- e.g. for CMake: add_link_options(-Wl,-object_path_lto,lto.o).

Related

XCode Cmake and -fobjc-weak

I have a question regarding a compiling flag -fobjc-weak. Currently, I work on the project that is generated using CMake, it uses C++ mainly and some minimal objective-C code to run the app. When studying compiling flags I saw that some of the Cmake target libraries are compiled with -fobjc-weak and some does not. This is not the flag that I set in CMake so I assume it is automatically added by XCode. My question is why? Where does it come from and what is the reason and implication of this flag being there? I could have missed something but I cannot seem to find out at which stage this flag gets added.
Another piece of information is that I use a iostoolchain.cmake It is identical to this project tool chain. It has a line like this:
#Check if Xcode generator is used, since that will handle these flags automagically
if(USED_CMAKE_GENERATOR MATCHES "Xcode")
message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as generator.")
I dont really understand how Xcode end up deciding which flags are being added but that is my suspection to why I am seeing this line added when compiling.
https://github.com/leetal/ios-cmake/blob/master/ios.toolchain.cmake
Cheers!

Visual Studio Code keeps giving me an error for all my include statments when trying to use C++ with Unreal Engine [duplicate]

I'm trying to use vscode with arduino but have no success.
The problem seems to be something with the libraries path.
But I havent been able to fix that !
I'm on linux.
"message": "#include errors detected. Please update your includePath. IntelliSense features for this translation unit (/home/harold/Arduino/Saaf_Curing/Saaf_Curing.ino) will be provided by the Tag Parser.",
I don't know how to find my includePath.
I'm not able to do any advices given in vscode.
I wonder if vs code is the right direction at all as it seems complicated ?
Although the question mentions Arduino, the following suggestions apply basically any time VSCode tells you to "update your includePath".
What is includePath?
The includePath is an attribute in c_cpp_settings.json, which is in the .vscode folder of the main folder you have opened in VSCode using File → Open Folder.
You can edit c_cpp_settings.json directly, but it is usually easier to use the "C/C++ Configurations GUI". To do that, open the Command Palette (Ctrl+Shift+P) and run "C/C++: Edit Configurations (UI)". Then look for the "Include path" setting.
The includePath tells VSCode (specifically the IntelliSense component of the C/C++ extension) where to look when resolving #include "filename" directives. That allows VSCode to see definitions of symbols defined in those files.
So should I fiddle with includePath when VSCode tells me to?
Not at first! Before changing the include path, if you haven't already, first set the "Compiler path" to point at your C/C++ compiler, and set "IntelliSense mode" to match the compiler as closely as possible.
You may also need to adjust the Compiler arguments, particularly if the compiler is capable of generating code for multiple targets, for example, both 32-bit and 64-bit code. (If you don't know what that means, skip it at first.)
Next, in Command Palette, run "C/C++: Log Diagnostics". The output will show you which compiler VSCode found and what it detected as its built-in include path and preprocessor defines.
Then, run these commands in a shell:
$ touch empty.c
$ gcc -v -E -dD empty.c
Here, I have assumed you are using gcc as your compiler. If not, substitute the actual compiler command name. If your compiler is not a variant of GCC (for example you are using the Microsoft cl.exe compiler), you'll need to look at its documentation or Google to find switches that print the predefined macros and include paths (e.g., see here for cl.exe).
Compare the output of the above command to what VSCode shows in its C/C++ diagnostics output. Hopefully they are very similar. If not, try adjusting the Compiler path, IntelliSense mode, or Compiler arguments. Once you've gotten them as close as possible by adjusting just those three settings, go on to the next step.
Now adjust includePath if necessary
If there are still significant differences between the compiler built-in configuration and what VSCode detects, fix that by (in the C/C++ settings UI) modifying the Include path, Defines, and C/C++ standard fields. Re-run the C/C++ Log Diagnostics command to see the effects.
It is probably not necessary to add all of the pre-defined preprocessor symbols. This really only matters if there are #ifdef directives that depend on them, and which are causing VSCode to see the wrong code as active. I suggest only adding predefined symbols if, while browsing your code, you see a specific case that VSCode gets wrong.
Finally, if your project has header files in places that the compiler does not search by default, that is, you normally have to pass -I switches on the compiler command line, add those as well to the Include path. The same goes for any -D arguments, which must be added to the Defines.
This is due to the extension is missing some includepath when initialize
add the missing lines into your c_cpp_properties.json
"includePath": [
"<arduino ide installation folder>\\tools\\**",
"<arduino ide installation folder>\\hardware\\arduino\\avr\\**",
"<arduino ide installation folder>\\hardware\\tools\\**",
"<arduino ide installation folder>\\hardware\\arduino\\avr\\cores\\arduino"
]
Also add "defines": [ "USBCON" ] under "configurations" to make Serial class work with intellisense
Try using platformIO extension it makes your life easier. Personally I use VScode with platformIO for my Arduino and ESP32 projects.
I just successfully wasted an hour finding solution to this problem on stack overflow but all in vain and now I have founded the solution which is, if you are using linux, just have to install the g++ compiler from your terminal,
sudo apt install g++
" and you are good to go.
For those using WSL, it's a common error, resolved by:
installing Remote-WSL VS-Code extension
setting c_cpp_properties.json includePath to ["${workspaceFolder}/**"] and intelliSenseMode to "linux-clang-x64" (or other intelliSense mode)
close VS-Code and open it again from your WSL termnial, you'll see the Status Bar icon as on the screenshot
Now the #include error should be gone
For more information follow the link
I had the same issue and spent hours trying different solutions, and finally, I realized I had a misspelling in "iostream". It's not an answer to this question, but if you have fallen here with the same error, check spelling as well.
Cause of the Problem:
My C/C++ Compiler got saved as /use/bin/clang and this was showing the error in my computer.
Operating System: Ubuntu 2022.04
Solutions:
Open Your VSCode and click Settings (at bottom left corner generally).
Now click at Open Settings (JSON) icon (at top right corner) and open the json file.
Add below code in between last part of main {} bracket [If you don't have the bracket then create one].
"C_Cpp.default.compilerPath": "/usr/bin/gcc",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
This has solved my problem and I think it will solve the problem for any Linux/Unix OS.
In case, if this doesn't work then try with:
"C_Cpp.default.compilerPath": "/usr/bin/g++",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
If you have Windows Operating System then Use the path of your GCC compiler instead of /usr/bin/gcc [this will be something like C:\MinGW\bin].

How can I debug a C++ executable compiled externally (with debug flags set) from inside Eclipse?

I have a large C++ project, different parts of which are compiled in different ways (bjam/make). I was having trouble getting it to build from within Eclipse. Could I build the code externally (with g++ -g), and then just run the debugger from within Eclipse?
I figured it out. Should've looked earlier at this: http://wiki.eclipse.org/CDT/User/FAQ#Debugging_C.2FC.2B.2B_Projects
I first added my project to eclipse. Then I followed the instructions above to set up a debug configuration. And somewhat surprisingly eclipse is able to figure out that the binary I want to run refers to the project that I have open, and so I can actually set breakpoints, step through the code while eclipse shows me which line in which file I'm at, etc. So its exactly as if I built the project from within eclipse. Its impressive :)

Debugging c++ .cpp file using Xcode

I have a solitary .cpp file, and I would very much like to debug it.
Without creating an Xcode project, is there anyway I can debug this using the Xcode debugger?
When I open the file in Xcode to edit and set breakpoints, the program doesn't stop at the break points.
You can't debug via Xcode without a project because without a project, Xcode works only as a file editor with color highlight and so one.
For debugging you need an executable compiled with debug option, which is produced via a compiler. The easy way (but in my opinion the worse) is to make a Xcode project and put the .cpp file there. There is the hard way too (and probably the best for future reference) that is to learn to do it on the terminal, using for instance the g++ (compiler) and gdb (debugger).
If noone answers you later, maybe this post will help you
I'm not a XCode developer, but I know, that to debug a process you need:
a debugger
the corresponding (!) code
the info, which stores a special debugging info, which gives the debugger an opportunity to map from binary process to your C++ (or other) code
and the process, sure :)
this link could help to understand if you have debugging info
http://www.meandmark.com/xcode3debugging.pdf
you can search words "Debug Information" and try to understand, if you have it or not
There is a way to do this without floundering through xcode, but unfortunately it is possibly more arcane.
Using cmake (https://cmake.org/) you can write a simple CMakeLists.txt to pull in your cpp file:-
cmake_minimum_required(VERSION 3.10)
project(project)
set(CMAKE_BUILD_TYPE Debug)
add_executable(project code.cpp)
To generate an xcode project type this:-
cmake -G Xcode
this will create project.xcodeproj
You can now type:-
open project.xcodeproj
and xcode will be launched.

"No source available for main()" error when debugging simple C++ in Eclipse with gdb

I'm having trouble debugging a C++ program in Eclipse (the latest RC of Helios, updated with latest CDT from within itself) on OSX.
The program is very simple (esentially Lesson 2 from NeHe's OpenGL tutorials), consisting of one cpp file and, using OpenGL and Cocoa frameworks, and linking with libSDL.a and libSDLmain.a.
The structure of the project is very simple: the source file(s) are in a subdirectory of the project called src/ and the executable is built to the project's root directory.
The problem is that whenever I try to add breakpoints and debug it, the breakpoints seem to get hit perfectly but no source is displayed - instead I just get a "No source available for main()" error in the code window.
The compiler flags have optimisations set to none, and both the compiler and linker have the debug symbols flag set (-g).
The debugging setting in Eclipse is set to "Standard spawn progess" and the debugger is set to "gdb".
Now the strangest thing is that if I try to debug the exact same executable - ie. the exact same one that was built by Eclipse - using gdb from the Terminal (shell) then everything works fine. Breakpoints are hit, source code is displayed, no problems at all.
I've made sure that both Eclipse and the shell are using the same gdb executable, and they are (it's /usr/bin/gdb).
Now I may be wrong, but this all suggests to me that there can't be a problem with the compiler and linker flags (because the same executable is debuggable from the shell), so presumably the problem must be with how gdb is being invoked from within Eclipse? Perhaps when run from Eclipse gdb is picking up different config files or something than when it's run from the shell? (Anyone know?)
I'd really appreciate any help with this because it's slowly driving me loopy!
Please let me know if there are any other details that would be useful - exact version numbers of Eclipse/cdt/gdb, exact linker/compiler command lines, etc. - and I'll very gladly update this post with them.
Many thanks in advance,
thoughton.
--- edited # "14 hours ago" ---
I tried the "add filesystem path" (with "search sub-folders") option, but that didn't work. I also tried creating a new completely flat project, but that didn't work either.
I even tried getting a Galileo release (eclipse-SDK-3.5.2RC4 with CDT update), but that made no difference (apart from gdb being slower to launch).
And here's something else strange I noticed: once I get the "No source available" message, if I then switch Eclipse's Console to display the "gdb" console, and also turn on "Verbose console mode" so I can communicate it, I can then issue "l" and "bt" commands and have them work succesfully, showing the correct source and stack where my breakpoint was hit. Which, correct me if I'm wrong, must mean that the information is there and gdb is being invoked correctly - so why will Eclipse not see this information?
I'm getting close to giving up on Eclipse to be honest... I came to it with such high hopes, too.
Any additional help or thoughts would be hugely appreciated.
t.
This thread suggests:
-g -O0
for debug flags to be set for Eclipse CDT compilation.
Sometime, it is simple a problem of rebuilding completely the application (like here)
See also this thread describing a similar situation:
I have noticed that sometimes in Eclipse I have to go and specifically add the path to my source files using the "add filesystem path" (with "search sub-folders") in the Debug Dialog (even when they are in the same project I am debugging), but I have not noticed a pattern to when I have to do this. But it may be worth a try.
I found the answer! And it's embarrassingly simple.
The problem was that I was using the Release version of SDL instead of the Debug version! (I had 'libsdl' from MacPorts whereas I should have had 'libsdl-devel'.)
So my generic answer is: make sure the libs you're linking against were compiled with debug flags set too, it's not always enough to just make sure your own code has them set.
Here is another reason for this problem. My configuration used -g3 as the option to gcc. Changing it to -g solved the problem. There seems to be some incompatibility between gcc and gdb. I checked that gdb was the latest revision (using apt-get).
I would like to add a little new blood to this old thread.
I encountered this problem when I tried to compile and debug a gnu arm project.
I solved the problem by modifying the Makefile:
adding "-g -O0" at the end of this line "CFLAGS += -Wall -Werror -O3"
Go to project Properties, C/C++ Build -> Settings. On the first tab (Tool Settings) under Cross GCC Compiler click Debugging and set Debug Level to Maximum (-g3)
I had this issue when I compiled the latest gcc, but did not update to the most recent gdb. After the update, it worked properly.
Thought to mention, that in case you are using cmake to build the project, one approach to the solution will be to add the "debug flag" to the cmake command, i.e. -
$ cmake /path/to/main/cmake_file -DCMAKE_BUILD_TYPE=Debug
For anyone else who may experience this issue,
I installed the linuxtools/valgrind plugin last night to do some memory profiling, and it seems that this broke the normal gdb. when i removed the linuxtools plugins everything started working as normal again.
So you might like to try that.
I had a similar problem. I was using CFLAGS=-Wall -O2 -fPIC -DPIC -lm -lasound and never had problem to compile it but when I tried to debbug it on Eclipse IDE I get this error: No source available for "main() at 0x401080" then I added -g to this line and it worked well:
CFLAGS=-g -Wall -O2 -fPIC -DPIC -lm -lasound
This issue depends on how gdb is being invoked. I found I needed to manually specify the source file locations when I got that error. Even though I'd already configured that under project properties. After doing so, Eclipse no longer had a problem supplying the appropriate source.
Using the release versus debug version of a library may be your specific problem (if you were building a library from source then debugging it). If someone is using a precompiled library, they'd never be able to set breakpoints within it and so that fix wouldn't apply to them.
Encountered the same problem once. You just have to go to your Project Properties, by hitting ALT+ENTR or right click project and scroll down at the bottom and you will find Properties. Expand C/C++ build on the left. Then click on settings. Once you open the settings, then click on tool settings. In the MCU GCC Compiler, there is a debugging option. Click on debugging and add
-g -O0
in the Other debugging flags. Trying debugging the project now.
I just faced with this issue and after take some time to find it out, I realize that the Arguments and Main tab in Debug Configurations dialog are conflicting each other.
Make sure that C/C++ Application and Programs Arguments point to the same binary file.
Seems like this message can have plenty of reasons to show.
For me (in the context of micro controller debugging) it was the link-time optimization. With -flto it broke; removing -flto from the "Other Options" field fixed this for me.
In Eclipse Neon (4.6) see Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> C Compiler -> Miscellaneous -> Other options.
Add this to your CMakeLists.txt
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS "-g")
set(CMAKE_C_FLAGS "-g")