This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
RFC: gdb_assert with 'catch signal ...' and fork
- From: Philippe Waroquiers <philippe dot waroquiers at skynet dot be>
- To: gdb-patches at sourceware dot org
- Date: Sat, 04 May 2013 00:37:25 +0200
- Subject: RFC: gdb_assert with 'catch signal ...' and fork
gdb 7.6 'catch signal' interacts badly with fork, causing a gdb_assert
such as
break-catch-sig.c:152: internal-error: signal_catchpoint_remove_location: Assertion `signal_catch_counts[iter] > 0' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n)
This can be reproduced with a (patched) gdb.base/catch-signal.c.
The problem is that the signal_catch_counts is decremented
by detach_breakpoints.
The patch below modifies catch-signal.c, catch-signal.exp
and modifies breakpoint.c so as to avoid the assert.
2 questions:
1. The fix is based on the assumption that detach_breakpoints
only has to detach breakpoints and watchpoints,
but not catchpoints (see breakpoints.h comments,
that do not fully match the implementation which
e.g. also detach the single step breakpoints).
Unclear to me if this is the good fix ?
(the fix causes no regtest failure)
2. when running the modified catch-signal test with an
unpatched gdb, the test fails but gdb.log does not contain
the assert. Rather, the test fails with 'the program exited'.
When doing the same commands manually, it shows the gdb assert.
No idea why this difference of behaviour.
Philippe
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.759
diff -r1.759 breakpoint.c
3552a3553,3555
> if (bl->owner->type == bp_catchpoint)
> continue;
>
Index: testsuite/gdb.base/catch-signal.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/catch-signal.c,v
retrieving revision 1.3
diff -r1.3 catch-signal.c
17a18
> #include <stdlib.h>
46a48,59
>
> signal (SIGCHLD, handle);
> switch (fork()) /* fork marker */
> {
> case -1:
> perror ("fork");
> exit (1);
> case 0:
> exit (0);
> }
> (void) wait(NULL);
> raise (SIGHUP); /* fifth HUP */
Index: testsuite/gdb.base/catch-signal.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/catch-signal.exp,v
retrieving revision 1.4
diff -r1.4 catch-signal.exp
85a86,87
>
> delete_breakpoints
86a89,95
> # Test interaction with fork. This used to cause a gdb_assert.
> gdb_breakpoint ${srcfile}:[gdb_get_line_number "fork marker"]
> gdb_continue_to_breakpoint "fork marker"
> gdb_test "handle SIGHUP nostop noprint pass" \
> "SIGHUP.*No.*No.*Yes.*"
> gdb_test "catch signal SIGHUP" "Catchpoint .*"
> gdb_test "continue" "Catchpoint .* SIGHUP.*" "got SIGHUP after fork"