Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PLT hook segfault about GCC 7 #91

Closed
Taeung opened this issue Apr 23, 2017 · 14 comments
Closed

PLT hook segfault about GCC 7 #91

Taeung opened this issue Apr 23, 2017 · 14 comments
Labels

Comments

@Taeung
Copy link
Collaborator

Taeung commented Apr 23, 2017

There is no this problem of uftrace built by gcc 5.4.1.
But when building uftrace by gcc 7.0.1, I found the segmentation fault about PLT hook like below.

# normal tracing

$ uftrace tests/t-abc
WARN: invalid task file
child terminated by signal: 11: Segmentation fault
# DURATION    TID     FUNCTION

But if using --no-libcall, the segmentation fault didn't appear.

$ uftrace --no-libcall t-abc
# DURATION    TID     FUNCTION
            [ 5133] | main() {
            [ 5133] |   a() {
            [ 5133] |     b() {
   0.982 us [ 5133] |       c();
   1.854 us [ 5133] |     } /* b */
   2.170 us [ 5133] |   } /* a */
   2.792 us [ 5133] | } /* main */

If checking core file, you can see libmcount/plthook.c:429

Reading symbols from t-abc...(no debugging symbols found)...done.
[New LWP 5249]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `t-abc'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007ff5a1b8a322 in plthook_entry (ret_addr=0x7ffd79fb0378, child_idx=1, 
    module_id=140692961395048, regs=0x7ffd79fb0338)
    at /home/taeung/git/uftrace/libmcount/plthook.c:429
429		struct ftrace_trigger tr = {
@namhyung
Copy link
Owner

namhyung commented Apr 24, 2017

Is the test program (t-abc) is a same binary for both case (or is it also rebuilt with GCC7)? I need to check GCC changes about PLT handling..

@namhyung
Copy link
Owner

If the binaries are different (IOW rebuit), could you please chek there's any difference in the disassembly output?

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

@namhyung I think there aren't big difference about PLT handling..

But if checking disassembly code of test program (t-abc) built by gcc 5,

Disassembly of section .plt:

0000000000400510 <getpid@plt-0x10>:
  400510:	ff 35 f2 0a 20 00    	pushq  0x200af2(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  400516:	ff 25 f4 0a 20 00    	jmpq   *0x200af4(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  40051c:	0f 1f 40 00          	nopl   0x0(%rax)

0000000000400520 <getpid@plt>:
  400520:	ff 25 f2 0a 20 00    	jmpq   *0x200af2(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  400526:	68 00 00 00 00       	pushq  $0x0
  40052b:	e9 e0 ff ff ff       	jmpq   400510 <_init+0x20>

0000000000400530 <__libc_start_main@plt>:
  400530:	ff 25 ea 0a 20 00    	jmpq   *0x200aea(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  400536:	68 01 00 00 00       	pushq  $0x1
  40053b:	e9 d0 ff ff ff       	jmpq   400510 <_init+0x20>

0000000000400540 <__monstartup@plt>:
  400540:	ff 25 e2 0a 20 00    	jmpq   *0x200ae2(%rip)        # 601028 <_GLOBAL_OFFSET_TABLE_+0x28>
  400546:	68 02 00 00 00       	pushq  $0x2
  40054b:	e9 c0 ff ff ff       	jmpq   400510 <_init+0x20>

0000000000400550 <mcount@plt>:
  400550:	ff 25 da 0a 20 00    	jmpq   *0x200ada(%rip)        # 601030 <_GLOBAL_OFFSET_TABLE_+0x30>
  400556:	68 03 00 00 00       	pushq  $0x3
  40055b:	e9 b0 ff ff ff       	jmpq   400510 <_init+0x20>

0000000000400560 <__cxa_atexit@plt>:
  400560:	ff 25 d2 0a 20 00    	jmpq   *0x200ad2(%rip)        # 601038 <_GLOBAL_OFFSET_TABLE_+0x38>
  400566:	68 04 00 00 00       	pushq  $0x4
  40056b:	e9 a0 ff ff ff       	jmpq   400510 <_init+0x20>

0000000000400570 <atoi@plt>:
  400570:	ff 25 ca 0a 20 00    	jmpq   *0x200aca(%rip)        # 601040 <_GLOBAL_OFFSET_TABLE_+0x40>
  400576:	68 05 00 00 00       	pushq  $0x5
  40057b:	e9 90 ff ff ff       	jmpq   400510 <_init+0x20>

...

00000000004006c6 <a>:
  4006c6:	55                   	push   %rbp
  4006c7:	48 89 e5             	mov    %rsp,%rbp
  4006ca:	e8 81 fe ff ff       	callq  400550 <mcount@plt>
  4006cf:	e8 05 00 00 00       	callq  4006d9 <b>
  4006d4:	83 e8 01             	sub    $0x1,%eax
  4006d7:	5d                   	pop    %rbp
  4006d8:	c3                   	retq   

00000000004006d9 <b>:
  4006d9:	55                   	push   %rbp
  4006da:	48 89 e5             	mov    %rsp,%rbp
  4006dd:	e8 6e fe ff ff       	callq  400550 <mcount@plt>
  4006e2:	e8 05 00 00 00       	callq  4006ec <c>
  4006e7:	83 c0 01             	add    $0x1,%eax
  4006ea:	5d                   	pop    %rbp
  4006eb:	c3                   	retq   

00000000004006ec <c>:
  4006ec:	55                   	push   %rbp
  4006ed:	48 89 e5             	mov    %rsp,%rbp
  4006f0:	e8 5b fe ff ff       	callq  400550 <mcount@plt>
  4006f5:	e8 26 fe ff ff       	callq  400520 <getpid@plt>
  4006fa:	89 c1                	mov    %eax,%ecx
  4006fc:	ba 89 b5 f8 14       	mov    $0x14f8b589,%edx
  400701:	89 c8                	mov    %ecx,%eax
  400703:	f7 ea                	imul   %edx
  400705:	c1 fa 0d             	sar    $0xd,%edx
  400708:	89 c8                	mov    %ecx,%eax
  40070a:	c1 f8 1f             	sar    $0x1f,%eax
  40070d:	29 c2                	sub    %eax,%edx
  40070f:	89 d0                	mov    %edx,%eax
  400711:	69 c0 a0 86 01 00    	imul   $0x186a0,%eax,%eax
  400717:	29 c1                	sub    %eax,%ecx
  400719:	89 c8                	mov    %ecx,%eax
  40071b:	5d                   	pop    %rbp
  40071c:	c3                   	retq   

000000000040071d <main>:
  40071d:	55                   	push   %rbp
  40071e:	48 89 e5             	mov    %rsp,%rbp
  400721:	48 83 ec 20          	sub    $0x20,%rsp
  400725:	e8 26 fe ff ff       	callq  400550 <mcount@plt>
  40072a:	89 7d ec             	mov    %edi,-0x14(%rbp)
  40072d:	48 89 75 e0          	mov    %rsi,-0x20(%rbp)
  400731:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
  400738:	83 7d ec 01          	cmpl   $0x1,-0x14(%rbp)
  40073c:	7e 16                	jle    400754 <main+0x37>
  40073e:	48 8b 45 e0          	mov    -0x20(%rbp),%rax
  400742:	48 83 c0 08          	add    $0x8,%rax
  400746:	48 8b 00             	mov    (%rax),%rax
  400749:	48 89 c7             	mov    %rax,%rdi
  40074c:	e8 1f fe ff ff       	callq  400570 <atoi@plt>
  400751:	89 45 fc             	mov    %eax,-0x4(%rbp)
  400754:	e8 6d ff ff ff       	callq  4006c6 <a>
  400759:	01 45 fc             	add    %eax,-0x4(%rbp)
  40075c:	83 7d fc 00          	cmpl   $0x0,-0x4(%rbp)
  400760:	0f 94 c0             	sete   %al
  400763:	0f b6 c0             	movzbl %al,%eax
  400766:	c9                   	leaveq 
  400767:	c3                   	retq   
  400768:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
  40076f:	00 

If checking the case of gcc 7,

Disassembly of section .plt:

00000000004004d0 <getpid@plt-0x10>:
  4004d0:	ff 35 d2 06 20 00    	pushq  0x2006d2(%rip)        # 600ba8 <_GLOBAL_OFFSET_TABLE_+0x8>
  4004d6:	ff 25 d4 06 20 00    	jmpq   *0x2006d4(%rip)        # 600bb0 <_GLOBAL_OFFSET_TABLE_+0x10>
  4004dc:	0f 1f 40 00          	nopl   0x0(%rax)

00000000004004e0 <getpid@plt>:
  4004e0:	ff 25 d2 06 20 00    	jmpq   *0x2006d2(%rip)        # 600bb8 <_GLOBAL_OFFSET_TABLE_+0x18>
  4004e6:	68 00 00 00 00       	pushq  $0x0
  4004eb:	e9 e0 ff ff ff       	jmpq   4004d0 <_init+0x28>

00000000004004f0 <__libc_start_main@plt>:
  4004f0:	ff 25 ca 06 20 00    	jmpq   *0x2006ca(%rip)        # 600bc0 <_GLOBAL_OFFSET_TABLE_+0x20>
  4004f6:	68 01 00 00 00       	pushq  $0x1
  4004fb:	e9 d0 ff ff ff       	jmpq   4004d0 <_init+0x28>

0000000000400500 <__monstartup@plt>:
  400500:	ff 25 c2 06 20 00    	jmpq   *0x2006c2(%rip)        # 600bc8 <_GLOBAL_OFFSET_TABLE_+0x28>
  400506:	68 02 00 00 00       	pushq  $0x2
  40050b:	e9 c0 ff ff ff       	jmpq   4004d0 <_init+0x28>

0000000000400510 <mcount@plt>:
  400510:	ff 25 ba 06 20 00    	jmpq   *0x2006ba(%rip)        # 600bd0 <_GLOBAL_OFFSET_TABLE_+0x30>
  400516:	68 03 00 00 00       	pushq  $0x3
  40051b:	e9 b0 ff ff ff       	jmpq   4004d0 <_init+0x28>

0000000000400520 <__cxa_atexit@plt>:
  400520:	ff 25 b2 06 20 00    	jmpq   *0x2006b2(%rip)        # 600bd8 <_GLOBAL_OFFSET_TABLE_+0x38>
  400526:	68 04 00 00 00       	pushq  $0x4
  40052b:	e9 a0 ff ff ff       	jmpq   4004d0 <_init+0x28>

0000000000400530 <atoi@plt>:
  400530:	ff 25 aa 06 20 00    	jmpq   *0x2006aa(%rip)        # 600be0 <_GLOBAL_OFFSET_TABLE_+0x40>
  400536:	68 05 00 00 00       	pushq  $0x5
  40053b:	e9 90 ff ff ff       	jmpq   4004d0 <_init+0x28>

...

0000000000400667 <a>:
  400667:	55                   	push   %rbp
  400668:	48 89 e5             	mov    %rsp,%rbp
  40066b:	e8 a0 fe ff ff       	callq  400510 <mcount@plt>
  400670:	e8 05 00 00 00       	callq  40067a <b>
  400675:	83 e8 01             	sub    $0x1,%eax
  400678:	5d                   	pop    %rbp
  400679:	c3                   	retq   

000000000040067a <b>:
  40067a:	55                   	push   %rbp
  40067b:	48 89 e5             	mov    %rsp,%rbp
  40067e:	e8 8d fe ff ff       	callq  400510 <mcount@plt>
  400683:	e8 05 00 00 00       	callq  40068d <c>
  400688:	83 c0 01             	add    $0x1,%eax
  40068b:	5d                   	pop    %rbp
  40068c:	c3                   	retq   

000000000040068d <c>:
  40068d:	55                   	push   %rbp
  40068e:	48 89 e5             	mov    %rsp,%rbp
  400691:	e8 7a fe ff ff       	callq  400510 <mcount@plt>
  400696:	e8 45 fe ff ff       	callq  4004e0 <getpid@plt>
  40069b:	89 c1                	mov    %eax,%ecx
  40069d:	ba 89 b5 f8 14       	mov    $0x14f8b589,%edx
  4006a2:	89 c8                	mov    %ecx,%eax
  4006a4:	f7 ea                	imul   %edx
  4006a6:	c1 fa 0d             	sar    $0xd,%edx
  4006a9:	89 c8                	mov    %ecx,%eax
  4006ab:	c1 f8 1f             	sar    $0x1f,%eax
  4006ae:	29 c2                	sub    %eax,%edx
  4006b0:	89 d0                	mov    %edx,%eax
  4006b2:	69 c0 a0 86 01 00    	imul   $0x186a0,%eax,%eax
  4006b8:	29 c1                	sub    %eax,%ecx
  4006ba:	89 c8                	mov    %ecx,%eax
  4006bc:	5d                   	pop    %rbp
  4006bd:	c3                   	retq   

00000000004006be <main>:
  4006be:	55                   	push   %rbp
  4006bf:	48 89 e5             	mov    %rsp,%rbp
  4006c2:	48 83 ec 20          	sub    $0x20,%rsp
  4006c6:	e8 45 fe ff ff       	callq  400510 <mcount@plt>
  4006cb:	89 7d ec             	mov    %edi,-0x14(%rbp)
  4006ce:	48 89 75 e0          	mov    %rsi,-0x20(%rbp)
  4006d2:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
  4006d9:	83 7d ec 01          	cmpl   $0x1,-0x14(%rbp)
  4006dd:	7e 16                	jle    4006f5 <main+0x37>
  4006df:	48 8b 45 e0          	mov    -0x20(%rbp),%rax
  4006e3:	48 83 c0 08          	add    $0x8,%rax
  4006e7:	48 8b 00             	mov    (%rax),%rax
  4006ea:	48 89 c7             	mov    %rax,%rdi
  4006ed:	e8 3e fe ff ff       	callq  400530 <atoi@plt>
  4006f2:	89 45 fc             	mov    %eax,-0x4(%rbp)
  4006f5:	e8 6d ff ff ff       	callq  400667 <a>
  4006fa:	01 45 fc             	add    %eax,-0x4(%rbp)
  4006fd:	83 7d fc 00          	cmpl   $0x0,-0x4(%rbp)
  400701:	0f 94 c0             	sete   %al
  400704:	0f b6 c0             	movzbl %al,%eax
  400707:	c9                   	leaveq 
  400708:	c3                   	retq   
  400709:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

@namhyung And let me show all cases about gcc 5 and gcc 7.

Case A) with uftrace built by gcc 5

  • A-1) test program(t-abc) built by gcc 5
$ gcc -dumpversion
5.4.0

$ ./runtest.py basic
Test case                 pg             finstrument-fu
------------------------: O0 O1 O2 O3 Os O0 O1 O2 O3 Os
001 basic               : OK OK OK OK OK OK OK OK OK OK
...
  • A-2) test program(t-abc) built by gcc 7
$ gcc -dumpversion
7.0.1

$ ./runtest.py basic
Test case                 pg             finstrument-fu
------------------------: O0 O1 O2 O3 Os O0 O1 O2 O3 Os
001 basic               : OK OK OK OK OK OK OK OK OK OK
...

Case B) with uftrace built by gcc 7

  • B-1) test program(t-abc) built by gcc 5
$ gcc -dumpversion
5.4.0

$ ./runtest.py basic
Test case                 pg             finstrument-fu
------------------------: O0 O1 O2 O3 Os O0 O1 O2 O3 Os
001 basic               : SG SG SG SG SG SG SG SG SG SG
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
...
  • B-2) test program(t-abc) built by gcc 7
$ gcc -dumpversion
7.0.1

$ ./runtest.py basic
Test case                 pg             finstrument-fu
------------------------: O0 O1 O2 O3 Os O0 O1 O2 O3 Os
001 basic               : SG SG SG SG SG SG SG SG SG SG
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
child terminated by signal: 11: Segmentation fault
...

@namhyung
Copy link
Owner

OK. Many thanks. Could you provide a link for libmcount-fast.so built with GCC7 so that I can take a look at the binary?

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

@namhyung Okey, you want to download libmcount-fast.so built by gcc 7. Right ?

@namhyung
Copy link
Owner

Yes, appreciated!

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

Hum.. My build way is wrong ?..

$ readelf -p .comment /usr/local/lib/libmcount-fast.so

String dump of section '.comment':
  [     0]  GCC: (GNU) 7.0.1 20170405 (experimental)
  [    29]  GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

@namhyung
Copy link
Owner

Not sure.. maybe it contains some object files built with GCC5. But I can reproduce the segfault so it's ok for me.

@namhyung
Copy link
Owner

And the problem might be due to stack alignment required by "movaps" instruction. Could you please test below patch?

diff --git a/arch/x86_64/plthook.S b/arch/x86_64/plthook.S
index baa6b52..fe0ff44 100644
--- a/arch/x86_64/plthook.S
+++ b/arch/x86_64/plthook.S
@@ -3,8 +3,10 @@ plt_hooker:
        .cfi_startproc
        /* PLT code already pushed symbol and module indices */
        .cfi_adjust_cfa_offset 16
-       sub $48, %rsp
-       .cfi_adjust_cfa_offset 48
+       sub $56, %rsp
+       .cfi_adjust_cfa_offset 56
+       movq %rax, 48(%rsp)
+       .cfi_offset rdi, -32
        movq %rdi, 40(%rsp)
        .cfi_offset rdi, -32
        movq %rsi, 32(%rsp)
@@ -19,11 +21,11 @@ plt_hooker:
        .cfi_offset r9, -72
 
        /* child idx */
-       movq 56(%rsp), %rsi
+       movq 64(%rsp), %rsi
        /* address of parent ip */
-       lea 64(%rsp), %rdi
+       lea 72(%rsp), %rdi
        /* module id */
-       movq 48(%rsp), %rdx
+       movq 56(%rsp), %rdx
        /* mcount_args */
        movq %rsp, %rcx
 
@@ -35,8 +37,9 @@ plt_hooker:
        movq 24(%rsp), %rdx
        movq 32(%rsp), %rsi
        movq 40(%rsp), %rdi
-       add $48, %rsp
-       .cfi_adjust_cfa_offset -48
+       /* ignore rax */
+       add $56, %rsp
+       .cfi_adjust_cfa_offset -56
 
        cmpq $0, %rax
        cmovz plthook_resolver_addr(%rip), %rax

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

Sure, after I tested this, will tell you the result ! 😄

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

@namhyung The segfault is gone ! with your patch.

But I don't understand exactly what +8 and alignment for movaps instruction means..
I think I seem to need the domain knowledge and Google.. 😄

@namhyung
Copy link
Owner

FYI

http://x86.renejeschke.de/html/file_module_x86_id_180.html

(gdb) disas
Dump of assembler code for function plthook_entry:
   0x00007f09d8db5300 <+0>:	push   %r15
   0x00007f09d8db5302 <+2>:	push   %r14
   0x00007f09d8db5304 <+4>:	push   %r13
   0x00007f09d8db5306 <+6>:	push   %r12
   0x00007f09d8db5308 <+8>:	push   %rbp
   0x00007f09d8db5309 <+9>:	push   %rbx
   0x00007f09d8db530a <+10>:	pxor   %xmm0,%xmm0
   0x00007f09d8db530e <+14>:	sub    $0x58,%rsp
   0x00007f09d8db5312 <+18>:	lea    0x2169c8(%rip),%rax        # 0x7f09d8fcbce1 <mcount_setup_done>
   0x00007f09d8db5319 <+25>:	movq   $0x0,0x40(%rsp)
=> 0x00007f09d8db5322 <+34>:	movaps %xmm0,0x20(%rsp)

(gdb) p $rsp
$1 = (void *) 0x7fffa19971f8

@Taeung
Copy link
Collaborator Author

Taeung commented Apr 24, 2017

Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants