Как gdb выбирает «текущий поток»?

#multithreading #gdb

#многопоточность #gdb

Вопрос:

При gdb управлении программой он выберет поток как «текущий поток».

Например, используйте gdb для отладки файл дампа ядра, поврежденный поток будет «текущим потоком»:

 # gdb -q program core_program_0_0_1402630731_27929
 (gdb) bt
 #0  0xfefb2d50 in strlen () from /lib/libc.so.1
 #1  0xff01f4a0 in _ndoprnt () from /lib/libc.so.1
 #2  0xff021cac in vsprintf () from /lib/libc.so.1
 ......
 #9  0xff04aee8 in _lwp_start () from /lib/libc.so.1
  

Но если программа запущена, когда gdb она подключается, как она выбирает «текущий поток»? Я выполнил тест и обнаружил, что он использует основной поток в качестве «текущего потока».

gdb Всегда ли выбирается основной поток в качестве «текущего потока»? Я искал в руководстве gdb, но, к сожалению, ответа на этот вопрос нет.

Может ли кто-нибудь дать некоторые комментарии по этому вопросу?

Ответ №1:

gdb сохраняет информацию о текущем потоке в этой переменной:

 /* Collected pid, tid, etc. of the debugged inferior.  When there's
   no inferior, ptid_get_pid (inferior_ptid) will be 0.  */

extern ptid_t inferior_ptid;
  

Я думаю, что это может зависеть от платформы, как gdb выбирается текущий поток после присоединения к процессу. Возьмем, к примеру gdb , Linux. В Linux PID процесса равен PID его основного потока. So gdb использует PID процесса, к которому вы хотите подключиться, в качестве идентификатора текущего потока процесса:

Это код, из gdb которого задается текущий идентификатор потока:

 static void
linux_nat_attach (struct target_ops *ops, char *args, int from_tty)
{
  struct lwp_info *lp;
  int status;
  ptid_t ptid;
  volatile struct gdb_exception ex;

  /* Make sure we report all signals during attach.  */
  linux_nat_pass_signals (0, NULL);

  TRY_CATCH (ex, RETURN_MASK_ERROR)
    {
      linux_ops->to_attach (ops, args, from_tty);
    }

   /* some code is skipped */

  /* The ptrace base target adds the main thread with (pid,0,0)
     format.  Decorate it with lwp info.  */
  ptid = BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid));
  thread_change_ptid (inferior_ptid, ptid);
  

Таким образом, он использует pid процесс в качестве значения для LWP текущего потока. И это обратная трассировка, в которой задается текущий идентификатор потока:

 Hardware watchpoint 1: inferior_ptid

Old value = {pid = 11386, lwp = 0, tid = 0}
New value = {pid = 11386, lwp = 11386, tid = 0}
0x000000000057ba69 in infrun_thread_ptid_changed (old_ptid=..., new_ptid=...) at infrun.c:1592
1592        inferior_ptid = new_ptid;
(gdb) bt
#0  0x000000000057ba69 in infrun_thread_ptid_changed (old_ptid=..., new_ptid=...) at infrun.c:1592
#1  0x00000000005c87ca in observer_thread_ptid_changed_notification_stub (data=0x0, args_data=0x0) at observer.inc:728
#2  0x00000000005c8595 in generic_observer_notify (subject=<optimized out>, args=0x7fffffffdcc0) at observer.c:167
#3  0x00000000005c8c37 in observer_notify_thread_ptid_changed (old_ptid=..., new_ptid=...) at observer.inc:753
#4  0x000000000048b81b in linux_nat_attach (ops=0xb95220, args=0x7fffffffe3b3 "11386", from_tty=1) at linux-nat.c:1635
#5  0x00000000005b7879 in target_attach (args=0x7fffffffe3b3 "11386", from_tty=1) at target.c:3798
#6  0x000000000057a587 in attach_command (args=0x7fffffffe3b3 "11386", from_tty=1) at infcmd.c:2578
#7  0x00000000005919e7 in catch_command_errors (command=0x57a4f0 <attach_command>, arg=0x7fffffffe3b3 "11386", from_tty=1, mask=<optimized out>) at exceptions.c:573
#8  0x00000000005940d8 in captured_main (data=<optimized out>) at main.c:963
#9  0x0000000000591a94 in catch_errors (func=0x593330 <captured_main>, func_args=0x7fffffffdfd0, errstring=0x759429 "", mask=6) at exceptions.c:546
#10 0x0000000000593094 in gdb_main (args=<optimized out>) at main.c:1050
#11 0x0000000000457a76 in main (argc=<optimized out>, argv=0x0) at gdb.c:34
  

Ответ №2:

http://sunsite.ualberta.ca/Documentation/Gnu/gdb-5.0/html_node/gdb_24.html

Gdb имеет текущий поток, установленный на поток, который генерирует исключение, точку останова или был запланирован в данный момент.

Комментарии:

1. @user3737345: когда я открываю ссылку, отображается «Файл 404 не найден». Не могли бы вы открыть его?

2. На самом деле мне не удалось найти was currently scheduled на этой странице. Я даже не нашел scheduled на нем. Кроме того, я написал тест, в котором первый поток запускает другой поток, а затем первый поток переходит в спящий режим (поэтому он не запланирован). Однако, когда я подключаюсь с помощью gdb к процессу, текущий поток является первым потоком, который фактически спит.