gdb and valgrind within a makefile

2019-07-21 11:01发布

问题:

I have a very basic question. I did look around like over here http://www.cs.cmu.edu/~gilpin/tutorial/ but still doubtfull..

Consider the following makefile(had also given it in a previous question)

all: clients.so simulator backup  
   LD_PRELOAD=/home/Juggler/client/clients.so ./simulator  
backup: backup.c libclient.a
   gcc backup.c -o backup -L /home/Juggler/client -L. -lclient -ldl 
simulator: simulator.c libclient.a     
   gcc -g simulator.c -o simulator -L /home/Juggler/client -L. -lclient -ldl -pthread
libclient.a: libclient.o client.o     
   ar rcs libclient.a libclient.o client.o 
libclient.o:libclient.c
   gcc -c libclient.c -o libclient.o -pthread  
clients.so: client.o client_invoke.o     
   ld -shared -o clients.so client_invoke.o client.o -ldl 
client_invoke.o: client_invoke.c     
   gcc -Wall -fPIC -DPIC -c -g client_invoke.c 
client.o: client.c
   gcc -Wall -fPIC -DPIC -c -g client.c -ldl -pthread 

What do I do/change to debug using either gdb or valgrind. Actually I am getting a segmentation fault while doing make and would like to debug. But I have never used gdb or valgrind from within a makefile

Thanks

回答1:

I made a small edit to your presentation. You originally wrote

client.o: client.c     gcc -Wall -fPIC -DPIC -c -g client.c -ldl -pthread 

Can you change it to the new form and see if make segfaults?



回答2:

normally I would do something to the effect of:

   $(DEBUGGER) ./simulator

then

$ make DEBUGGER=gdb --args
$ make DEBUGGER=valgrind
$ make # should still work without the debugger.

(technically the --args isn't needed for the command like it is, but if you add arguments to simulator in the future.)

but using LD_PRELOAD complicates this, because you probably don't want gdb loading libclient

   gdb -ex 'set env LD_PRELOAD=/home/Juggler/client/clients.so' -ex 'run' ./simulator

Additionally its normal to link shared libraries through gcc via gcc -shared -o client.so



回答3:

One inelegant way would be to spawn the process via the makefile, and then attach to it with GDB in another terminal. Using the trick from linux: suspend process at startup, you can launch the process and have it suspend immediately, and then connect with gdb.

have a script called launch.sh: #!/bin/bash

echo "Pid is $$"
echo -n "Press Enter.." 
read 
exec $@

have a makefile recipe like this:

whatever_target: whatever_deps
        ./launch.sh PROGRAM [ARGS]

if for some reason you can't see the output (like if you are redirecting), you can still get the PID via ps -ef or something. then with gdb:

gdb PROGRAM_NAME PID