1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
|
[[!meta copyright="Copyright © 2013 Free Software Foundation, Inc."]]
[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable
id="license" text="Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license
is included in the section entitled [[GNU Free Documentation
License|/fdl]]."]]"""]]
[[!tag open_issue_gdb open_issue_glibc]]
# 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
%edx,0x4(%eax)
<zyg> here is my signal test pasted: http://pastebin.com/U72qw3FC
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void *
my_handler(int signal, void *info, void *context)
{
printf("got SIGHUP\n");
return NULL;
}
void
install_handler (int signal)
{
struct sigaction sa;
sa.sa_sigaction = my_handler;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(signal, &sa, NULL);
}
void test_sighup(void)
{
raise(SIGHUP);
}
int main(int argc, char **argv){
install_handler(SIGHUP);
test_sighup();
exit(1);
}
<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:
http://pastebin.com/nUyCx6Wj
$ 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 <http://gnu.org/licenses/gpl.html>
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:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/shrek/a.out...(no debugging symbols found)...done.
(gdb)
(gdb) display/i $pc
(gdb) handle SIGHUP pass stop print
Signal Stop Print Pass to program Description
SIGHUP Yes Yes Yes Hangup
(gdb)
(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)
(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)
(gdb) break *0x804863f
Breakpoint 1 at 0x804863f
(gdb) c
Continuing.
got SIGHUP
Breakpoint 1, 0x0804863f in my_handler ()
1: x/i $pc
=> 0x804863f <my_handler+18>: mov $0x0,%eax
(gdb)
(gdb) si
0x08048644 in my_handler ()
1: x/i $pc
=> 0x8048644 <my_handler+23>: leave
(gdb)
0x08048645 in my_handler ()
1: x/i $pc
=> 0x8048645 <my_handler+24>: ret
(gdb)
0x010708b2 in trampoline () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x10708b2 <trampoline+2>: add $0xc,%esp
(gdb)
0x010708b5 in trampoline () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x10708b5 <trampoline+5>: ret
(gdb)
__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
(gdb)
0x01096341 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096341 <__sigreturn+1>: push %edi
(gdb)
0x01096342 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096342 <__sigreturn+2>: push %esi
(gdb)
0x01096343 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096343 <__sigreturn+3>: push %ebx
(gdb)
0x01096344 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096344 <__sigreturn+4>: sub $0x2c,%esp
(gdb)
0x01096347 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096347 <__sigreturn+7>: mov 0x40(%esp),%esi
(gdb)
0x0109634b 30 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x109634b <__sigreturn+11>: call 0x11a0609 <__x86.get_pc_thunk.bx>
(gdb)
0x011a0609 in __x86.get_pc_thunk.bx () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x11a0609 <__x86.get_pc_thunk.bx>: mov (%esp),%ebx
(gdb)
0x011a060c in __x86.get_pc_thunk.bx () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x11a060c <__x86.get_pc_thunk.bx+3>: ret
(gdb)
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
(gdb)
35 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096356 <__sigreturn+22>: test %esi,%esi
(gdb)
0x01096358 35 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096358 <__sigreturn+24>: je 0x10964f0 <__sigreturn+432>
(gdb)
0x0109635e 35 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x109635e <__sigreturn+30>: testl $0x10100,0x4(%esi)
(gdb)
0x01096365 35 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x1096365 <__sigreturn+37>: jne 0x10964f0 <__sigreturn+432>
(gdb)
__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
(gdb)
__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
(gdb)
__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
(gdb)
0x01096376 94 in ../hurd/hurd/threadvar.h
1: x/i $pc
=> 0x1096376 <__sigreturn+54>: jae 0x10964d0 <__sigreturn+400>
(gdb)
0x0109637c 94 in ../hurd/hurd/threadvar.h
1: x/i $pc
=> 0x109637c <__sigreturn+60>: mov -0x15c(%ebx),%eax
(gdb)
0x01096382 94 in ../hurd/hurd/threadvar.h
1: x/i $pc
=> 0x1096382 <__sigreturn+66>: and (%eax),%edx
(gdb)
0x01096384 94 in ../hurd/hurd/threadvar.h
1: x/i $pc
=> 0x1096384 <__sigreturn+68>: mov -0x90(%ebx),%eax
(gdb)
0x0109638a 94 in ../hurd/hurd/threadvar.h
1: x/i $pc
=> 0x109638a <__sigreturn+74>: add (%eax),%edx
(gdb)
_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
(gdb)
0x0109638f 165 in ../hurd/hurd/signal.h
1: x/i $pc
=> 0x109638f <__sigreturn+79>: test %edi,%edi
(gdb)
0x01096391 165 in ../hurd/hurd/signal.h
1: x/i $pc
=> 0x1096391 <__sigreturn+81>: je 0x1096598 <__sigreturn+600>
(gdb)
__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)
(gdb)
0x0109639a 42 in ../sysdeps/mach/hurd/i386/sigreturn.c
1: x/i $pc
=> 0x109639a <__sigreturn+90>: call 0x1051d70 <_hurd_sigstate_lock@plt>
(gdb)
0x01051d70 in _hurd_sigstate_lock@plt () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x1051d70 <_hurd_sigstate_lock@plt>: jmp *0x864(%ebx)
(gdb)
_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
(gdb)
0x0106bb93 170 in hurdsig.c
1: x/i $pc
=> 0x106bb93 <_hurd_sigstate_lock+3>: mov %ebx,0x14(%esp)
(gdb)
0x0106bb97 170 in hurdsig.c
1: x/i $pc
=> 0x106bb97 <_hurd_sigstate_lock+7>: call 0x11a0609 <__x86.get_pc_thunk.bx>
(gdb)
0x011a0609 in __x86.get_pc_thunk.bx () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x11a0609 <__x86.get_pc_thunk.bx>: mov (%esp),%ebx
(gdb)
0x011a060c in __x86.get_pc_thunk.bx () from /lib/i386-gnu/libc.so.0.3
1: x/i $pc
=> 0x11a060c <__x86.get_pc_thunk.bx+3>: ret
(gdb)
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
(gdb)
0x0106bba2 170 in hurdsig.c
1: x/i $pc
=> 0x106bba2 <_hurd_sigstate_lock+18>: mov %esi,0x18(%esp)
(gdb)
170 in hurdsig.c
1: x/i $pc
=> 0x106bba6 <_hurd_sigstate_lock+22>: mov 0x20(%esp),%esi
(gdb)
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
(gdb)
0x0106bbb0 162 in hurdsig.c
1: x/i $pc
=> 0x106bbb0 <_hurd_sigstate_lock+32>: mov (%eax),%eax
(gdb)
163 in hurdsig.c
1: x/i $pc
=> 0x106bbb2 <_hurd_sigstate_lock+34>: test %eax,%eax
(gdb)
0x0106bbb4 163 in hurdsig.c
1: x/i $pc
=> 0x106bbb4 <_hurd_sigstate_lock+36>: je 0x106bbbc <_hurd_sigstate_lock+44>
(gdb)
0x0106bbb6 163 in hurdsig.c
1: x/i $pc
=> 0x106bbb6 <_hurd_sigstate_lock+38>: cmpl $0x1,0x18(%esi)
(gdb)
0x0106bbba 163 in hurdsig.c
1: x/i $pc
=> 0x106bbba <_hurd_sigstate_lock+42>: je 0x106bbe0 <_hurd_sigstate_lock+80>
(gdb)
_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
(gdb)
__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
(gdb)
0x0106bbe8 59 in ../sysdeps/mach/i386/machine-lock.h
1: x/i $pc
=> 0x106bbe8 <_hurd_sigstate_lock+88>: xchg %edx,0x4(%eax)
(gdb)
<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
"si"
<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
probably?
<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
segfailts
<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
single-stepping?
<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
segfaults
<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: http://paste.debian.net/61170/
<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):
http://paste.debian.net/61178/
<gnu_srs> Ah, have to do it again as root;-)
<braunr> yes .. :p
<gnu_srs> new last part: http://paste.debian.net/61181/
<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
|