How to Determine Which Shared Library a Function Belongs to in gdb? - gdb

When I get the callstack from gdb, I only get function names and source file information.
(gdb) f
#0 main (argc=1, argv=0xbffff1d4) at main.c:5
I don't get which Shared Library or Application the function belongs to.
On Windows, Windbg or Visual Studio will show callstacks with "myDll!myFunc" format, which shows you which module the function belongs to.
Currently in gdb I'm using "info address [function]" to get the address of the function symbol, and then use "info share" to manually find the range in which the function lies in memory to determine which library it is in.
Anyway to see the library directly without this manual process?

You can use info symbol. It prints a library name for a function.
Like this:
(gdb) info symbol f
f(double) in section .text of libmylib_gcc.so
(gdb) info symbol printf
printf in section .text of /lib64/libc.so.6

Related

Why does this linker warning and segment fault happen?

I recently upgraded some external library version from librdkafka 1.3.0 to librdkafka 1.6.1.
After building the external library, it was linked as a shared object.
Then the following warning occurred when my program was linked.
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld:
Warning: type of symbol `mtx_lock' changed from 2 to 1
in ../externals/synapfilter/lib/libsnf.a(memoryUtil.cpp.o)
Also a segment fault occurred during program execution.
The output of gdb is as follows.
Program terminated with signal SIGSEGV, Segmentation fault.
b#0 0x0000000000f27a80 in mtx_lock ()
Missing separate debuginfos, use: debuginfo-install bzip2-libs-1.0.5-7.el6_0.x86_64 cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64 glibc-2.12-1.192.el6.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-57.el6.x86_64 libcom_err-1.41.12-22.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libicu-4.2.1-14.el6.x86_64 libselinux-2.0.94-7.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64 libzstd-1.4.5-3.el6.x86_64 lz4-r131-1.el6.x86_64 nss-softokn-freebl-3.14.3-23.3.el6_8.x86_64 openssl-1.0.1e-57.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt
#0 0x0000000000f27a80 in mtx_lock ()
#1 0x00007f59479a38cc in rd_kafka_global_cnt_incr () at rdkafka.c:182
#2 rd_kafka_new (type=type#entry=RD_KAFKA_PRODUCER, app_conf=app_conf#entry=0x2531870, errstr=errstr#entry=0x7ffd71c7c7d0 <incomplete sequence \350>,
errstr_size=errstr_size#entry=512) at rdkafka.c:2092
I found that the name(mtx_lock) in the two external libraries used was duplicated.
It was used as a global variable in one object file of the libsnf.a.
$ objdump -t memoryUtil.cpp.o | grep mtx_lock
0000000000000000 g O .bss 0000000000000028 mtx_lock
Also the name was used as a function in one object file of the librdkafka.a.
$ objdump -t tinycthread.o | grep mtx_lock
0000000000000090 g F .text 0000000000000016 mtx_lock
I wonder why this is happening and how to fix it.
In my makefile, I linked a libsnf.a as a static library and librdkafka.so as a dynamic library.
I wonder why this is happening
You have two separate object files: memoryUtil.cpp.o and tinycthread.o, defining the same symbol: mtx_lock. One of them defines it as a function, the other as a variable.
Normally this should result in "multiply defined" symbol error at link time, but you get a warning instead. I am not sure why; perhaps one of these symbol definitions is weak.
(In general, you should never use objdump to look at ELF symbols -- use readelf -Ws instead.)
Your program proceeds to call mtx_lock(), but gets a data variable instead, and crashes.
and how to fix it.
Since these libraries are open source, the easiest fix is to rename one (or both) of the variables, and rebuild.
If you don't want to rebuild, you could use objcopy --redefine-sym ... to achieve the same result.
Update:
The mtx_lock() function is part of the C11 standard, which makes its use as a variable in libsnf highly problematic.

Call ambiguous function in gdb with stripped symbols

I'm trying to call a function with
(gdb) call fun()
in a 3rd party library libFoo which I get in compiled form with stripped symbols.
(gdb) info function ^fun$
Non-debugging symbols:
0x00007ffff6d7e3b0 fun
Problem is, there is an unrelated system library libBar loaded which also has fun in it, a variable this time, and gdb prefers that symbol instead of the desired one. I suspect that this is because this hit is a non-stripped debugging symbol.
(gdb) info var ^fun$
File ../bar/baz.c:
256: static const int fun[18];
(gdb) info symbol fun
fun in section .rodata of libBar.so
It's a bit crazy that it tries to call variable as a function, but that's what it tries to do.
The question is, how do I disambiguate the symbol and instruct gdb to use one from libFoo ?
So far, the only way I found requires a manual step (info function ^fun$ above) and then call (void)0x00007ffff6d7e3b0(). This isn't too good because it doesn't allow me to script the call across different program runs.

Calling to a pointer from a c++ thread

I'm trying to call from a thread to a pointer.
Here is my code:
myDll.dll c++ :
long cbAddrAsync;
void _asyncer(void* data)
{
typedef void (__stdcall *FUNCPTR)();
FUNCPTR vbFunc;
vbFunc = (FUNCPTR)cbAddrAsync;
vbFunc();
}
extern "C" __declspec(dllexport) void async(long addr)
{
cbAddrAsync = addr;
HANDLE hHandle = (HANDLE)_beginthread(_asyncer,0,NULL);
}
calling to this extern with vb6:
In Module1:
Declare Sub async Lib "myDll.dll" (ByVal addr As Long)
Sub onAsync()
MsgBox "ASYNC"
End Sub
In Form1:
Private Sub Command_Click()
Call async(AddressOf Module1.onAsync)
End Sub
when i click at command button , The problem occurs in
dll:
Unhandled exception at 0x734f9232 in Project1.exe: 0xC0000005: Access violation reading location 0x00000076.
in vbFunc();
How can I fix it?
Thanks.
0x00000076 is an invalid memory address. All addresses under 0x0000ffff are invalid. This catches a whole class of errors (failed memory allocations or object creation) along the lines of 0x0 and 0x0 + 2 (or 0x0 + 0x76) etc. The errors are errors that programmers are supposed to check for but often don't.
My guess is you are accessing the 0x76th byte of a structure that wasn't initialised.
VB6 is designed to be a COM server not a dynamic load dll.
AddressOf has rules because you are actually calling VB6 runtime not your program.
You can also start in a debugger.
windbg or ntsd (ntsd is a console program and maybe installed). Both are also from Debugging Tools For Windows.
Download and install Debugging Tools for Windows
http://msdn.microsoft.com/en-us/windows/hardware/hh852363
Install the Windows SDK but just choose the debugging tools.
Create a folder called Symbols in C:\
Start Windbg. File menu - Symbol File Path and enter
srv*C:\symbols*http://msdl.microsoft.com/download/symbols
then
windbg -o -g -G c:\windows\system32\cmd.exe /k batfile.bat
You can press F12 to stop it and kb will show the call stack (g continues the program). If there's errors it will also stop and show them.
Type lm to list loaded modules, x *!* to list the symbols and bp symbolname to set a breakpoint
If programming in VB6 then this environmental variable link=/pdb:none stores the symbols in the dll rather than seperate files. Make sure you compile the program with No Optimisations and tick the box for Create Symbolic Debug Info. Both on the Compile tab in the Project's Properties.
Also CoClassSyms (microsoft.com/msj/0399/hood/hood0399.aspx) can make symbols from type libraries.

GDB can't find symbol defined in header file of boost BGL

I am able to compile and run an executable that uses C++ boost graph library (BGL) on OSX 10.8.3.
But when I try to debug using either gdb or Xcode the debugger is unable to find symbols defined in the BGL header file adjacency_list.hpp.
I looked at the file and tried different namespaces
boost::in_degree
boost::detail::in_degree
But debuggers could not find symbols.
It seems the function is inlined and the information is lost.
I tried another function (add_vertex) with same result.
I compile the code using CMake with the flag -DCMAKE_BUILD_TYPE=Debug and I am able to print other symbols.
Please suggest how can I fix this.
// Trying using
(gdb) print boost::detail::in_degree
No symbol "in_degree" in namespace "boost::detail".
(gdb) print boost::detail::in_degree(0, *pGraph)
No symbol "in_degree" in namespace "boost::detail".
(gdb) print boost::in_degree(0, *pGraph)
No symbol "in_degree" in namespace "boost".
// Trying using boost::
(gdb) pt boost::in_degree
No symbol "in_degree" in namespace "boost".
(gdb) pt boost::in_degree(0, *pGraph)
No symbol "in_degree" in namespace "boost".

VS2008 debugger and kernel32.dll

I've been just debugging a process (in C++/windows) which uses "GetThreadContext" which is in kernel32.dll.
I noticed that I could get it's address with
unsigned long address = (unsigned long)(&GetThreadContext);
but when I looked at the loaded modules tab - I saw that the symbols for kernel32.dll were not loaded!
How did the VS2008 know the address of "GetThreadContext"?
And how can I do it myself without having the PDBs?
thanks :)
This works for the same reason that
GetThreadContext(hThread, lpContext);
works. Named functions used in your code must be resolved at link-time, or the link would fail. Whether you are taking their address using & or calling them does not matter. At runtime, the DLL is loaded and the function name then resolves to a specific address in the process.
PDB files are used only to provide enhanced symbolic information during debugging. Normally, they are not used at runtime.
[I can't help thinking I'm missing something about this question. Tell me if this is not your problem.]