При использовании coredump в gdb как я могу точно узнать, какой поток вызвал SIGSEGV?

В моем приложении используется более 8 потоков. Когда я запускаю info threads в gdb, я вижу потоки и последнюю функцию, которую они выполняли. Мне не кажется очевидным, какой именно поток вызвал SIGSEGV. Можно ли это сказать? Это поток 1? Как пронумерованы темы?


person russoue    schedule 05.01.2015    source источник
comment
Я не думаю, что единственный ответ на этот вопрос - это ответ на мой вопрос. Он говорит о том, как видеть следы назад.   -  person russoue    schedule 05.01.2015
comment
Добро пожаловать в SO, @russoue! Дело в том, что этот вопрос является копией того. Вы разочарованы тем, что ответ неясен, и в этом есть смысл. Но способ смягчить это - добавить комментарии и / или вознаграждения к этому вопросу. К сожалению, я думаю, что окончательный ответ заключается в том, что вы не можете знать это точно и должны вывести это из трассировки.   -  person Brian Cain    schedule 05.01.2015


Ответы (1)


Когда вы используете gdb для анализа файла дампа ядра, gdb остановится на функции, которая вызывает дамп ядра программы. И текущая ветка будет убийством. В качестве примера возьмем следующую программу:

#include <stdio.h>
#include <pthread.h>
void *thread_func(void *p_arg)
{
        while (1)
        {
                printf("%s\n", (char*)p_arg);
                sleep(10);
        }
}
int main(void)
{
        pthread_t t1, t2;

        pthread_create(&t1, NULL, thread_func, "Thread 1");
        pthread_create(&t2, NULL, thread_func, NULL);

        sleep(1000);
        return;
}

Поток t2 приведет к остановке программы, поскольку он ссылается на указатель NULL. После остановки программы используйте gdb для анализа файла дампа памяти:

[root@localhost nan]# gdb -q a core.32794
Reading symbols from a...done.
[New LWP 32796]
[New LWP 32795]
[New LWP 32794]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./a'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
(gdb)

gdb останавливается на функции __strlen_sse2, это означает, что эта функция вызывает остановку программы. Затем используйте команду bt, чтобы увидеть, каким потоком она вызывается:

(gdb) bt
#0  0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
#1  0x00000034e4268cdb in puts () from /lib64/libc.so.6
#2  0x00000000004005cc in thread_func (p_arg=0x0) at a.c:7
#3  0x00000034e4a079d1 in start_thread () from /lib64/libpthread.so.0
#4  0x00000034e42e8b6d in clone () from /lib64/libc.so.6
(gdb) i threads
  Id   Target Id         Frame
  3    Thread 0x7ff6104c1700 (LWP 32794) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
  2    Thread 0x7ff6104bf700 (LWP 32795) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
* 1    Thread 0x7ff60fabe700 (LWP 32796) 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6

Команда bt показывает кадр стека текущего потока (который является убийцей). Команды «i threads» показывают все потоки, номер потока, который начинается с *, является текущим потоком.

Что касается «How are the threads numbered?», это зависит от ОС. дополнительную информацию можно найти в руководстве по gdb.

person Nan Xiao    schedule 06.01.2015