Segfault после возобновления условной точки останова - PullRequest
0 голосов
/ 06 марта 2020

Я получил следующую обратную трассировку, возвращенную Perf:

evince 13293  3713.930210:        100 mem_load_uops_retired.l3_miss:uppp:     7ffff5733440         5080022 N/A|SNP N/A|TLB N/A|LCK N/A
    7ffff54b0226 g_private_get_impl+0x6 (inlined)
    7ffff54b0226 g_private_get+0x6 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff5487f23 thread_memory_from_self+0x93 (inlined)
    7ffff5487f23 g_slice_free1+0x93 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff5466c72 g_source_callback_unref+0x22 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff54676eb g_source_destroy_internal+0x6b (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff546a30f g_main_dispatch+0x1df (inlined)
    7ffff546a30f g_main_context_dispatch+0x1df (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff546a64f g_main_context_iterate+0x1ff (inlined)
    7ffff546a6db g_main_context_iteration+0x2b (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4)
    7ffff5a2be3c g_application_run+0x1fc (/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5600.4)
    555555573707 main+0x447 (/opt/evince-3.28.4/bin/evince)
    7ffff4a91b96 __libc_start_main+0xe6 (/lib/x86_64-linux-gnu/libc-2.27.so)
    555555573899 _start+0x29 (/opt/evince-3.28.4/bin/evince)

Я хотел воспроизвести состояние в какой-то момент в этой обратной трассировке. Точно, мне пришлось прервать исполнение, когда g_source_callback_unref() вызвал g_slice_free1(). Вот разборка точки вызова (посмотрите на смещение 33):

Dump of assembler code for function g_source_callback_unref:
   0x0000000000048c50 <+0>: lock subl $0x1,(%rdi)
   0x0000000000048c54 <+4>: je     0x48c60 <g_source_callback_unref+16>
   0x0000000000048c56 <+6>: repz retq 
   0x0000000000048c58 <+8>: nopl   0x0(%rax,%rax,1)
   0x0000000000048c60 <+16>: push   %rbx
   0x0000000000048c61 <+17>: mov    0x18(%rdi),%rax
   0x0000000000048c65 <+21>: mov    %rdi,%rbx
   0x0000000000048c68 <+24>: test   %rax,%rax
   0x0000000000048c6b <+27>: je     0x48c73 <g_source_callback_unref+35>
   0x0000000000048c6d <+29>: mov    0x10(%rdi),%rdi
   0x0000000000048c71 <+33>: callq  *%rax
   0x0000000000048c73 <+35>: mov    %rbx,%rdi
   0x0000000000048c76 <+38>: pop    %rbx
   0x0000000000048c77 <+39>: jmpq   0x51ba0 <g_free>
End of assembler dump.

Для этого требуется условная точка останова. Итак, я определил следующее (0x7ffff5487e90 - это адрес g_slice_free1()):

b *0x7ffff5466c71 if ($rax = 0x7ffff5487e90)

Затем я продолжил выполнение и вызвал точку останова. В этот момент состояние потоков было следующим :

(gdb) info threads
  Id   Target Id         Frame 
  1    Thread 0x7ffff7fac480 (LWP 6069) "evince" 0x00007ffff4b84bf9 in __GI___poll (fds=0x55555586f0d0, nfds=1, timeout=25000) at ../sysdeps/unix/sysv/linux/poll.c:29
  2    Thread 0x7fffecae7700 (LWP 6070) "gmain" 0x00007ffff4b84bf9 in __GI___poll (fds=0x55555585c000, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
* 3    Thread 0x7fffe7fff700 (LWP 6071) "gdbus" 0x00007ffff5466c71 in g_source_callback_unref (cb_data=0x555555862f30) at ../../../../glib/gmain.c:1546

Затем я продолжил выполнение, которое привело к ошибке сегментации:

Thread 3 "gdbus" received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x1) at malloc.c:3103
3103    malloc.c: No such file or directory.

В чем причина этой ошибки? Должен ли я изменить подход к установке точки останова?

...