IRC, freenode, #hurd, 2013-07-07

<zyg> Hi, I'm in GDB inside a handler for SIGHUP, after stepping out, gdb
  will hang on instruction: <_hurd_sigstate_lock+88>:  xchg
<zyg> here is my signal test pasted:
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>

    void *
    my_handler(int signal, void *info, void *context)
      printf("got SIGHUP\n");
      return NULL;

    install_handler (int signal)
      struct sigaction sa;
      sa.sa_sigaction = my_handler;
      sa.sa_flags = SA_SIGINFO;
      sigaction(signal, &sa, NULL);

    void test_sighup(void)

    int main(int argc, char **argv){
<braunr> zyg: thanks
<braunr> zyg: what is the problem exactly ?
<braunr> zyg: i mean, does it hand before attaching with gdb ?
<zyg> braunr: it doesn't hang if runned without gdb. I've pasted here when
  I step out of the handler, and get to the hanging instruction:
    $ gdb --args a.out
    GNU gdb (GDB) 7.6-debian
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-gnu".
    For bug reporting instructions, please see:
    Reading symbols from /home/shrek/a.out...(no debugging symbols found)...done.

    (gdb) display/i $pc
    (gdb) handle SIGHUP pass stop print
    Signal        Stop      Print   Pass to program Description
    SIGHUP        Yes       Yes     Yes             Hangup

    (gdb) run
    Starting program: /home/shrek/a.out
    [New Thread 3571.5]

    Program received signal SIGHUP, Hangup.
    0x010548ec in mach_msg_trap ()
        at /build/buildd-eglibc_2.17-6-hurd-i386-g946kE/eglibc-2.17/build-tree/hurd-i386-libc/mach/mach_msg_trap.S:2
    2       /build/buildd-eglibc_2.17-6-hurd-i386-g946kE/eglibc-2.17/build-tree/hurd-i386-libc/mach/mach_msg_trap.S: No such file or directory.
    1: x/i $pc
    => 0x10548ec <mach_msg_trap+12>:        ret

    (gdb) si
    0x0804862d in my_handler ()
    1: x/i $pc
    => 0x804862d <my_handler>:      push   %ebp
    (gdb) x/20xi 0x804862d
    => 0x804862d <my_handler>:      push   %ebp
       0x804862e <my_handler+1>:    mov    %esp,%ebp
       0x8048630 <my_handler+3>:    sub    $0x18,%esp
       0x8048633 <my_handler+6>:    movl   $0x8048750,(%esp)
       0x804863a <my_handler+13>:   call   0x8048500 <puts@plt>
       0x804863f <my_handler+18>:   mov    $0x0,%eax
       0x8048644 <my_handler+23>:   leave
       0x8048645 <my_handler+24>:   ret
       0x8048646 <install_handler>: push   %ebp
       0x8048647 <install_handler+1>:       mov    %esp,%ebp
       0x8048649 <install_handler+3>:       sub    $0x28,%esp
       0x804864c <install_handler+6>:       movl   $0x804862d,-0x14(%ebp)
       0x8048653 <install_handler+13>:      movl   $0x40,-0xc(%ebp)
       0x804865a <install_handler+20>:      lea    -0x14(%ebp),%eax
       0x804865d <install_handler+23>:      add    $0x4,%eax
       0x8048660 <install_handler+26>:      mov    %eax,(%esp)
       0x8048663 <install_handler+29>:      call   0x80484d0 <sigemptyset@plt>
       0x8048668 <install_handler+34>:      movl   $0x0,0x8(%esp)
       0x8048670 <install_handler+42>:      lea    -0x14(%ebp),%eax
       0x8048673 <install_handler+45>:      mov    %eax,0x4(%esp)

    (gdb) break *0x804863f
    Breakpoint 1 at 0x804863f
    (gdb) c
    got SIGHUP

    Breakpoint 1, 0x0804863f in my_handler ()
    1: x/i $pc
    => 0x804863f <my_handler+18>:   mov    $0x0,%eax

    (gdb) si
    0x08048644 in my_handler ()
    1: x/i $pc
    => 0x8048644 <my_handler+23>:   leave
    0x08048645 in my_handler ()
    1: x/i $pc
    => 0x8048645 <my_handler+24>:   ret
    0x010708b2 in trampoline () from /lib/i386-gnu/
    1: x/i $pc
    => 0x10708b2 <trampoline+2>:    add    $0xc,%esp
    0x010708b5 in trampoline () from /lib/i386-gnu/
    1: x/i $pc
    => 0x10708b5 <trampoline+5>:    ret
    __sigreturn (scp=0x102988c) at ../sysdeps/mach/hurd/i386/sigreturn.c:30
    30      ../sysdeps/mach/hurd/i386/sigreturn.c: No such file or directory.
    1: x/i $pc
    => 0x1096340 <__sigreturn>:     push   %ebp
    0x01096341      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096341 <__sigreturn+1>:   push   %edi
    0x01096342      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096342 <__sigreturn+2>:   push   %esi
    0x01096343      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096343 <__sigreturn+3>:   push   %ebx
    0x01096344      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096344 <__sigreturn+4>:   sub    $0x2c,%esp
    0x01096347      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096347 <__sigreturn+7>:   mov    0x40(%esp),%esi
    0x0109634b      30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x109634b <__sigreturn+11>:  call   0x11a0609 <__x86.get_pc_thunk.bx>
    0x011a0609 in __x86.get_pc_thunk.bx () from /lib/i386-gnu/
    1: x/i $pc
    => 0x11a0609 <__x86.get_pc_thunk.bx>:   mov    (%esp),%ebx
    0x011a060c in __x86.get_pc_thunk.bx () from /lib/i386-gnu/
    1: x/i $pc
    => 0x11a060c <__x86.get_pc_thunk.bx+3>: ret
    0x01096350 in __sigreturn (scp=0x102988c) at ../sysdeps/mach/hurd/i386/sigreturn.c:30
    30      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096350 <__sigreturn+16>:  add    $0x15ccb0,%ebx
    35      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096356 <__sigreturn+22>:  test   %esi,%esi
    0x01096358      35      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096358 <__sigreturn+24>:  je     0x10964f0 <__sigreturn+432>
    0x0109635e      35      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x109635e <__sigreturn+30>:  testl  $0x10100,0x4(%esi)
    0x01096365      35      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x1096365 <__sigreturn+37>:  jne    0x10964f0 <__sigreturn+432>
    __hurd_threadvar_location_from_sp (__sp=<optimized out>, __index=<optimized out>) at ../hurd/hurd/threadvar.h:94
    94      ../hurd/hurd/threadvar.h: No such file or directory.
    1: x/i $pc
    => 0x109636b <__sigreturn+43>:  mov    -0x38(%ebx),%ebp
    __hurd_threadvar_location (__index=_HURD_THREADVAR_SIGSTATE) at ../hurd/hurd/threadvar.h:116
    116     in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x1096371 <__sigreturn+49>:  mov    %esp,%edx
    __hurd_threadvar_location_from_sp (__sp=0x1029848, __index=_HURD_THREADVAR_SIGSTATE) at ../hurd/hurd/threadvar.h:94
    94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x1096373 <__sigreturn+51>:  cmp    0x0(%ebp),%esp
    0x01096376      94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x1096376 <__sigreturn+54>:  jae    0x10964d0 <__sigreturn+400>
    0x0109637c      94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x109637c <__sigreturn+60>:  mov    -0x15c(%ebx),%eax
    0x01096382      94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x1096382 <__sigreturn+66>:  and    (%eax),%edx
    0x01096384      94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x1096384 <__sigreturn+68>:  mov    -0x90(%ebx),%eax
    0x0109638a      94      in ../hurd/hurd/threadvar.h
    1: x/i $pc
    => 0x109638a <__sigreturn+74>:  add    (%eax),%edx
    _hurd_self_sigstate () at ../hurd/hurd/signal.h:165
    165     ../hurd/hurd/signal.h: No such file or directory.
    1: x/i $pc
    => 0x109638c <__sigreturn+76>:  mov    0x8(%edx),%edi
    0x0109638f      165     in ../hurd/hurd/signal.h
    1: x/i $pc
    => 0x109638f <__sigreturn+79>:  test   %edi,%edi
    0x01096391      165     in ../hurd/hurd/signal.h
    1: x/i $pc
    => 0x1096391 <__sigreturn+81>:  je     0x1096598 <__sigreturn+600>
    __sigreturn (scp=0x102988c) at ../sysdeps/mach/hurd/i386/sigreturn.c:42
    42      ../sysdeps/mach/hurd/i386/sigreturn.c: No such file or directory.
    1: x/i $pc
    => 0x1096397 <__sigreturn+87>:  mov    %edi,(%esp)
    0x0109639a      42      in ../sysdeps/mach/hurd/i386/sigreturn.c
    1: x/i $pc
    => 0x109639a <__sigreturn+90>:  call   0x1051d70 <_hurd_sigstate_lock@plt>
    0x01051d70 in _hurd_sigstate_lock@plt () from /lib/i386-gnu/
    1: x/i $pc
    => 0x1051d70 <_hurd_sigstate_lock@plt>: jmp    *0x864(%ebx)
    _hurd_sigstate_lock (ss=ss@entry=0x1244008) at hurdsig.c:170
    170     hurdsig.c: No such file or directory.
    1: x/i $pc
    => 0x106bb90 <_hurd_sigstate_lock>:     sub    $0x1c,%esp
    0x0106bb93      170     in hurdsig.c
    1: x/i $pc
    => 0x106bb93 <_hurd_sigstate_lock+3>:   mov    %ebx,0x14(%esp)
    0x0106bb97      170     in hurdsig.c
    1: x/i $pc
    => 0x106bb97 <_hurd_sigstate_lock+7>:   call   0x11a0609 <__x86.get_pc_thunk.bx>
    0x011a0609 in __x86.get_pc_thunk.bx () from /lib/i386-gnu/
    1: x/i $pc
    => 0x11a0609 <__x86.get_pc_thunk.bx>:   mov    (%esp),%ebx
    0x011a060c in __x86.get_pc_thunk.bx () from /lib/i386-gnu/
    1: x/i $pc
    => 0x11a060c <__x86.get_pc_thunk.bx+3>: ret
    0x0106bb9c in _hurd_sigstate_lock (ss=ss@entry=0x1244008) at hurdsig.c:170
    170     in hurdsig.c
    1: x/i $pc
    => 0x106bb9c <_hurd_sigstate_lock+12>:  add    $0x187464,%ebx
    0x0106bba2      170     in hurdsig.c
    1: x/i $pc
    => 0x106bba2 <_hurd_sigstate_lock+18>:  mov    %esi,0x18(%esp)
    170     in hurdsig.c
    1: x/i $pc
    => 0x106bba6 <_hurd_sigstate_lock+22>:  mov    0x20(%esp),%esi
    sigstate_is_global_rcv (ss=0x1244008) at hurdsig.c:162
    162     in hurdsig.c
    1: x/i $pc
    => 0x106bbaa <_hurd_sigstate_lock+26>:  lea    0x57c0(%ebx),%eax
    0x0106bbb0      162     in hurdsig.c
    1: x/i $pc
    => 0x106bbb0 <_hurd_sigstate_lock+32>:  mov    (%eax),%eax
    163     in hurdsig.c
    1: x/i $pc
    => 0x106bbb2 <_hurd_sigstate_lock+34>:  test   %eax,%eax
    0x0106bbb4      163     in hurdsig.c
    1: x/i $pc
    => 0x106bbb4 <_hurd_sigstate_lock+36>:  je     0x106bbbc <_hurd_sigstate_lock+44>
    0x0106bbb6      163     in hurdsig.c
    1: x/i $pc
    => 0x106bbb6 <_hurd_sigstate_lock+38>:  cmpl   $0x1,0x18(%esi)
    0x0106bbba      163     in hurdsig.c
    1: x/i $pc
    => 0x106bbba <_hurd_sigstate_lock+42>:  je     0x106bbe0 <_hurd_sigstate_lock+80>
    _hurd_sigstate_lock (ss=ss@entry=0x1244008) at hurdsig.c:172
    172     in hurdsig.c
    1: x/i $pc
    => 0x106bbe0 <_hurd_sigstate_lock+80>:  lea    0x4(%eax),%ecx
    __spin_try_lock (__lock=0x124480c) at ../sysdeps/mach/i386/machine-lock.h:59
    59      ../sysdeps/mach/i386/machine-lock.h: No such file or directory.
    1: x/i $pc
    => 0x106bbe3 <_hurd_sigstate_lock+83>:  mov    $0x1,%edx
    0x0106bbe8      59      in ../sysdeps/mach/i386/machine-lock.h
    1: x/i $pc
    => 0x106bbe8 <_hurd_sigstate_lock+88>:  xchg   %edx,0x4(%eax)
<braunr> zyg: i don't get what you mean
<braunr> are you starting it with gdb ?
<zyg> braunr: yes: "gdb --args a.out"
<braunr> ok
<braunr> can't reproduce it
<braunr> i get "Program received signal SIGHUP, Hangup.
<braunr> "
<braunr> then continue, then the program has exited
<zyg> braunr: do you run it in gdb or without?
<zyg> braunr: Ah "Program received signal SIGHUP, Hangup." is from
  gdb.. try issue continue, not sure why gdb stops at SIGHUP (default?).
<braunr> 10:34 < braunr> then continue, then the program has exited
<braunr> gdb stops at signals
<zyg> braunr: yes, try repeating that, but instead of continue, just issue
<zyg> braunr: sorry.. you would need to remove that printf/fprintf, else it
  gets too long. That's why I put a breakpoint.
<braunr> a breakpoint ?
<braunr> on the signal handler ?
<zyg> braunr: yes, put a break after having entered the handler. Or edit
  the pasted C code an remove that printf("got SIGHUP\n");
<braunr> i'm not sure that's correctly supported
<braunr> and i can see why glibc would deadlock on the sigstate lock
<braunr> don't do that :p
<zyg> braunr: why does it deadlock?
<braunr> because both the signal handler and messages from gdb will cause
  common code paths to be taken
<zyg> braunr: oh.. when I step instruction I'm inside an SIGTRAP handler
<braunr> possible
<braunr> i don't know the details but that's the kind of things i expect
<braunr> and signals on the hurd are definitely buggy
<braunr> i don't know if we support nesting them
<braunr> i'd say we don't
<zyg> braunr: I'll try to put a break beyond that xchg and continue
<braunr> xhcg is probably the sigstate spinlock
<braunr> xchg*
<braunr> you'd need to reach the unlock instruction, which is probably
  executed once the handler has finished running
<zyg> braunr: yes :) ... one instruction beyond didn't help
<zyg> braunr: thanks alot, putting a break in __sigreturn, after that
  function has called _hurd_sigstate_unlock@plt works!
