I'm trying to debug an application compiled with Ninja.
I have my source code /usr/local/...project-src/
I have my build output located at /usr/local/...project-src/out/Debug/build
The compiled output includes debug information
file out/Debug/build includes:
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
I'm able to add breakpoints when using relative paths:
cd /usr/local/...project-src
gdb
file out/Debug/build
b x/y.cc:34
# success
Breakpoint 1 at <mem-loc>: file ../../x/y.cc, line 34.
But when I use absolute paths, it fails
cd /usr/local/...project-src
gdb
file out/Debug/build
b /usr/local/...project-src/x/y.cc
# failure
No source file named /usr/local/...project/x/y.cc.
info source prints No current source file.
dir prints Source directories searched: /usr/local/...project-src/out/Debug:$cdir:$cwd
I've also tried:
b ../../x/y.cc, I tried this since that's what the successful command outputs. Surprisingly, it didn't work which is really confusing me.
running gdb from the root directory and other directories.
doing cd to various directories after starting gdb
messing around with set substitute-path and adding directories using dir
I'm hoping the solution is simple, since breakpoints, and variable values, and everything else works, just not with absolute paths.
Also worth noting, once I've successfully added a breakpoint to a file (using the relative path), the other paths also work (both the absolute path and the ../../x/y.cc path).
Lastly, as to why I want absolute paths to work, I'm using CLion's remote-gdb configuration to connect to a gdbserver, and CLion is using absolute paths for whatever reason. Perhaps there is a way to configure CLion to just use the x/y.cc instead? I'm running the gdbserver with gdbserver :2000 out/Debug/build and configured CLion's target remote, symbol file, and sysroot. I've also tried setting the path mappings in CLion.
Edit, testing on a dummy HelloWorld project using g++ -g instead of ninja to build, I'm able to add breakpoints using absolute paths e.g. b /usr/local/...untitled/main.cpp:4. So it seems to be, for some reason, gdb supports full paths for the HelloWorld project built with g++, but not for the real project built with Ninja.
tldr, resolved using gdb --readnow.
Per the comment suggestion I began digging into my build config. 2 things I noticed:
1) The issue disappeared if I built with less debug details. But then I wouldn't be able to inspect expressions & variables. So I thought the issue may somehow related to gdb not having enough memory or cache to load all the debug info. This sounds reasonable since the project source code contains 100,000's of files.
2) As I mentioned earlier, I could add breakpoints using absolute paths after I had added a breakpoint using a relative path to the same file.
I learnt of the info, info set, and info sources commands. Although the outputs were the same between the light-weight debug build and the full debug built (step 1), I noticed that the output of info sources changed in step 2. Before I had added the breakpoint using a relative path, `info sources would list all source files under 'Source files for which symbols will be read in on demand'. But after adding a relative breakpoint, a few of the files (I think the files on the current frame) would be added to the loaded source files.
So I went looking for a way to tell gdb to load all the source files and discovered the gdb --readnow flag (or file <built-file> -readnow with 1 dash -) and though it prints a bunch of warning messages, it seems to resolve my issue.
That being said, I never discovered how to configure CLion to use the readnow flag. The newest EAP (2019.3) release supposedly supports configuring .gdbinit files individual per project, though I haven't tried this. I also don't know if readnow can be configured in a .gdbinit file since it's not a setting. I kind of circumvented the entire configuring CLion issue when I figured how to correctly configure custom build targets and applications in CLion during this investigation.
Edit,
Yet another workaround. If I cd into /usr/local/...project-src/out/Debug which contains the build file (as opposed to /usr/local/...project-src/), then absolute paths work even without readnow.
Related
My workspaces are located in my home directory.
I am currently trying to debug python code which loads a shared C++ library, using Eclipse Oxygen and PyDev. I can debug the Python files just fine.
I run the program (pytest unit test if that matters) with a breakpoint somewhere in the test before the shared library is called (but after it is loaded) and then run a C/C++ Attach to Application debug and attach to the paused python thread. I then set a breakpoint in my C++ code and resume python, and get this from the GDB console output:
No source file named /home/myname/.../models/sourcefile.cpp
Doing an ls /home/myname/.../models clearly shows that that file exists.
I'm not sure if this matters but my library was compiled with CMake where the source and build directory are siblings. E.g. workspace is ~/dev and source is in ~/dev/sourceFolder and build files are in ~/dev/buildFolder
Update:
I was able to attach to the running Python debug thread manually in the console using gdb python <thread_number>. This works and finds my source files just fine, allowing me to debug manually in the console. It would still be much faster and less cumbersome if I were able to get it to work in Eclipse.
Things I've tried in the C++ debug config settings:
In preferences, changing C/C++ -> Debug -> Source Lookup to have
absolute file path first, profile first, and relative file path
first
In CppDebug settings debugger tab, manually added build and source directory to shared libraries
In CppDebug settings source tab, manually added source directory in source lookup path
None of these seemed to do much.
For cmake projects:
The launch configuration can default to the wrong executable, so go to launch configuration => main and check the "C/C++ Application"
Change it from this: build/default/
to this: build/cmake.debug.linux.x86_64/
(you can do this with the "Search Project" button.
This will then pick up the correct debug version and all your source will be found when you debug.
I am using bazel to build a c++ application that includes protocol buffers. This means that bazel runs the protocol buffer compiler as part of the build process, and squirrels the generated files away somewhere within the bazel output directory. VSCode is then unable to resolve these #include directives since they are not on any include path that vscode knows about.
But I'd rather not hardcode some frequently-changing bazel output directory in my vscode config. Does anyone have any suggested strategy for resolving this?
You can hardcode <bazel_workspace_path>\bazel-genfiles or <bazel_workspace_path>\bazel-bin as include directories.
bazel-bin and bazel-genfiles are junctions (~= directory symlinks) that point to the corresponding output directories. (They are called convenience symlinks. See the --symlink_prefix flag for more info.)
I have the following Eclipse CDT setup on a Red Hat Linux system:
Eclipse Mars with CDT 8.7
gdb 7.6
I have two projects open in my workspace
Project1: the main source code that builds the executable I want to debug
Project2: library code that gets statically linked with the binary in Project1
Project2 is linked to Project1 in its properties.
The problem occurs when I try to set breakpoints in a debug session in source files that are in Project2. gdb reports the following error:
No source file named <absolute_path_to_file>.
The weird thing is that I can set breakpoints in the gdb console in Eclipse using the function name and/or function name and line number syntax. When I do this, gdb reports that it successfully set the breakpoint showing the file and line number. The file name, in the trace message, has no path (maybe relevant?)
Using objdump I was able to confirm that my executable has all of the symbols and files in it (not absolute paths though... relevant?)
Once I get the debugger to stop at the breakpoint after setting it using the function name, I can then add/remove breakpoints within the Debug perspective like normal; even if I restart the debugging session.
I've seen lots of comments about loading shared libraries into gdb, but the code I'm trying to break into is in a statically linked library, not a shared one.
Given that I can add breakpoints using the normal method once I get gdb to break on one added manually in the conosole, indicates to me that maybe something is missing in my gdb settings.
Any thoughts?
Thanks!
I compiled Xcode project in debug mode. however, while running it from VM with lldb (or any other remote machine), I cannot see any debug symbols.
to resolve this I've created a soft link to the project source code in local compilation machine, so that each file will have the same path.
however, unlike local VM, in remote machine i might not have source code access.
so my question is what files should i copy from project debug outputs in compilation machine, to remote machine so that the lldb debugger will recognize target symbols, and how should i "tell" lldb to look at those new data, rather than the original symbols location (in compilation machine)
In the normal build/debug cycle lldb reads debug information from the .o files made in the course of the build. There's a "debug map" in the binary produce that points to the locations of these .o files. Since the debug map records absolute paths, if you want to use the .o files on another machine the .o files must appear in the same place on the file system as they are on the builder.
The other way to do this is to use Xcode's "DWARF + dSYM" variant of debug info generation, which builds a ".dSYM" folder that contains fully linked debug information. Then just move the dSYM & the binary to the same directory and lldb will find it. If for some reason that doesn't work, there is also an lldb command: add-dsym that you can use to manually tell lldb where the dSYM is.
On Ubuntu, I have a C++ app in Eclipse. The application compiles fine and I can run the app from the command line.
But when I try to debug it or run it with Eclipse, the error :
"Cannot open shared object file: No such file or directory" is thrown on a shared library.
I've set LD_LIBRARY_PATH in my bashrc file and also set an LD_LIBRARY_PATH environment variable in both the Run Configuration and Debug Configuration to :
/home/behlingb/Documents/api_libs/FileGDB_API/lib
What else am I missing here to get Eclipse to run this?
UPDATE
There is only one shared object file this application requires, and that file is from a 3rd party API download. I just found that if I place the shared object inside the directory the executable is in, it will debug in Eclipse. Is there a way to specify a different directory so I dont have to copy the file for every project?
I'm using the Kepler version of Eclipse.
In Eclipse click on Run then Debug Configurations
Click on the Environment Tab
Click on New
Add LD_LIBRARY_PATH and set its value to the directory containing the library
restart Eclipse
If you have set LD_LIBRARY_PATH and it doesn't work. Close Eclipes and run it from command terminal. I accidentally found that this could make it work. Not sure about the reason, but probably have something to do with Eclipes initialization.
you can use strace utility (and then grep for open and/or stat calls) to get list of .so files required to run smth, then use locate (or find among packages) to find out the actual placement of required lib
According to what #zuafi suggested , you do not have to grep for the libraries and `locate' to find them.
Instead save strace's output to a file:
strace -o my_output_file.txt /path/to/my_executable_file
then open the file, where you can see
open("/a/path/to/some/library.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
scroll down those lines until you hit
open("/real/path/to/some/library.so", O_RDONLY|O_CLOEXEC) = 3 (any value here)
this means before finding /real/path/to/some/library.so there have been several trials to find library.so in different paths. but finally the library has been found in /real/path/to/some/.
Just copy and paste this into your Eclipse!
This is valid with Eclipse Kepler (I have not looked into older versions).
To enable the debugger to load your shared libraries, trying to set LD_LIBRARY_PATH will fail. However the CDT plugin provides a Shared Libraries list for this purpose
Run menu -> Debug Configurations ...
then in the configuration dialog
C/C++ Application -> your project -> Debugger tab -> Shared Libraries tab