Можно ли в gdb определить, выполняется ли поток (или заблокирован) в ядре или пространстве пользователя? - PullRequest
0 голосов
/ 16 мая 2018

Рассмотрим следующую программу.

#include <unistd.h>

int main(){
    sleep(1000);
}

Если мы запустим strace в этой программе, последняя строка, которая появляется перед длительным сном, выглядит следующим образом.

nanosleep({1000, 0}, 

Покапрограмма спит, код выполняется (вероятно, заблокирован) внутри ядра ОС.

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

Есть ли в gdb некоторое выражение, которое оценивается как true, если поток должен пересечь границу syscallперед повторным выполнением кода в пользовательском пространстве?

В идеале было бы кросс-платформенное решение, но также полезны решения для конкретных платформ.

Разъяснение :Мне все равно, действительно ли поток выполняет ;только то, было ли его последнее значение счетчика программы в коде ядра или в коде пользователя.

Другими словами, может gdb сообщить нам, вошел ли конкретный поток в ядро, но еще не вышел из ядра?

1 Ответ

0 голосов
/ 17 мая 2018

Есть ли какое-то выражение в gdb, которое оценивается как true, если поток должен пересечь границу системного вызова перед выполнением кода в пользовательское пространство снова?

Вы можете попробовать использовать catch syscall nanosleep, см. документацию .

catch syscall nanosleep останавливается на 2 событиях: одно при вызове системного вызова и второе при системном вызове. Вы можете использовать info breakpoints, чтобы увидеть количество попаданий этой точки перехвата. Если это даже, то вы должны быть в пространстве пользователя. Если это странно, то вы должны быть в пространстве ядра:

$ gdb -q a.out 
Reading symbols from a.out...done.
(gdb) catch syscall nanosleep 
Catchpoint 1 (syscall 'nanosleep' [35])
(gdb) i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "nanosleep" 
(gdb) r
Starting program: /home/ks1322/a.out 
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.27-8.fc28.x86_64

Catchpoint 1 (call to syscall nanosleep), 0x00007ffff7adeb54 in nanosleep () from /lib64/libc.so.6
(gdb) i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "nanosleep" 
    catchpoint already hit 1 time
(gdb) c
Continuing.

Catchpoint 1 (returned from syscall nanosleep), 0x00007ffff7adeb54 in nanosleep () from /lib64/libc.so.6
(gdb) i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "nanosleep" 
    catchpoint already hit 2 times
(gdb) c
Continuing.
[Inferior 1 (process 19515) exited normally]
...