|
Home > Archive > Unix Programming > October 2007 > Debug multiple binaries
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Debug multiple binaries
|
|
| Tim Frink 2007-10-18, 1:30 am |
| Hi,
I've a C++ program that has been compiled with "gcc -g". This
program uses "syscall" to invoke another binary also compiled
with "gcc -g". What I now want is to debug the invoked binary.
I'm using gdb to debug the first program but didn't find any
possibility to continue debugging of the second binary after
its syscall invocation. So what I need is to make both
binaries visible to gdb then set a breakpoint in the
second program, run the first program and thus jump to the
breakpoint after the second program has been invoked. Any ideas
how to do that?
Regards,
Tim
| |
| Paul Pluzhnikov 2007-10-18, 1:30 am |
| Tim Frink <plfriko@yahoo.de> writes:
> I've a C++ program that has been compiled with "gcc -g". This
> program uses "syscall" to invoke another binary also compiled
> with "gcc -g".
Which 'syscall'? SYS_fork, SYS_execve, some other one?
Or do you mean 'system(3)' call (which is entirely different thing) ?
> What I now want is to debug the invoked binary.
How you do that depends on how exactly the other process was invoked.
One technique that works with any debugger, is to pass to the second
process a command-line parameter, e.g. --hang, which would cause that
process to wait forever. For example:
int main(int argc, char *argv[])
{
bool hang = check_for_hang_param(argc, argv);
while (hang) {
sleep(1);
}
// rest of main
}
Then you can attach debugger to the second process (blocked in
sleep()), set variable 'hang' to false, and proceed with your
further debugging. [Unfortunately, sometimes that's too late,
e.g. when you must debug early constructors and/or library
initializers.]
> I'm using gdb to debug the first program but didn't find any
> possibility to continue debugging of the second binary after
> its syscall invocation.
If you mean 'system(3)' call, then newer versions of gdb have a
'set follow-fork child', which might (on some platforms) allow you
to attach to the child. However, you would not be able to set any
breakpoints in your code yet, because the child is the shell. You'll
have to wait until shell exec()s your process, and then you should
be able to debug it. Generally, gdb in the past got easily confused
when crossing exec(), and it is unlikely you'll have a "smooth"
debugging session.
> So what I need is to make both binaries visible to gdb
I don't believe gdb is prepared to deal with multiple processes.
If you really want to debug both processes at once, and having two
separate gdb instances doesn't work for you, then maybe TotalView
is the answer.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
| |
| Tim Frink 2007-10-18, 1:25 pm |
| On Wed, 17 Oct 2007 20:31:25 -0700, Paul Pluzhnikov wrote:
> Which 'syscall'? SYS_fork, SYS_execve, some other one?
> Or do you mean 'system(3)' call (which is entirely different thing) ?
Sorry, I meant "system".
> How you do that depends on how exactly the other process was invoked.
> One technique that works with any debugger, is to pass to the second
> process a command-line parameter, e.g. --hang, which would cause that
> process to wait forever. For example:
>
> int main(int argc, char *argv[])
> {
> bool hang = check_for_hang_param(argc, argv);
> while (hang) {
> sleep(1);
> }
> // rest of main
> }
That's a possible solution. Thank you.
> If you mean 'system(3)' call, then newer versions of gdb have a
> 'set follow-fork child', which might (on some platforms) allow you
> to attach to the child. However, you would not be able to set any
> breakpoints in your code yet, because the child is the shell. You'll
> have to wait until shell exec()s your process, and then you should
> be able to debug it. Generally, gdb in the past got easily confused
> when crossing exec(), and it is unlikely you'll have a "smooth"
> debugging session.
Unfortunately, "set follow-fork child"
BTW, I have problem with breakpoints in constructors. When I
set a breakpoint there in gdb, the constructor will be executed
(I've inserted some printf) but the program execution does not
break at that point. Any ideas why?
Regards,
Tim
| |
|
| Tim Frink wrote:
> BTW, I have problem with breakpoints in constructors. When I
> set a breakpoint there in gdb, the constructor will be executed
> (I've inserted some printf) but the program execution does not
> break at that point. Any ideas why?
g++ outputs two versions of a constructor.
Perhaps gdb is setting the breakpoint in the wrong one?
Do you have recent versions of g++ and gdb?
| |
| Paul Pluzhnikov 2007-10-19, 1:33 am |
| Spoon <root@localhost> writes:
> Tim Frink wrote:
>
[vbcol=seagreen]
> g++ outputs two versions of a constructor.
If the constructor is inline, gcc outputs many more than 2 versions --
it emits 2 versions into every compilation unit that #includes
the definition of that constructor.
On some, but not all, platforms, these duplicate instances are
merged into one by the linker.
> Perhaps gdb is setting the breakpoint in the wrong one?
Likely. A "trick" that often works is to do 'rbreak SomeClass'
to set a breakpoint on every instance of every method of SomeClass.
Then run the exe, and delete all the breakpoints that aren't
interesting, as you hit them.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
| |
| Tim Frink 2007-10-19, 7:20 pm |
| On Thu, 18 Oct 2007 15:53:37 +0200, Spoon wrote:
> Do you have recent versions of g++ and gdb?
I'm using gcc 3.4.6. Unfortunately, I can't switch to
newer versions since some of the code is not compatible.
| |
| Tim Frink 2007-10-19, 7:20 pm |
| On Thu, 18 Oct 2007 21:41:55 -0700, Paul Pluzhnikov wrote:
> If the constructor is inline, gcc outputs many more than 2 versions --
> it emits 2 versions into every compilation unit that #includes
> the definition of that constructor.
How does gcc decide if the constructor will be inlined?
And why does it insert 2 versions for each #include?g one?
>
> Likely. A "trick" that often works is to do 'rbreak SomeClass'
> to set a breakpoint on every instance of every method of SomeClass.
> Then run the exe, and delete all the breakpoints that aren't
> interesting, as you hit them.
I'm solved this by adding a new function that is called in the
constructor. Each time this function with a breakpoint is entered
I do an "up" and get the calling constructor.
| |
| Paul Pluzhnikov 2007-10-20, 1:31 am |
| Tim Frink <plfriko@yahoo.de> writes:
> On Thu, 18 Oct 2007 21:41:55 -0700, Paul Pluzhnikov wrote:
>
>
> How does gcc decide if the constructor will be inlined?
I didn't say anything about 'gcc inlining'.
I said: if *you* declared the constructor inline, i.e. like this:
struct A { A() { /* body of ctor */ } ... };
When you do that, gcc has no option but to emit a copy of the "body"
into every compilation unit.
> And why does it insert 2 versions for each #include?g one?
There sometimes are 'in-charge' and 'not-in-charge' versions:
http://www.sourceware.org/ml/gdb/2003-10/msg00015.html
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
|
|
|
|
|