2012-02-25 1 views
0

대학의 Pintos 장난감 운영체제에서 작업하고 있지만 GCC 4.6.2를 사용할 때 이상한 버그가 있습니다. 시스템 호출 인수 (인라인 어셈블리에서 3 pushl -s 만)를 푸시면 일부 신비한 데이터가 스택에 표시되고 인수의 순서가 잘못되었습니다. -fno-omit-frame-pointer를 설정하면 이상한 데이터가 제거되지만 인수는 여전히 잘못된 순서로 유지됩니다. GCC 4.5 잘 작동합니다. 어떤 특정 옵션을 통해이 문제를 해결할 수 있습니까?GCC 4.6.2의 신비한 스택 문제

참고 : 여전히 -O0과 함께 문제가 발생합니다.

+3

최소 예제 코드? –

답변

0

범인은 -fomit-frame-pointer였습니다. 4.6.2 이후 기본적으로 활성화되었습니다. -fno-omit-frame-pointer가 문제를 해결했습니다.

1

코드 예제와 다른 컴파일의 결과 목록이 없으면 도움을 받기가 어렵습니다. 하지만 여기에 세 가지 원인이있을 수 있습니다.

  1. 인수가 스택에 푸시되는 방식을 알고 있어야합니다. 인수는 뒤에서 푸시됩니다. 이렇게하면 printf(char *, ...)이 첫 번째 항목을 검사하여 더 많은 항목이 있는지 확인할 수 있습니다. int foo(int a, int b, int c) 함수를 호출하려면 c을 입력 한 다음 b을 입력하고 마지막으로 으로 푸시해야합니다.
  2. 스택의 이상한 데이터가 반송 주소 또는 EFLAGS 일 수 있습니까? 나는 Pintos와 시스템 호출이 어떻게 이루어지는 지 모르지만 CALL/RET과 INT/IRET의 차이점을 이해했는지 확인하십시오. INT는 플래그를 스택에 푸시합니다.
  3. 인라인 어셈블리에 부작용이있는 경우 앞에 volatile/__volatile__을 입력 할 수 있습니다. 그렇지 않으면 최적화 할 때 GCC에서 이동이 허용됩니다.

어떤 일이 벌어지고 있는지 더 잘 이해하려면 코드를 살펴야합니다.

+0

매개 변수는 3 회 pushl-s와 함께 전달되고 시스템 호출 번호가 push됩니다 (asm 휘발성). 그러나 커널 세그먼트가 메모리를 볼 때 인수는 3 1 2 순서 (또는 옵션에 따라 가비지)입니다. GCC 4.5를 사용하면 올바른 위치에 올바른 순서로 제공됩니다. –

+0

@vahokif 코드 예제를 보여줄 수 있습니까? 내가 해결할 수있을 지 모르겠지만, 코드를 보지 않고는 거의 불가능합니다. 물론 컴파일러에 버그가있을 수도 있습니다. 이 경우 버그 보고서를 제출하는 것이 좋습니다. –

0

syscall 다음에 스택의 매개 변수를 지우셨습니까? gcc는 스택을 만져서 코드를 생성하는 것이 예상되는 스택 포인터에 달려 있다는 것을 인식하지 못할 수도 있습니다. -fno-omit-frame-pointer gcc가 locate 데이터에 액세스하기 위해 e/rbp를 사용하도록하지만 실제로 문제를 숨 깁니다.