<braunr> works ?
<braunr> what did you want to do ?
<zyg> braunr: I want to trace user code inside the signal handler, also how
  we enter and how we leave.
<braunr> well you can't do that inside, so no it doesn't work for you :/
<braunr> but that's a start i guess
<zyg> braunr: I seem to do most normal things inside the handler,
  step-instruction and put breaks.
<braunr> ?
<braunr> i thought that's what made the program deadlock
<zyg> braunr: as you said earlier, the deadlock came when i "step
  instruction" into the area between _hurd_sigstate_lock and
  _hurd_sigstate_unlock. Otherwise I havn't had any issues.
<braunr> but isn't the sigstate locked during the handler execution ?
<zyg> braunr: no it locks and unlocks in __sigreturn which is done when
  leaving the handler.
<braunr> than how could it deadlock on handler entry ?
<braunr> or perhaps the fact your handler was empty made the entry point
  directly reach __sigreturn
<braunr> hm no i don't buy it
<braunr> the sigstate must also be locked on entry
<zyg> braunr: there was never any problem with entering
<braunr> then describe the problem with more details please
<braunr> ah sorry
<zyg> braunr: are you sure? there is minimal user-code run before the
  signal is going into the handler.
<braunr> you "step out of the handler"

IRC, freenode, #hurd, 2013-10-24

