문제

예를 들어 인터럽트에 첨부 된 콜백을 설정하여 메모리 주소가 발생할 때 감지 할 수 있습니다. 누구든지 방법을 아는 사람이 있습니까?

런타임 에서이 작업을 수행하고 싶습니다 (아마도 GDB는이 기능이 있지만 특정 응용 프로그램은 GDB가 충돌하게됩니다).

도움이 되었습니까?

해결책

다양한 주소를 가로 채려면 사용할 수 있습니다. mprotect() 해당 메모리를 작성할 수없는 것으로 표시하고 사용하여 신호 처리기를 설치하려면 sigaction() 결과적인 SIGSEGV를 잡으려면 로깅이나 무엇이든 페이지를 다시 쓰기 쉬운 것으로 표시하십시오.

다른 팁

필요한 것은 X86 디버그 레지스터에 대한 액세스입니다. http://en.wikipedia.org/wiki/debug_register

DR0에서 DR3에서 DR3에서 중단 점 주소를 설정 한 다음 DR7의 조건 (데이터 쓰기)을 설정해야합니다. 인터럽트가 발생하고 디버그 코드를 실행하여 DR6을 읽고 중단 점의 원인을 찾을 수 있습니다.

GDB가 작동하지 않으면 더 간단하고 작은 디버거를 시도 할 수 있습니다. http://sourceforge.net/projects/minibug/ - 작동하지 않는 경우 적어도 코드를 살펴보고 프로세서에서 디버깅 하드웨어를 사용하는 방법을 이해할 수 있습니다.

또한 Linux 디버깅 기술을 마스터 링하는 훌륭한 IBM 개발자 리소스가 있으며 몇 가지 추가 옵션을 제공해야합니다.

http://www.ibm.com/developerworks/linux/library/l-debug/

이 작업을 수행하는 것에 대한 합리적으로 좋은 기사는 Windows가 여기 있습니다 (Linux에서 실행 중이지만 다른 사람들은 Windows에서 수행하기를 원하는이 질문에 올 수도 있습니다).

http://www.codeproject.com/kb/debug/hardwarebreakpoint.aspx

-아담

GDB는 해당 기능이 있습니다. 하드웨어 파트 포인트라고하며 Linux/x86에서 잘 지원됩니다.

(gdb) watch *(int *)0x12345678

응용 프로그램이 GDB가 충돌하는 경우 현재 GDB를 빌드하십시오. CVS 헤드.

그 GDB가 여전히 실패하면 GDB를 제출하십시오 벌레.

SIGSEGV 핸들러 (좋은 테스트 케이스 제공)를 해킹 할 수있는 것보다 GDB를 더 빨리 고칠 수 있으며 GDB에 대한 수정은 미래의 문제를 도와줍니다.

mprotect에는 단점이 있습니다. 메모리는 페이지에 정렬되어야합니다. 스택에 문제가있는 메모리가 있었고 mprotect ()를 사용할 수 없었습니다.

Adam이 말했듯이, 원하는 것은 디버그 레지스터를 조작하는 것입니다. Windows에서는 이것을 사용했습니다. http://www.morearty.com/code/breakpoint/ 그리고 그것은 훌륭하게 작동했습니다. 나는 또한 그것을 Mach-O (Mac OS X)에 포팅했으며 훌륭하게 작동했습니다. mach-o에는 strook_set_state ()가 있기 때문에 SetTheRreadContext ()와 동일하기 때문에 쉬웠습니다.

Linux의 문제점은 그러한 동등성이 없다는 것입니다. 나는 ptrace를 발견했지만, 나는 이것이 할 수 없다고 생각했다. 더 간단한 것이 있어야한다. 그러나 없습니다. 아직. 나는 그들이 커널과 사용자 공간 모두에 대해 HW_BREAKPOINT API에서 작업하고 있다고 생각합니다. (보다 http://lwn.net/articles/317153/)

그러나 내가 이것을 찾았을 때 : http://blogs.oracle.com/nike/entry/memory_debugger_for_linux 나는 그것을 시도했고 그렇게 나쁘지 않았다. PTRACE 메소드는 프로그램에 첨부하고 디버그 레지스터의 새로운 값을 주입하고 새로운 HW 브레이크 포인트 세트로 계속 진행하는 "디버거"역할을하는 "외부 프로세스"로 작용하여 작동합니다. 문제는 포크 ()를 사용 하여이 "외부 프로세스"를 직접 만들 수 있으며 (PTHREAD로 성공하지 못했음) 코드에서 이러한 간단한 단계를 인라인으로 수행 할 수 있습니다.

AddWatchPoint 코드는 64 비트 Linux에서 작동하도록 조정되어야하지만 사용자 _dr7 등을 변경하는 것입니다 (Struct User, U_Debugreg [7]). 또 다른 것은 ptrace_attach 후에 디버거가 실제로 멈출 때까지 기다려야한다는 것입니다. 그러나 바쁜 루프에서 pokeuser를 다시 시도하는 대신, 올바른 일은 PID의 Waitpid () 일 것입니다.

PTRACE 방법의 유일한 캐치는 프로그램에 한 번에 하나의 "디버거"가 첨부 될 수 있다는 것입니다. 따라서 프로그램이 이미 GDB 제어하에 실행중인 경우 Ptrace 첨부가 실패합니다. 그러나 예제 코드와 마찬가지로 SIGTRAP에 대한 신호 핸들러를 등록하고 GDB없이 실행할 수 있으며 신호를 잡을 때 GDB가 첨부 될 때까지 대기하는 바쁜 루프를 입력 할 수 있습니다. 거기에서 누가 기억을 쓰려고했는지 알 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top