每个进程所有pthread_internal_t结构是用g_thread_list链起来的。因此可以通过这个静态变量来查找想要的pthread_internal_t,如:
(gdb) p g_thread_list $87 = (pthread_internal_t *) 0x7f6a51a450 (gdb) p *g_thread_list $88 = { next = 0x7f69bc6450, prev = 0x0, tid = 31561, cached_pid_ = 1448, attr = { flags = 1, stack_base = 0x7f6a41e000, stack_size = 1033296, guard_size = 4096, sched_policy = 0, sched_priority = 0, __reserved = " REf177 00 00 00 20 20253k177 00 00" }, join_state = THREAD_DETACHED, cleanup_stack = 0x0, start_routine = 0x7f97147cd0 <thread_data_t::trampoline(thread_data_t const*)>, start_routine_arg = 0x7f66455260, return_value = 0x0, alternate_signal_stack = 0x0, startup_handshake_lock = { state = Lock::Unlocked, process_shared = false }, mmap_size = 1036288, thread_local_dtors = 0x0, tls = {0x7f6a51a4e8, 0x7f6a51a450, 0x0, 0x0, 0x0, 0x2212c0df7ebda00b, 0x0, 0x0, 0x0}, key_data = {{ seq = 0, data = 0x0 } <repeats 141 times>}, dlerror_buffer = ' 00' <repeats 511 times> }
(gdb) p *(pthread_internal_t *)0x7f69bc6450 $91 = { next = 0x7f6b695450, prev = 0x7f6a51a450, tid = 30974, cached_pid_ = 1448, attr = { flags = 1, stack_base = 0x7f69aca000, stack_size = 1033296, guard_size = 4096, sched_policy = 0, sched_priority = 0, __reserved = "v240275~337300 22"310362O222177 00 00" }, join_state = THREAD_DETACHED, cleanup_stack = 0x0, start_routine = 0x7f943ca7b4 <__timer_thread_start(void*)>, start_routine_arg = 0x7f75b694f0, return_value = 0x0, alternate_signal_stack = 0x7f6e6c1000, startup_handshake_lock = { state = Lock::LockedWithoutWaiter, process_shared = false }, mmap_size = 1036288, thread_local_dtors = 0x0, tls = {0x7f69bc64e8, 0x7f69bc6450, 0x0, 0x0, 0x0, 0x2212c0df7ebda00b, 0x0, 0x0, 0x0}, key_data = {{ seq = 0, data = 0x0 } <repeats 141 times>}, dlerror_buffer = ' 00' <repeats 511 times> }
pthread_internal_t中有很多有用的数据可供我们分析和调试问题。
如果需要通过tid或者栈指针获取对应的pthread_internal_t,可以用以下脚本实现:
define print_thread_by_tid set $tid = $arg0 set $pThread = g_thread_list while $pThread != 0 if $pThread->tid == $tid p $pThread p *$pThread loop_break end set $pThread = $pThread->next end end define print_thread_by_sp set $cursp = $arg0 set $pThread = g_thread_list while $pThread != 0 if $pThread->attr.stack_base <= $cursp && $pThread->attr.stack_base + $pThread->attr.stack_size >= $cursp p $pThread p *$pThread loop_break end set $pThread = $pThread->next end end
如果要找当前线程的pthread_internal_t,则可以利用当前的sp,如:
define print_current_thread print_thread_by_sp $sp end
运行结果:
(gdb) print_current_thread $92 = (pthread_internal_t *) 0x7f6b466450 $93 = { next = 0x7f6987a450, prev = 0x7f6ad59450, tid = 2047, cached_pid_ = 1448, attr = { flags = 1, stack_base = 0x7f6b36a000, stack_size = 1033296, guard_size = 4096, sched_policy = 0, sched_priority = 0, __reserved = "200 25324u177 00 00 00@373212311177 00 00" }, join_state = THREAD_DETACHED, cleanup_stack = 0x0, start_routine = 0x7f97147cd0 <thread_data_t::trampoline(thread_data_t const*)>, start_routine_arg = 0x7f75d415a0, return_value = 0x0, alternate_signal_stack = 0x7f721be000, startup_handshake_lock = { state = Lock::LockedWithoutWaiter, process_shared = false }, mmap_size = 1036288, thread_local_dtors = 0x0, tls = {0x7f6b4664e8, 0x7f6b466450, 0x0, 0x7f954ad7f0 <android::gHooks+9224>, 0x0, 0x2212c0df7ebda00b, 0x0, 0x7f76239200, 0x0}, key_data = {{ seq = 1, data = 0x7f75d40080 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 1, data = 0x7f86abe180 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 0, data = 0x0 }, { seq = 1, data = 0x7f76018010 }, { seq = 1, data = 0x7f75d42fa0 }, { seq = 1, data = 0x7f75d9dc00 }, { seq = 0, data = 0x0 }, { seq = 1, data = 0x7f67be29a0 }, { seq = 1, data = 0x7f67917c50 }, { seq = 0, data = 0x0 } <repeats 119 times>}, dlerror_buffer = ' 00' <repeats 511 times> }