Nowdays I use qnx gdb server to debug a application, but there are some amazing things happend.
There are lots of files in my project, for examples
src/a.c src/b.c src/c.c
include/a.h include/b.h include/c.h
using Makefile, I generate a libso file named libtest.so and a executable file name helloworld.
I scp the libtest.so and helloworld to target machine, and the path is /home/user/myapp/ and set PATH well, and I can run helloworld in target machine
Attention there is a fun name Display() fun in the libtest.so, and there is a fuction named myfun() in the include/c.h(at line 5), and myfun will call Dislpay() function:
myfun(){Display();}
When I use qnx gdb server , the step is as follows:
1. ntoaarch64-gdb
2. file helloworld
3. target qnx IP:PORT
4. upload helloworld /home/user/helloworld
5. b c.h:5
6. r
It call stop at breakpoint myfun(), but when I run step or stepi command,
it can not step into Display() function, and I run disassemblecommand,
it show 0x100cd5e0 <Display#plt>, There is no disassembly content about Display function, I seemed be omitted!
There are any worng or missing step when I debug this application, who can help my, I have speed five days... Thank a lot
By the way, I think is a gdb server question instead of a qnx gdb server question.
but when I run step or stepi command, it can not step into Display() function
This is somewhat expected with lazy dynamic symbol resolution. Note that if you call myfun again, you should be able to step into Display without problems.
The best solution is to set a break Display.
Alternatively, you could use export LD_BIND_NOW=1 before running helloworld, or link the binary with -Wl,-z,now to disable lazy symbol binding.
Related
I need to set breakpoints in a cpp source file. The current setup to call the cpp target is through a shell target, with additional dependencies, which means it's not feasible to directly invoke the cpp target in Linux console.
As I searched online, there are generally two ways:
invoke gdb in shell
pause in cpp, let gdb connect to the process
I don't know how to do the first way, so I choose the second way here.
I insert sleep(30) in cpp file, then in another terminal I open gdb and connect to the running process. I confirm the gdb can stop at the sleep() function in gdb. But the problem is the gdb seems only knowing the sleep function context, without knowing the call site of the sleep function. If I force setting breakpoint in the main program, gdb shows no such file. If I continue in gdb, it will not stop at any breakpoints I set in cpp file.
You need to compile the program with debug symbols. Otherwise GDB will only know of symbols in the dynamic symbol table. Turning off optimizations also helps debugging. So add the flags -O0 -g.
If this is not possible, you'll have have to step through the disassembly (Ctrl+X, 2).
I am new to Linux space.
My project creates 'so' (akin to our dll's) which is used by an executable.
Currently to debug, I invoke gdb -tui Which puts me into the gdb terminal where I put break points and do the r with parameters ... and debug.
Everything was fine, until now where the entire architecture has been changed.
Now to run our code, we execute a command
$ java -jar ... and a lot many parameters.
The jar files etc do not belong to us.
I am yet to find out what executable is called, or the code flow.
Question :
Is there a way to invoke gdb command from within my source code ?
say
MyClass::myFunc()
{
some calls
<THE GDB COMMAND>
What I am looking at is, once I place my 'so' in the path and execute the said java command, the gdb is invoked the moment it hits my function.
The solution provided here wasn't clear.
Invoke and control GDB from c++
I am using gdb to debug NS-2 which is a simulator for network protocols. It takes an .tcl file as input and interpret it. [I think it is an interpreter.]
Some of the code is written in tcl (events and creation of network components) and some in C++ (especially Packet Formats, Agents etc.).
I have created an Agent in C++ and i want to stop it at some function call so that i can see the stack trace and find which other classes have been called before it.
This is what i have done:
There was some error in one of my MyAgent::function and it was giving Segmentation Fault and gdb was stopping there automatically. I could then see the stack trace. I rectified the error.
Now when i run
gdb ./ns
b MyAgent::function()
/*
When i press TAB after writing "b MyA" it gives me all functions
of my class :). when i press enter after above command --
it asks me "Breakpoint on future shared library load" and i say Yes.
I hope this is ok ??
*/
r myfiles/myWireless.tcl
Now it runs and do not stop anywhere. :(
I am sure that this function is being called, because when that Segmentation fault was occuring, it was stopping at that function.
Thanks
You can add a breakpoint in that function:
(gdb) break MyAgent::function()
You must make sure to compile with whatever options are necessary to get debug symbols. On GCC, use the -g or -ggdb options.
You need the -args option to specify the tcl script that will be executed.
Run gdb like this:
gdb -args ./ns path/to/tcl/script.tcl
To enable debug flag to c++ code, if have not done it already, re-configure your ns2 instalation with:
./configure --enable-debug ;# plus any other flags you use for configuring
make clean
make -j 3 ;# -j for faster compiling
make install ;# optional
You can also use the --with-tcldebug=..., for debugging tcl code (You need to install tcldebug first for this option)
I'm trying to debug a CUDA program, but when I'm launching gdb like so:
$ gdb -i=mi <program name>
$ r <program arguments>
I'm getting:
/home/wvxvw/Projects/cuda/exercise-1-udacity/cs344/HW2/hw:
error while loading shared libraries: libcudart.so.5.0:
cannot open shared object file: No such file or directory
Process gdb-inferior killed
(formatted for readability)
(I'm running gdb using M-xgdb) If that matters, then CUDA libraries are in the .bashrc
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
error while loading shared libraries: libcudart.so.5.0
This error has nothing to do with GDB: your executable, when run from inside GDB, can't find the library it needs.
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
GDB runs your program in a new $SHELL, so that should have worked. I wonder if there is some interaction with emacs.
In any case, this:
(gdb) set env LD_LIBRARY_PATH /usr/local/cuda/lib64
(gdb) run
should fix this problem.
Update:
as I've mentioned it before, ld path is set properly
No, it isn't. If it was, you wouldn't have the problem.
Now, I don't know why it isn't set properly. If you really want to find out, start by running GDB outside emacs (to exclude possible emacs interactions).
If the problem is still present, gdb show env, shell env, adding echo "Here" to your ~/.basrc, etc. should help you find where things are not working as you expect them.
I've had this problem as well. One way to look at it is that even if the LD_LIBRARY_PATH variable is correct when you enter show env into gdb, it may not be correct when you actually execute the program because gdb executes $SHELL -c <program> to run the program. Try this as a test, run $SHELL from the command line and then echo $LD_LIBRARY_PATH. Is it correct? If not, then you probably need to add it to your rc (.tcshrc in my case).
I had a similar problem when trying to run gdb on windows 7. I use MobaXterm to access a Linux toolbox. I installed gdb separately from http://www.gnu.org/software/gdb/ . I got it to work by making sure gdb could find the correct .dll files as mentioned by Employed Russian. If you have MobaXterm installed the .dll files should appear in your home directory in MobaXterm/slash/bin.
gdb however did not recognize the LD_LIBRARY_PATH variable. For me, it worked when I used the PATH variable instead:
(gdb) set env PATH C:\Users\Joshua\Documents\MobaXterm\slash\bin
(gdb) run
I would think using PATH instead of LD_LIBRARY_PATH might work for you provided you put the correct path to your library.
gdb is looking for a library, so why are you concerned with the include path? You may want to try to set the gdb option "solib-search-path" to point to the location of the libcudart.so.5.0 library.
I have two different version of a library let's say
libxyz.so
at two different location
1) /home/maverick/dev/libxyz.so ( development Version)
2) /home/maverick/prod/libxyz.so ( Production Version )
I have a setup that compile my program and link with appropriate version of the library depending on LD_LIBRARY_PATH. for example If I want to link my program with dev version of libxyz.so i change my LD_LIBRARY_PATH to add /home/maverick/dev and if I want to link with prod version I change LD_LIBRARY_PATH to add /home/maverick/prod instead.
I compiled my program by linking with dev version and the output of
ldd MyProg
is
libxyz.so => /home/maverick/dev/libxyz.so
If i run the program it loads the libxyz.so from
/home/maverick/dev/libxyz.so
and runs fine.
it this point my LD_LIBRARY_PATH includes /home/maverick/dev not /home/maverick/prod
but when I try to debug this program through GDB
gdb MyProg
it loads the libxyz.so from location
/home/maverick/prod/libxyz.so
I have trouble making GDB load the correct version of the library during debug. So till now what I am doing is first launch the program (that load the dev version) and attach gdb to that PID this way its works fine. but if it run like
gdb MyProg
it dosen't
I tried every thing to fix this like setting up sysroot, solib-search-path in GDB but nothing is working.
if fact when I set up sysroot to point to the debug version of the library gdb gave some message like
.dynamic section for XXX is not at the expected address
any suggestion would be appreciated.
I have trouble making GDB load the correct version of the library during debug.
Let me guess: you are using tcsh, right?
The problem most likely comes from yoour ~/.cshrc resetting LD_LIBRARY_PATH to /home/maverick/prod.
When you run the program in GDB, it executes $SHELL -c your-program [args...] (so as to allow you to use I/O redirection).
Solution: don't touch environment in your .cshrc for non-interactive shell, e.g. start it with:
if ($?prompt == 0) exit