I have a windows PC that is connected to a Linux server in LAN. The Windows is running Windows 10 64 bit while the Linux is Ubuntu 12.04 LTS (GNU/Linux 3.2.0-24-generic x86_64) CPU: Intel(R) Xeon(R) CPU E3-1505M v6 @ 3.00GHz.
I am trying to debug an .so file that is written in C targeted for the Linux server.
I get the process that accessing my .so file's PID and I run the gdbserver with this command gdbserver --attach :9999 <pid>
.
From my windows PC using cygwin64 gdb I used file
command to read the local copy of the .so file and connect to the gdbserver using gdb target attach <linuxServerIp>:9999
.
The problem is I cannot add breakpoint remotely from the windows pc. Any command to add breakpoint will cause Fail to access memory.
(gdb) break my_func
Breakpoint 1 at 0x36a13: my_func. (2 locations)
(gdb) c
Continuing.
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x36a13
Upon some inspection I try to run
(gdb) print my_func
$1 = {int ()} 0x369ff <my_func>
Then I try to run the gdb locally in the linux server. I run the print my_func and same address is retrieved
(gdb) print my_func
$1 = {int ()} 0x369ff <my_func>
Then I try to connect to the process using attach PID
(gdb) attach 28290
Attaching to process 28290
And then try to print my_func
address and add breakpoint to it.
(gdb) print my_func
$2 = false
(gdb) break my_func
Breakpoint 1 at 0x7fffe5b46a13: file src/myFlow/my_func.c, line 55.
(gdb) c
Continuing.
Notice here the address is not same as previously. Using this new memory, I able to break and inspect line by line. I then restarted the gdbserver, reconnect from my windows's gdb and try to break using this address in host PC. Now it able to break correctly.
(gdb) break *0x7fffe5b46a13
Breakpoint 1 at 0x7fffe5b46a13
Why my SO file change the function address when it is been loaded by external process? Why gdb in Linux PC able to translate the function address correctly when attaching to the PID while gdb in my windows PC that is connected using GDBServer cannot translate the address?
After some more reading I found out that the memory of the SO file will be loaded depending on the process that is using it. The address when inspecting the SO file is just an offset from the memory of the loaded SO file.
From this website
If you are debugging a shared object library, avoid specifying the .so file as a symbol file. With .so as a symbol file, the debugger resolves the source location to two places: one to the actual address in memory, and the other to a file address within the .so file, which is not a valid memory address. As a result, stepping and other debugging actions do not work correctly.
Thus as a solution , we need to load the SO file at the correct address using add-symbol-file command : https://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_14.html#:~:text=The%20add%2Dsymbol%2Dfile%20command,the%20program%20that%20is%20running.
add-symbol-file filename address
add-symbol-file filename address [ -readnow ] [ -mapped ]
add-symbol-file filename -ssection address
The add-symbol-file command reads additional symbol table information from the file filename. You would use this command when filename has been dynamically loaded (by some other means) into the program that is running. address should be the memory address at which the file has been loaded; GDB cannot figure this out for itself. You can additionally specify an arbitrary number of `-ssection address' pairs, to give an explicit section name and base address for that section. You can specify any address as an expression. The symbol table of the file filename is added to the symbol table originally read with the symbol-file command. You can use the add-symbol-file command any number of times; the new symbol data thus read keeps adding to the old. To discard all old symbol data instead, use the symbol-file command without any arguments. add-symbol-file does not repeat if you press RET after using it. You can use the `-mapped' and `-readnow' options just as with the symbol-file command, to change how GDB manages the symbol table information for filename.
So I need to using add-symbol-file <mySoFile> address
to load the .so file at correct address.
Thank you,