<gnu_srs> how come some executables are not debuggable with gdb, e.g Cannot
  access memory at address xxx. -fPIC flag?
<braunr> no
<braunr> i'm not sure but it's certainly not -fPIC
<gnu_srs> Another example is localedef: ./debian/tmp-libc/usr/bin/localedef
  -i en_GB -c -f UTF-8 -A /usr/share/locale/locale.alias en_GB.UTF-8
<gnu_srs> and in gdb hangs after creating a thread., after C-c no useful
  info: stack ends with: Cannot access memory at address 0x8382c385
<braunr> if it's on the stack, it's probably a stack corruption
<nalaginrut> gnu_srs:  are u using 'x' command or 'print' in GDB? IIRC
  print may throw such message, but x may not
<gnu_srs> bt
<braunr> x may too
<braunr> what you're showing looks like an utf-8 string
<braunr> c385 is Å
<braunr> 83 is a special f
<braunr> 82 is a comma
<gnu_srs> so the stack is corrupted:-(
<braunr> probably
<braunr> well, certainly
<braunr> but gdb should show you where the program counter is
<gnu_srs> is that: ECX: the count register 
<braunr> no
<braunr> eip
<braunr> program counter == instruction pointer
<gnu_srs> k!, the program counter is at first entry in bt: #0  0x01082612
  in _hurd_intr_rpc_msg_in_trap () at intr-msg.c:133
<braunr> this is the hurd interruptible version of mach_msg
<braunr> so it probably means the corruption was made by a signal handler
<braunr> which is one of the reasons why gdb can't handle Ctrl-c
<gnu_srs> what to do in such a case, follow the source code
<braunr> single stepping also uses signals
<braunr> and using printf will probably create an infinite recursion
<braunr> in those cases, i use mach_print
<braunr> as a first step, you could make sure a signal is actually received
<braunr> and which one
<braunr> hmm
<braunr> also, before rushing into conclusions, make sure you're looking at
  the right thread
<braunr> i don't expect localedef to be multithreaded
<braunr> but gdb sometimes just doesn't get the thread where the segfault
  actually occurred
<gnu_srs> two threads: 1095.4 and 1095.5 (created when starting localedef
  in gdb)
<braunr> no, at the time of the crash
<braunr> the second thread is always the signal thread
<gnu_srs> OK,in gdb the program hangs, interrupted by C-c, outside it
<braunr> when you use bt to get the corrupted stack, you can also use info
  threads and thread apply all bt
<gnu_srs> I did:
<braunr> ok so it confirms there is only one real application thread, the
  main one
<braunr> and that the corruption probably occurs during signal handling
<gnu_srs> rpctrace (edited out non-printable characters):
<gnu_srs> Ah, have to do it again as root;-)
<braunr> yes .. :p
<gnu_srs> new last part:
<braunr> so, there is a seek, then a stat, then a close perhaps (port
  deallocation) and then a signal received (probably sigsegv)
<braunr> gnu_srs: when you try running it in gdb, do you get a sigkill ?
<braunr> damn, gdb on darnassus is bugged :-(
<gnu_srs> It hangs, interrupted with C-c.
<braunr> ok