programing

디버깅 없이 잘못된 명령 오류를 발생시킨 어셈블리 명령 찾기

cafebook 2023. 7. 2. 20:57
반응형

디버깅 없이 잘못된 명령 오류를 발생시킨 어셈블리 명령 찾기

어셈블리에서 작성한 프로그램을 실행하는 동안, 저는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

반응형