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

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

But when I ran it, I encountered 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 expect to 20100

be the return value printed by the main function.

But I am getting 132

like exit code.

I checked with GDB that 20100

is the value in the register eax

when main returns.

➜  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 confirmed that when control is passed back to a function __libc_start_main

and exit

is 20100

pushed as an argument 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 be causing this?

I don't think the exit code 132

here has anything to do with SIGILL

, because when I changed the hardcoded argument to foo()

from 200

to 2

, the exit code was changed to 172

where the expected exit code is 26796

.

+3


source to share


3 answers


It looks like what you are doing is wrong since you only have 8 bits to get back to the OS.

Assuming you bind to libc

:

When the program exits, it can return a little information about the reason for termination to the parent process using the exit status. This is a value between 0 and 255 that exits the process as an argument to exit.



As stated in its documentation here . This line is also relevant:

Warning. Don't try to use the error count as your exit status. This is actually not very useful; the parent process usually doesn't care how many errors happened. Worse, it doesn't work because the status value is truncated to eight bits. Thus, if the program tried to report 256 errors, the parent will receive a report of 0 errors, that is, success.

+3


source


20100

decimal is 4E84

hex.
132

decimal 84

hex.
Your shell gets the return value as only 8 bits.



+2


source


As long as your program can return 20100, the system only gets the least significant byte, for example return % 256

So 20100 % 256 = 132

0


source







All Articles