catch
+strstr
状態
このメソッドの優れた点は、使用されている glibc に依存しないことwrite
です。実際のシステム コールをトレースします。
さらに、printf()
複数のprintf()
呼び出しで出力される文字列をキャッチすることさえできるため、バッファリングに対する回復力が高くなります。
x86_64 バージョン:
define stdout
catch syscall write
commands
printf "rsi = %s\n", $rsi
bt
end
condition $bpnum $rdi == 1 && strstr((char *)$rsi, "$arg0") != NULL
end
stdout qwer
テストプログラム:
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
write(STDOUT_FILENO, "asdf1", 5);
write(STDOUT_FILENO, "qwer1", 5);
write(STDOUT_FILENO, "zxcv1", 5);
write(STDOUT_FILENO, "qwer2", 5);
printf("as");
printf("df");
printf("qw");
printf("er");
printf("zx");
printf("cv");
fflush(stdout);
return EXIT_SUCCESS;
}
結果: 休憩:
qwer1
qwer2
fflush
. 前のprintf
ものは実際には何も出力しませんでした。バッファリングされていました! syacallwrite
は でのみ発生しましたfflush
。
ノート:
Ubuntu 17.10、gdb 8.0.1 でテスト済み。
トレース
インタラクティブに感じている場合の別のオプション:
setarch "$(uname -m)" -R strace -i ./stdout.out |& grep '\] write'
出力例:
[00007ffff7b00870] write(1, "a\nb\n", 4a
そのアドレスをコピーして、次の場所に貼り付けます。
setarch "$(uname -m)" -R strace -i ./stdout.out |& grep -E '\] write\(1, "a'
この方法の利点は、通常の UNIX ツールを使用してstrace
出力を操作できることと、深い GDB-fu を必要としないことです。
説明: