Как я могу поставить точку останова на «что-то печатается на терминал» в GDB? - PullRequest
24 голосов
/ 08 октября 2009

Я хотел бы знать, откуда внутри огромного приложения печатается определенное сообщение. Приложение настолько большое и старое, что использует все мыслимые способы печати текста на терминале; например, printf (), fprintf (stdout, ...) и т. д.

Я пишу, чтобы поставить точку останова на системный вызов write (), но затем меня переполняет слишком много остановок точек останова из-за различных операций ввода-вывода файлов, которые также используют write ().

Поэтому я хочу, чтобы gdb останавливался всякий раз, когда программа печатает что-то на терминале, но в то же время я не хочу, чтобы gdb останавливался, когда программа записывает что-то в файл.

Ответы [ 2 ]

26 голосов
/ 08 октября 2009

Используйте условную точку останова, которая проверяет первый параметр. В 64-битных системах x86 условие будет:

(gdb) b напишите, если 1 == $ rdi

В 32-битных системах это более сложно, поскольку параметр находится в стеке, а это означает, что вам нужно привести $ esp к int * и проиндексировать параметр fd. Стек в этой точке имеет адрес возврата, длину, буфер и, наконец, fd.

Это сильно зависит от аппаратных платформ.

12 голосов
/ 06 января 2010

С помощью gdb 7.0 вы можете установить условную точку останова на syscall write ():

(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [4])
(gdb) condition 1 $ebx==1

$ ebx содержит первый параметр системного вызова - здесь номер FD

...