callgrind no source available for a couple of functions only - c++

I am using linux and I am trying to debug an executable that I launch from the command line. It calls some functions from another custom library that I linked to it. I built both my executable and my library with the debug flags (-g3) then I ran it with callgrind this way:
valgrind --tool=callgrind --trace-children=yes ./my_exe --some_args
For most of the functions, kcachegrind shows the name and the location. But for a couple it just shows the address in hexadecimal format and complains about missing debug information. I just know that the functions come from my custom library.
The functions not being shown call some pthread functions (mainly pthread_mutex_lock and pthread_mutex_unlock) and are themselves called by other functions from the same library that are also not shown.
Despite that, I have some functions from my custom library that are fully displayed (name, file and even source code).
I tried compiling my_exe by linking dynamically my_lib.so:
kcachegrind displays the function location as being in my_lib.so but the name and the file of the function are not shown.
I then tried compiling my_exe by linking statically my_lib.a:
kcachegrind displays the function location as being in my_exe but once again it doesn't show the name nor the file and complains about missing debug infos.
Other functions called from my_exe are also fully displayed as expected (name, file, source code...).
I don't understand why some functions would be displayed and some would not, given that they're in the same executable/library and that I compiled with debug symbols. I expected having either no function names at all or all of them. Am I missing some debug flags from valgrind ? Any ideas ?

Answering my own question in case it helps someone:
I discovered that my custom library A was itself linked with another static library B and that the unsourced functions were arising from B. Since it was static, valgrind considered it as part of A.
I managed to understand that by linking A dynamically with B (B.so), and valgrind told me the function was in libB.so. I could not find the exact name though since I don't have the sources to recompile lib B with debug flags but at least I was able to figure out where the problem was coming from.

Related

Receiving the error "undefined symbol" when loading C++ dynamic library from C executable

I am trying to write a plugin for a popular program whose code and compilation process I do not have control over. The program is written in C. However, I have written parts of my plugin in C++, since I use the QT5 library for graphics capabilities. The functions that the C program calls are written in C.
When the C program tries to load the plugin (shared library), it produces this error:
dlopen('build/libfoo.so') failed: build/libfoo.so: undefined symbol: _ZTV13JoystickPanel
JoystickPanel is a class in the C++ part of the program.
I've tried rewriting parts of the program in C, but the error was unaffected. I know that I could rewrite the entire program in C, but I'd rather not have to switch to another, more C-friendly GUI framework. I've also opened up libfoo.so in a text editor and search for JoystickPanel, but it appears to be mangled as _ZN13JoystickPanel.
Are there any compiler options or solutions that I'm missing?
I have no idea what _ZN13JoystickPanel means, since it's not apparently a valid mangled C++ name. It should perhaps be _ZN13JoystickPanelE, which would translate to JoystickPanel. That'd be symbol name for sure, but without much meaning anyway. You must have truncated something: I tried quite a bit and just can't generate an object file that would include _ZN13JoystickPanel as the complete symbol. It's just a prefix, there should be a "second half" attached to it - was there?
But _ZTV13JoystickPanel is the vtable for the JoystickPanel class. It's missing because you didn't provide implementations for all the virtual methods of the JoystickPanel class. Most likely, you didn't invoke moc properly, or forgot to compile and link its output.
You need to show a complete build script for your plugin at the very least (the .pro file, or CMakeLists.txt). You'll also need to provide a github link to your project (I presume it's open source).
The symbols you want to find in the compiled output are at least _ZTV13JoystickPanelD#Ev - virtual destructors, where # is a digit, _ZTV13JoystickPanel - the virtual method table,
Those symbols may be absent when compiled with optimization and/or LTCG, but also absent will be references to them.
You may wish to delete the build folder and rebuild your project, just to be sure. qmake is bad at dependency generation for the makefiles it produces, so if you use it, I suggest switching to cmake + ninja.
Apparently, I'd forgetten to put the #include "moc_controller.cpp" line at the bottom of a file that needed it.
For anyone else chasing this issue while using Qt on CMake, consider making sure that the proper lines are added.

GDB Shared Object unable to get symbols in current context

