디버깅 없이 잘못된 명령 오류를 발생시킨 어셈블리 명령 찾기
어셈블리에서 작성한 프로그램을 실행하는 동안, 저는Illegal instruction
오류. 디버깅 없이 어떤 명령어가 오류를 유발하는지 알 수 있는 방법이 있습니까? 즉, 제가 실행 중인 컴퓨터에 디버거나 개발 시스템이 없기 때문입니다.즉, 한 시스템에서 컴파일하고 다른 시스템에서 실행합니다.컴파일 중인 컴퓨터에서 프로그램을 테스트할 수 없습니다. SSE4.2를 지원하지 않기 때문입니다.그럼에도 불구하고 내가 프로그램을 실행하는 기계는 SSE4.2 명령을 지원합니다.
gcc를 명령을 인 것 .-msse4.2
깃발. 아니면 그게 이유가 아니라고 생각하세요?YASM에게 SSE4.2 명령을 인식하도록 지시하는 방법을 알고 있습니까?
SIGILL 신호를 트랩한 다음 SA_SIGINFO를 디코딩하여 프로그램이 어떤 종류의 불법 작업을 하는지 확인해야 할 것 같습니다.
최근 132 종료 상태 코드(128 + 4: 프로그램이 신호 + 잘못된 명령 신호에 의해 중단됨)로 인해 충돌이 발생했습니다.추락의 원인이 무엇인지 제가 알아낸 방법은 다음과 같습니다.
먼저 코어 덤프를 활성화했습니다.
$ ulimit -c unlimited
에 흥롭게도,실리를던라는 이름의 .core
리눅스에 코어 덤프에 PID를 추가하라고 말해야 했습니다.
$ sudo sysctl -w kernel.core_uses_pid=1
그런 다음 프로그램을 실행하고 이름이 붙은 코어를 얻었습니다.core.23650
나는 바이너리와 코어에 gdb를 로드했습니다.
$ gdb program core.23650
gdb에 들어가자 다음과 같은 정보가 표시되었습니다.
Program terminated with signal SIGILL, Illegal instruction.
#0 0x00007f58e9efd019 in ?? ()
그것은 내 프로그램이 불법적인 지시로 인해 중단되었다는 것을 의미합니다.0x00007f58e9efd019
주소 메모리그런 다음 마지막으로 실행된 명령을 확인하기 위해 sm 레이아웃으로 전환했습니다.
(gdb) layout asm
>|0x7f58e9efd019 vpmaskmovd (%r8),%ymm15,%ymm0
|0x7f58e9efd01e vpmaskmovd %ymm0,%ymm15,(%rdi)
|0x7f58e9efd023 add $0x4,%rdi
|0x7f58e9efd027 add $0x0,%rdi
은 지도 그것은였다니습시지.vpmaskmovd
오류의 원인이 되었습니다.세트를 로 하는 . AVX2는 AVX2와 AVX2 사이에 있습니다.
$ cat /proc/cpuinfo | grep avx2
마지막으로 vpmaskmovd가 AVX2 전용 명령이라는 것을 확인했습니다.
실제로 프로그램에 잘못된 opcode가 포함되어 있기 때문이 아니라 프로그램에 버그(예: 버퍼 오버플로)가 있기 때문에 프로그램이 일반 데이터가 있는 임의 주소나 코드로 점프하지만 opcode의 시작 부분은 점프하지 못하게 만드는 경우가 많습니다.
만약 당신이 그 시스템에서 코어 덤프를 활성화할 수 있다면, 프로그램을 실행하고 크래시를 허용한 다음, 당신의 개발 기계에 코어 덤프를 가져와서 당신의 타겟 아키텍처를 디버그하기 위해 만들어진 GDB에 로드하면, 크래시가 발생한 정확한 위치를 알 수 있을 것입니다.GDB를 사용하면 됩니다.core
코어 파일을 디버거에 로드하는 명령입니다.
대상에서 코어 덤프를 활성화하려면:
ulimit -c unlimited
코어 파일의 이름을 지정하는 방법을 제어하는 유사 파일(현재 구성을 보려면 cat, 구성을 변경하려면 write)
/proc/sys/kernel/core_pattern /proc/sys/kernel/core_uses_pid
내 시스템에서 코어 덤프가 활성화되면 크래시 프로그램은 단순히 "core"라는 이름의 파일을 작업 디렉토리에 기록합니다.이 정도면 충분하지만 코어 덤프 파일의 이름을 변경하면 필요한 경우(간헐적인 문제의 경우) 코어 덤프 기록을 유지할 수 있습니다.
음...물론 추적 인쇄물을 삽입할 수 있으므로 코드의 큰 영역을 빠르게 제외할 수 있습니다.작업을 완료했으면 실행합니다. 예를 클릭합니다.
$ objdump --disassemble my-crashing-program | less
그런 다음 오류의 원인으로 알고 있는 기능으로 이동하여 코드를 읽고 이상하게 보이는 것을 찾습니다.
어떻게 해야 할지 잘 모르겠습니다.objdump
는 잘못된 지침을 표시하지만 눈에 띄어야 합니다.
수기로 작성된 어셈블리의 경우 스택 관리 문제로 인해 아무 곳도 반환되지 않을 것으로 예상됩니다.모든 레지스터를 저장하는 디버깅 출력 루틴을 작성하고 모든 기능의 맨 위에 호출을 삽입합니다.
그러면 당신이 얼마나 멀리 가는지 보게 될 것입니다.
(BTW, 좋은 편집자, 그리고 어셈블러의 매크로 구문에 대한 이해는 기계 코드를 작성할 때 생명을 구하는 것입니다.)
a 누락return
함수의 끝에 있는 문이 원인일 수 있습니다.
언급URL : https://stackoverflow.com/questions/10354147/find-which-assembly-instruction-caused-an-illegal-instruction-error-without-debu
'programing' 카테고리의 다른 글
spring-boot-starter-web과 spring-boot-starter-weblux는 함께 작동하지 않습니까? (0) | 2023.07.02 |
---|---|
MongoDB의 실제 필드 유형 반환 (0) | 2023.07.02 |
Python을 사용하여 디렉토리의 모든 파일 삭제 (0) | 2023.07.02 |
이미지에서 알파 채널 제거 (0) | 2023.07.02 |
첫 번째와 두 번째 최대 수를 찾는 방법은 무엇입니까? (0) | 2023.07.02 |