Unexpected exit code for a C program compiled for 32 bit architecture using gcc

◇◆丶佛笑我妖孽 提交于 2020-01-14 11:28:57

问题


I wrote a simple C program and compiled it for 32 bit architecture.

But when I ran it, I found unexpected results.

#include <stdio.h>

int foo(int n) {
    int sum=0;
    int i;
    if (n <= 1 || n >= 0x1000)
        return n;
    for (i=0; i<= n; i++) {
        sum = sum + i;
    }
    return foo(sum);
}

int main(int argc, char** argv) {
    int n;
    n = foo(200);
    printf("\n\n main about to return %d \n\n", n);
    return n;
}
➜  wbench  gcc -o test.elf test.c -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -Wall
➜  wbench  ./test.elf 

 main about to return 20100


➜  wbench  echo $?
132

I'm expecting 20100 to be the return value, as printed by the main function.

But, I'm getting 132 as the exit code.

I verified using GDB that 20100 is the value in the eax register when main is about to return.

➜  wbench  gdb -q test.elf
gdb-peda$ b *main+44
Breakpoint 1 at 0x8048492
gdb-peda$ r

 main about to return 20100 

Breakpoint 1, 0x08048492 in main ()

   0x8048489 <main+35>: call   0x80482f0 <printf@plt>
   0x804848e <main+40>: mov    eax,DWORD PTR [ebp-0x4]
   0x8048491 <main+43>: leave  
=> 0x8048492 <main+44>: ret    
   0x8048493:   xchg   ax,ax



gdb-peda$ p/d $eax
$1 = 20100
gdb-peda$ c
[Inferior 1 (process 32172) exited with code 0204]
Warning: not running or target is remote
gdb-peda$ p/d 0204
$2 = 132

I even verified that when control is transferred back to __libc_start_main and exit function is being called, 20100 is being pushed as argument to exit().

gdb-peda$ r
 main returning 20100 
Breakpoint 1, 0x08048492 in main ()

gdb-peda$ finish
=> 0xf7e1ca83 <__libc_start_main+243>:  mov    DWORD PTR [esp],eax
   0xf7e1ca86 <__libc_start_main+246>:  call   0xf7e361e0 <exit>
   0xf7e1ca8b <__libc_start_main+251>:  xor    ecx,ecx
gdb-peda$ si
=> 0xf7e1ca86 <__libc_start_main+246>:  call   0xf7e361e0 <exit>
   0xf7e1ca8b <__libc_start_main+251>:  xor    ecx,ecx
gdb-peda$ x/wd $esp
0xffffd5c0: 20100

What could possibly be the reason for this ?

I don't think the exit code 132 here has got anything to do with SIGILL because when I changed the hardcoded argument to foo() from 200 to 2 , the exit code changed to 172 where the expected exit code is 26796.


回答1:


It looks like what you're doing is invalid, as you only have 8 bits to return to the OS.

Assuming you're linking against libc:

When a program exits, it can return to the parent process a small amount of information about the cause of termination, using the exit status. This is a value between 0 and 255 that the exiting process passes as an argument to exit.

As indicated in its documentation here. Also relevant is this line:

Warning: Don’t try to use the number of errors as the exit status. This is actually not very useful; a parent process would generally not care how many errors occurred. Worse than that, it does not work, because the status value is truncated to eight bits. Thus, if the program tried to report 256 errors, the parent would receive a report of 0 errors—that is, success.




回答2:


20100 decimal is 4E84 hex.
132 decimal is 84 hex.
Your shell is receiving the return value as only 8 bits.




回答3:


While your program may be returning 20100, the system only fetches the lowest byte, e.g return % 256

So 20100 % 256 = 132



来源:https://stackoverflow.com/questions/31815346/unexpected-exit-code-for-a-c-program-compiled-for-32-bit-architecture-using-gcc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!