I have a piece of software that is compiled with several shared libraries. My code is calling a function inside the shared object and crashing inside. I believe my problem is how the parameters are being constructed for this function. I want to validate this by viewing what is happening inside the .so such that I can make the correct changes for how I am constructing the parameters.
The problem I a am running into is not being able to resolve local variables within the shared object. For instance gdb will print out:
0x<addr> in <function>(int const* , int, int const*)
Based on this I know where I am inside the .so. When I navigate here and try to find what different variables are being set to gdb complains with:
No symbol <var> in current context.
Now I know for a fact where I am within the code. Additionally, I have checked to make sure the .so was compiled with symbols on and I have also made sure gdb is loading these symbols.
Can anyone inform me on why gdb is unable to see these local variables?
As a note - I haven't used gdb in a while and not to this level of debugging so I am sorry in advance is this is just a limitation of gdb that I am unaware of.
GDB Version: 7.7.1
Edit for comment:
Yes the .so was compile with symbols. I have verified this with:
file <.so>
This tells me it was dynamically linked and not stripped.
As for commands, I simply trying to print variables.
Overall I am not sure why gdb is unable to resolve the source/exact function of the .so when I explicitly loaded it and made sure the .so was compiled with symbols.
I have checked to make sure the .so was compiled with symbols on
Every .so is compiled with symbols on -- it would be useless without symbols.
It's the debugging info that you are compiling without. Add -g flag to your compile lines, and make sure to not have -s or --strip anywhere on your link line.
and I have also made sure gdb is loading these symbols.
Yes, this output <function>(int const* , int, int const*) tells us that GDB has read symbols, and also that it did not load debugging info (these are two completely separate things).

can gdb allow to see ALL source code?

I was debugging an application created in C ++ for Linux when I realized that the executables in release version were compiled with the -g flag.
My concern is whether it is possible to read the source code of the executable through gdb using list or backtrace (exploiting some know core dump or antoher method)
No, the source code is not included in the executable, even when compiled with -g. What is included are references to the source code, so there's a mapping between program addresses and file and line numbers.
There will also be information in the debug that describe the functions in your program, so there will be information describing each function, the types taken and returned, and what local variables it contains, there's also information about which addresses correspond to which functions. All your types and global variables will also be described in the debug information.
It is possible to split the debug information out of you program using objcopy, the following is taken from the gdb online manual (https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html)
objcopy --only-keep-debug foo foo.debug
strip -g foo
objcopy --add-gnu-debuglink=foo.debug foo
This takes the debug information out of foo and places it in foo.debug, the strips the debug information out of foo and adds a link between foo.debug back to foo.
Now you, as the developer can debug release builds by loading the additional foo.debug file containing the debug data, while the customer is only given foo and so does not see the debug information.
A more detailed look at creating split debug information can be found here How to generate gcc debug symbol outside the build target?
No, source code is not included in a binary built with -g and therefore it will not be possible to read it using only the binary.
Things that they may be able to read include:
Names of variables and functions
For each intruction: full path of source file, line in the file and name of the function it is in

VS 2015: The breakpoint will not currently be hit. No symbols have been loaded for this document

The problem
I have a C++ (*.cpp) file, which is part of a static library project that I can't put an active breakpoint. When I do, it gives me the notification seen in the title of this post. I can put breakpoints in any other C++ file in that same project and it will be hit during debugging. There's nothing special about this C++ file. I use CMake to generate the projects and I also refer to the class in the executable project. There are no linking errors, just that debugger says that no debug symbols have been loaded for that source file. I have tried several ways to try and diagnose what's wrong and I don't have a good answer as to what's going on in my case.
What I have tried
Compare this file with other *.cpp files in the same project: I cross-check the compiler flags between this and other files that I tested to verify are able to put a valid breakpoint. There's nothing different.
Rebuild the entire solution: As you might've guess, this didn't help
Recreate the entire solution using CMake: This didn't make any difference either.
Included the file in the source file that had main() and referred to the class in that file: This made the difference. I was able to put breakpoint in the class and its code was getting executed, while previously, it wasn't.
More Information about code
The C++ file I'm referring to is RoCreateCharacterSuccess.cpp
The job of roREGISTER_PACKET is to register this packet class with another class (RoPacketTranslator) when the application initializes.
The constructor of RoCreateCharacterSuccess gets invoked when registering the packet class.
When the breakpoint isn't active, this constructor doesn't get invoked. I know this because this packet class doesn't exist in the class that it's supposed to be registered with. It's like RoCreateCharacterSuccess.cpp is never part of the static library it's supposed to be in. But if I purposefully change the file to introduce a syntax error, the library fails to build.
To make this file be able to have active breakpoints, I have to manually register the packet with the translator in the application.
Has anyone else seen such an issues? I'm stumped at this point trying to understand what's happening. Any help in shedding light into what's happening here would be great! Thanks for your time reading this question.
EDIT: I forgot to mention that this problem was diagnosed because I was trying to diagnose why the character creation packet didn't get translated into RoCreateCharacterSuccess object when the character gets successfully created. I later found that RoCreateCharacterSuccess class was not getting registered with RoPacketTranslator class. Trying to put a breakpoint to check if the constructor was called lead to this question.
Solution
Thanks to #user1, I figured out what was happening. So, in my executable, where I refer to this class (or an instance of it), I was only accessing RoCreateCharacterSuccess::getCharacter(), which is in the header-file and probably got inline'd by the compiler into the executable. As far as the compiler could see, that was my only interaction with that class. I wasn't invoking its constructor, which was defined in the cpp file. This means that the compiler has the opportunity to optimize that part of the code away (I did have that option turned on).
The solution: I moved the definition of the only method I interact with, RoCreateCharacterSuccess::getCharacter(), into the cpp file, therefore avoiding inline'ing and forcing the compiler to link to that part of the static library that defined RoCreateCharacterSuccess class, thereby triggering the act of registering RoCreateCharacterSuccess class with the translator class.
First of all, I don't see any issue here. This is not a problem with C++ compiler or linker.
I can put breakpoints in any other C++ file in that same project and
it will be hit during debugging. There's nothing special about this
C++ file. I use CMake to generate the projects and I also refer to the
class in the executable project. There are no linking errors, just
that debugger says that no debug symbols have been loaded for that
source file.
What going on here really is, When your executable program doesn't see explicit call to module - RoCreateCharacterSuccess.cpp in your static library, It will not link to the module.
If the program required a symbol defined in the module, that module would get linked; if not, it would be skipped. Thus any functions, symbols in RoCreateCharacterSuccess.cpp module will never exist.
RoCreateCharacterSuccess.cpp is considered an unused module.
Since symbols have not been loaded for the module, Visual Studio ends up reporting that the breakpoints will not be hit. Which is obvious.
To make this file be able to have active breakpoints, I have to
manually register the packet with the translator in the application.
When you manually registered the packet with the translator module in application, RoCreateCharacterSuccess.cpp module got linked and the breakpoint was available. You were able to hit the breakpoints in that module.
It's like RoCreateCharacterSuccess.cpp is never part of the static
library it's supposed to be in. But if I purposefully change the file
to introduce a syntax error, the library fails to build.
BTW, This is true for any program, any syntax errors will result in compilation failure. I understand you did that to check if your program was loading correct module, but that really is not the problem.
Update #Vite Falcon I'm glad my answer gave you hint to find out why the breakpoint wasn't active. Evidently, It was compiler who was optimising inline function calls and breaking the connection between the module and program.

