gpt4 book ai didi

linux - 为什么 _exit(0)(通过系统调用退出)阻止我接收任何标准输出内容?

转载 作者:IT王子 更新时间:2023-10-29 01:19:58 26 4
gpt4 key购买 nike

我有一个 Linux x86-32 GAS 汇编程序这样终止:

movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80

当我这样退出时,程序正常运行,但如果我尝试读取标准输出输出,我什么也得不到(使用 less 或 wc)。

我尝试编译一个最小的 C 程序并比较 strace 输出。我发现的唯一区别是,GCC 使 C 程序 (int main() { printf("donkey\n"); }) 隐式退出 exit_group(0) 在 strace 输出中。

我尝试修改我的 ASM 程序以使用 call exit 而不是原始系统调用退出。标准输出现在可以正常读取了。

测试用例

.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

编辑:

我尝试同时调用 tcflushfflush,但问题仍然存在。使用 fflush 我什至会遇到段错误。

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

编辑2:

好的,现在大家可以使用了。我使用了从此处复制的错误调用约定:Printf without newline in assembly

fflush 的参数应该像往常一样在堆栈上。

$ 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
$

谢谢大家,特别是nos。

最佳答案

当您将 stdout 通过管道传输到 wc 时,stdout 将完全缓冲。

_exit 立即终止进程并且不运行 atexit() 和其他清理处理程序。运行时将注册此类处理程序以在刷新打开的 FILE* 时运行,例如 stdout。当这些处理程序在退出时未执行时,缓冲数据将丢失。

如果在 printf 调用之后调用 fflush(stdout),或者如果您只是在 consol 中运行程序而不将输出传输到另一个程序,您应该会看到输出 - 在这种情况下,stdout 通常会被行缓冲,所以每当你写一个\n

时,stdout 就会被刷新

关于linux - 为什么 _exit(0)(通过系统调用退出)阻止我接收任何标准输出内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9755027/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com