Используйте dtrace, lldb или gdb, чтобы найти, какой файл или строка кода отвечает за строку вывода в stdout или stderr?

Я вижу, что строка выводится на мой терминал, когда я запускаю исполняемый файл. У меня есть исходный код (на C) исполняемого файла, но он написан не мной. Я скомпилировал его с флагом -g. Есть ли способ узнать, какая строка в каком файле привела к выводу, с помощью dtrace, lldb, gdb или любых других средств?

Я использую macOS 10.13. Когда я запустил gdb и следующее: catch syscall write

Я получил эту ошибку: функция «перехват системного вызова» еще не поддерживается в этой архитектуре.

Есть ли способ достичь моей цели?


person forgodsakehold    schedule 09.08.2020    source источник


Ответы (1)


lldb, как правило, лучше поддерживается в macOS, чем gdb. Вы должны иметь возможность отслеживать этот вызов, используя его условную точку останова особенность.

Хотя вы, безусловно, можете отследить вызов write() с помощью dtrace и получить трассировку стека с помощью действия ustack(), я думаю, вам будет труднее определить состояние программы, чем если бы вы сломали ее в отладчике.

Ваш комментарий предполагает, что вы, возможно, ищете совпадение подстроки. Я подозреваю, что вы можете создать условную точку останова в lldb, которая соответствует подстроке, используя что-то вроде этого:

br s -n write -c 'strnstr((const char*)$rsi, "test", $rdx) != NULL'

Я предполагаю, что lldb не имеет имен аргументов для функции write, поэтому я напрямую использую имена регистров вызовов x86-64. ($rdi = первый аргумент, который будет дескриптором файла; $rsi = второй аргумент, буфер; $rdx = третий аргумент, длина буфера)

person pmdj    schedule 09.08.2020
comment
Спасибо за ваш ответ @pmdj. Но можете ли вы дать более подробную информацию о том, как использовать условную точку останова для отслеживания записи системного вызова? Ссылка на другой вопрос о переполнении стека говорит только об использовании равенства строк в качестве условия... - person forgodsakehold; 10.08.2020
comment
@forgodsakehold В вашем вопросе не указано, что вы ищете - я вижу выводимую строку, которая мне подсказала, что это фиксированная строка. - person pmdj; 10.08.2020
comment
Я обновил ответ, чтобы показать пример того, как я бы реализовал условную точку останова в write(), где написанная строка содержит тест подстроки - возможно, это то, что вам нужно. - person pmdj; 10.08.2020
comment
Обратите внимание, что lldb поддерживает $arg<N> в качестве псевдонимов для регистров передачи аргументов GPR в текущем ABI. Таким образом, вы можете сделать это с помощью $rdi -> $arg1 и т. д. - person Jim Ingham; 10.08.2020
comment
@JimIngham Я этого не знал, это очень удобный совет, спасибо! - person pmdj; 11.08.2020