Fun with gdb and threads...

From: Peter Edwards (peter.edwards_at_openet-telecom.com)
Date: 08/07/03

  • Next message: Mike Silbersack: "another buildworld -j4 panic"
    To: current@freebsd.org
    Date: 07 Aug 2003 22:21:57 +0100
    
    
    

    Hi.
    This might be of interest to anyone who has tried debugging
    multi-threaded programs (of the libc_r variety) with gdb. This has been
    bugging me for months, and I finally got frustrated enough to find out
    what was going on.

    The symptom:

    Once you call any function that puts a thread to sleep, the target
    process crashes (simple program, 1.c attached, and log of gdb killing it
    in crash.txt)

    The problem:

    I traced this to an interaction between gdb and the threads scheduler.
    The initial crash comes from gdb adding internal breakpoints in the
    "(_)?(sig)?longjmp" functions. This breakpoint gets hit when the thread
    scheduler calls "_thread_kern_sched"

    After handling the breakpoint, gdb then needs to reset the instruction
    pointer in the "current thread" to re-run the instruction the breakpoint
    was at. However, at that point, gdb's freebsd_uthread_store_registers()
    barfs, thinking that the thread in question is not "active", because its
    not in state PS_RUNNING (it's just about to go to sleep). As a result,
    it mucks up the resetting of the instruction pointer, because it thinks
    it just needs to twiddle with the threads context, rather than the
    "live" registers.

    Once the process is resumed, it starts in the middle of whatever
    instruction the breakpoint overwrote, and generally fscking things up.

    The fix:

    I added a couple of "nop"s to "___longjmp", and created a new
    entrypoint below them called "___longjmp_raw". This provides a way for
    the libc_r library to avoid hitting the gdb breakpoints at sensitive
    moments. All other consumers still work the exact same way (modulo the
    time spent executing a couple of nops). The patch is attached, and makes
    gdb behave perfectly for me.

    Does anyone have any comments on this, or ideas on how to improve on it?
    The only penalty I can see is an extra "nop" instruction for normal
    longjmps, which I'll gladly trade for a usable debugger.

    PS:

    before anyone suggests it, I initially tried changing freebsd_uthread.c
    to check for the active thread more effectively, as is done in
    freebsd_uthread_fetch_registers, by comparing it with "_pthread_run",
    rather than checking the state.

    This improved things, but gdb still got confused, and started stopping
    unexpectedly when it lost it's breakpoints, etc, so I figured the other
    approach was probably going to be more stable.

    
    
    

    petere@rocklobster$ gcc -o 1 -g -Wall -pthread 1.c
    petere@rocklobster$ gdb ./1
    GNU gdb 5.2.1 (FreeBSD)
    Copyright 2002 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "i386-undermydesk-freebsd"...
    (gdb) b threadFunc
    Breakpoint 1 at 0x804861e: file 1.c, line 10.
    (gdb) run
    Starting program: /local/petere/1

    Breakpoint 1, threadFunc (arg=0x0) at 1.c:10
    10 sleep(1);
    (gdb) n

    Program received signal SIGSEGV, Segmentation fault.
    0x280d0138 in _longjmp () from /usr/lib/libc.so.5
    (gdb)

    
    

    _______________________________________________
    freebsd-current@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-current
    To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"



  • Next message: Mike Silbersack: "another buildworld -j4 panic"

    Relevant Pages

    • Re: Great SWT Program
      ... More a shell than an operating system, ... Gdb is for the birds. ... Well, debugging one's own code is what gdb is for, isn't it? ... Being able to make a breakpoint that would trip the first time any ...
      (comp.lang.java.programmer)
    • [PATCH 9/21] KGDB: This adds basic support to the MIPS architecture
      ... This patch also adds support for the rs232 early kgdb access for MIPS ... * To enable debugger support, ... * or error conditions to be properly intercepted and reported to gdb. ... a breakpoint needs to be generated to begin communication. ...
      (Linux-Kernel)
    • Re: How to implement the breakpoint in debugger?
      ... Breakpoint Handling ... the CPU raises an exception and reports it to GDB. ... theory is that GDB will replace a program instruction with a trap, ... set not to have any instructions usable for a software breakpoint, ...
      (comp.os.linux.misc)
    • Re: [Kgdb-bugreport] [PATCH][3/3] Update CVS KGDBs wrt connect / detach
      ... >>If gdb is restarted, kgdb has to remove all breakpoints. ... >>We have to check for gdb connection in putpacket or else following problem ... Once connected and running, ^C/hit breakpoint and ...
      (Linux-Kernel)
    • Re: More trouble with i386 EFLAGS and ptrace
      ... > The reason this happens is that when the inferior hits a breakpoint, ... So GDB does a PTRACE_SINGLESTEP, ... So the single-step completes and returns SIGTRAP to GDB. ... GDB tries to singlestep past the breakpoint - PTRACE_SINGLESTEP, ...
      (Linux-Kernel)