2009-10-08 4 views
18

나는 내부에서 거대한 응용 프로그램에 특정 메시지가 인쇄되어 있는지 알고 싶습니다. 응용 프로그램은 터미널에 텍스트를 인쇄 할 수있는 모든 방법을 사용하기에 너무 크고 오래되었습니다. (printf(), fprintf (stdout, ...) 등)gdb에서 "무언가가 터미널에 인쇄됩니다"에 중단 점을 넣을 수 있습니까?

write() 시스템 콜에 breakpoint를 씀으로써 쓰기를하지만 그 다음에는 너무 많은 breakpoint로 인해 여러 파일 I/O 작업은 write()도 사용합니다.

그래서 기본적으로 프로그램이 터미널에 뭔가를 인쇄 할 때마다 gdb를 멈추고 싶지만 동시에 프로그램에서 파일에 무언가를 쓸 때 gdb를 멈추게하고 싶지는 않습니다.

+1

표준 출력 버퍼 및 특정 문자열이 파이프에 보관 될 때 중단?] (http://stackoverflow.com/questions/8235436/how-can-i-monitor-whats-being-put-into-the-standard- out-buffer-and-break-when-a) –

+0

터미널에 나타나는 "무언가"에 대한 소스를'grep' 할 수 없습니까? – Calmarius

답변

18

첫 번째 매개 변수를 검사하는 조건부 중단 점을 사용하십시오. 64 비트 x86 시스템의 상태가 될 것이다 :

(GDB) B 기입 == $의 RDI 32 비트 시스템

한 경우, 상기 파라미터는 스택에 있기 때문에,이 의미 더 복잡 $ esp를 int *로 캐스팅하고 fd 매개 변수를 인덱싱해야합니다. 그 시점의 스택에는 리턴 주소, 길이, 버퍼 및 마지막으로 fd가 있습니다.

이것은 하드웨어 플랫폼에 따라 크게 다릅니다. GDB 7.0

+1

나는 이것으로 조금 뒤죽박죽이고 FD 번호가 "* (int) ($ esp + 4)"와 문자열 길이가 "(int) * (int) ($ esp + 12)"로 유용하다는 것을 발견했다. 마지막으로 문자열 데이터는 "* (int) ($ esp + 8)"입니다. 그래서 당신은 같은 것을 할 수 STDOUT을 위해 : 휴식 쓰기를하는 경우 1 == * (INT) ($ ESP + 4) 인쇄 (int)를 * (INT) ($ ESP + 12) X/s의 명령 end 그러나 _huge_ 응용 프로그램에서 이것을 실제로 사용하려고 시도했을 때 응용 프로그램이 dup2를 사용하는 경우 리디렉션 등을 처리하지 않기 때문에이 방법이 빠지지 않았 음이 밝혀졌습니다.() stdout에 당신은 stdout에 인쇄되는 것들을 놓칠 수도 있습니다. – martin

+0

좀 더 세련된 시도가 있습니다 :

 break write commands silent if !isatty(*(int)($esp + 4)) c end echo \ntty write(), size: x/d (int)($esp + 12) echo tty write(), data: x/s *(int)($esp + 8) end 
martin

11

, 당신은 콜 쓰기()에 조건부 중단 점을 설정할 수 있습니다

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

$의 EBX 먼저 콜 매개 변수를 포함 - 여기 FD 번호

또한보십시오 [I 모니터링 할 수있는 방법에 투입되고 있는지
+0

참고 :'printf'는 버퍼링되므로 두 번째'printf' 호출의 첫 번째'printf'에'write' 만 볼 수 있습니다. –

관련 문제