Я получил следующую обратную трассировку, возвращенную 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.
В чем причина этой ошибки? Должен ли я изменить подход к установке точки останова?