使用gcc为32位架构编译的C程序的意外退出代码 [英] Unexpected exit code for a C program compiled for 32 bit architecture using gcc
问题描述
我编写了一个简单的C程序,并将其编译为32位体系结构.
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
我希望20100
是返回值,由主函数打印出来.
I'm expecting 20100
to be the return value, as printed by the main function.
但是,我得到132
作为退出代码.
But, I'm getting 132
as the exit code.
我使用GDB验证了当main将要返回时,20100
是eax
寄存器中的值.
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
我什至验证了将控制权转移回__libc_start_main
并调用exit
函数时,20100
被作为exit()
的参数推入了.
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
这可能是什么原因?
我认为这里的退出代码132
与SIGILL
没有任何关系,因为当我将硬编码参数从200
更改为2
时,退出代码更改为172
,其中预期的退出代码为26796
.
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
.
推荐答案
您正在执行的操作似乎无效,因为您只有8位可以返回操作系统.
It looks like what you're doing is invalid, as you only have 8 bits to return to the OS.
假设您要链接到libc
:
程序退出时,可以使用退出状态将少量有关终止原因的信息返回给父进程.这是一个介于0到255之间的值,退出进程将其作为要退出的参数传递.
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:
警告:请勿尝试将错误数量用作退出状态.实际上这不是很有用.父进程通常不会在意发生了多少错误.更糟糕的是,它不起作用,因为状态值被截断为八位.因此,如果程序尝试报告256个错误,则父级将收到0个错误的报告,即成功.
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.
这篇关于使用gcc为32位架构编译的C程序的意外退出代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!