怎么会_exit(0)$ P $(由系统调用退出)pvents我接收任何标准输出的内容? [英] How come _exit(0) (exiting by syscall) prevents me from receiving any stdout content?

查看:242
本文介绍了怎么会_exit(0)$ P $(由系统调用退出)pvents我接收任何标准输出的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