Trouble compiling dll that accesses another dll

So, I have an interesting issue. I am working with a proprietary set of dlls that I ,obviously, don't have the source for. The goal is to write an intermediate dll that groups together a large series of funnction calls from the proprietary dlls. The problem I am having, when compiling with g++, is that I get errors for the original dlls along the lines of:
cannot export libname_NULL_THUNK_DATA. Symbol not found.
If I add a main and just compile to an executable everything works as expected. I'm using mingw for compilation. Thanks for any help.
In response to the first reply: Either I'm confused about what you're saying or I didn't word my question very well. I'm not explicitly trying to export anything from my wrapper I am just calling functions from their dlls. The problem is that I get errors that it can't export these specific symbols from the dll to my wrapper. The issue is that I'm not even entirely sure what these _NULL_THUNK_DATA symbols are for. I did a search and read somewhere that they shouldn't be exported because they're internal symbols that windows uses. I have tried using the --exclude-symbols directive to the linker but it didn't seem to do anything. I apologize if I'm completely misunderstanding what you're trying to say.
So, I think my issue was related to this. When just compiling a standard executable that uses a dll I was able to include the headers and directly call the functions for example:
#include :3rdparty.h
int main(){
dostuff(); // a function in the 3rdparty.dll
}
this would compile and run fine. I just needed to link the libraries in the g++ command.
When linking with the -shared flag I would get these errors (with main removed of course). I think it has something to do with the fact that by default g++ attempts to import all symbols from the dll. What I didn't understand is why this happens in the dll vs in an executable. I will try doing it using GetProcAddress(). Thank you!
it should be as easy as you think it should be.
eg:
your dll code needs:
void doStuff()
{
3rdparty.login();
3rdparty.dostuff();
3rdparty.logoff();
};
so far - so good, you've included the right headers .... (if you have them, if you don't then you need to import the library using LoadLibrary(), then create a function pointer to each exported dll entrypoint using GetProcAddress() and then call that function pointer)
You then link with the 3rd party lib and that's it. Occasionally you will have to wrap the definitions with 'extern "C"' in order to get the linkage name mangling correct.
As you say you're using g++, you can't be getting confused with __declspec(dllimport) which is a MS VC extension.
"Compiling" tells me that you're approaching this from the wrong end. Your DLL should not export its own wrapper functions, but directly refer to exports from other DLLs.
E.g. in a Windows Kernel32.DEF file, the following forward exists:
EXPORTS
...
HeapAlloc = NTDLL.RtlAllocHeap
There's no code for the HeapAlloc function.