怎么会_exit(0)$ P $(由系统调用退出)pvents我接收任何标准输出的内容? [英] How come _exit(0) (exiting by syscall) prevents me from receiving any stdout content?
问题描述
我有一个Linux的x86-32 GAS的汇编程序终止这样的:
I have a Linux x86-32 GAS assembly program terminating like this:
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
当我离开这个样子,该程序的功能,如正常,但如果我尝试读取标准输出的输出,我得到什么(即使用小于或WC)。
When I exit like this, the program functions like normally, but if I try to read the stdout output, I get nothing (using i.e. less or wc).
我试图编译一个最小的C程序,并比较strace的输出。我发现唯一的区别是,那GCC所做的C程序( INT的main(){printf的(驴\\ n);}
)与隐含退出 exit_group(0)
在strace的输出。
I tried compiling a minimal C program and comparing the strace outputs. The only difference I found was, that GCC made the C program (int main() { printf("donkey\n"); }
) implicitely exit with exit_group(0)
in the strace output.
我试图改变我的ASM程序与调用exit
而不是原始的系统调用退出。该标准输出现在可读正常。
I tried modifying my ASM program to exit with call exit
instead of the raw syscall. The stdout was now readable as normal.
测试用例
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
movl $1, %eax
movl $0, %ebx
int $0x80
编译并运行:
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
0
预期:
7
编辑:
我打过电话都 tcflush
和 fflush
,我仍然有问题。随着 fflush
我甚至得到了段错误。
I tried calling both tcflush
and fflush
, and I still have the problem. With fflush
I even get a segfault.
0xb7e9e7c9 in _IO_fflush (fp=0x804a018) at iofflush.c:42
42 iofflush.c: No such file or directory.
in iofflush.c
(gdb) bt
#0 0xb7e9e7c9 in _IO_fflush (fp=0x804a018) at iofflush.c:42
#1 0x08048434 in main () at t.asm:12
(gdb) frame 1
#1 0x08048434 in main () at t.asm:12
12 call fflush
(gdb) list
7
8 pushl $douout
9 call printf
10 # Exit
11 movl $0, %eax
12 call fflush
13 movl $1, %eax
14 movl $0, %ebx
15 int $0x80
EDIT2:
好吧,现在它工作的每一个人。我是用我从这里抄错调用约定: printf的组装不换行
Okay, it works now everyone. I was using the wrong calling convention that I copied from here: Printf without newline in assembly
为 fflush
参数应该是在栈上,像往常一样。
The argument for fflush
should be on the stack, as usual.
$ cat t.asm
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
pushl $0
call fflush
movl $1, %eax
movl $0, %ebx
int $0x80
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
7
$
谢谢大家,特别是第
Thanks everyone, especially nos.
推荐答案
在标准输出管道发送到wc,标准输出变成全缓冲。
when you pipe stdout to wc, stdout becomes fully buffered.
_exit立即终止进程,不运行的atexit()和其他清理处理程序。运行时将注册这样的处理程序既可以在该刷新打开文件*,如标准输出退出运行。当这些处理程序没有得到退出执行,缓冲的数据将会丢失。
_exit terminates the process immediately and does not run atexit() and other cleanup handlers. The runtime will register such handlers to be run on exit that flushes open FILE*, such as stdout. When those handlers does not get executed on exit, buffered data will be lost.
您应该看到的输出,如果你调用 fflush(标准输出)
的printf的电话后,或者如果你只是在一个康寿运行程序不输出管道到另一个程序 - 在这种情况下,标准输出通常会行缓冲,所以stdout是刷新每当你写一个\\ n
You should see output if you call fflush(stdout)
after the printf call, or if you just run the program in a consol without piping the output to another program - in which case stdout will normally be line buffered, so stdout is flushed whenever you write a \n
这篇关于怎么会_exit(0)$ P $(由系统调用退出)pvents我接收任何标准输出的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!