加入收藏 | 设为首页 | 会员中心 | 我要投稿 德州站长网 (https://www.0534zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 动态 > 正文

运行个 Hello World 也可以出 Bug?

发布时间:2022-03-22 13:47:18 所属栏目:动态 来源:互联网
导读:一句最简单的 Hello World,居然也会出 Bug? 倒不是这句代码还能写错,而是运行时找到了许多操作系统对异常处理的漏洞。 在向 /dev/full 输出结果,也就是设备空间不足、任何写入都应失败的情况下,C 语言依然返回了 0,成功退出: $ gcc hello.c -o hello
       一句最简单的 Hello World,居然也会出 Bug?
 
      倒不是这句代码还能写错,而是运行时找到了许多操作系统对异常处理的漏洞。
 
      在向 /dev/full 输出结果,也就是设备空间不足、任何写入都应失败的情况下,C 语言依然返回了 0,成功退出:
 
$ gcc hello.c -o hello
$ ./hello > /dev/full
$ echo $?
0
     Bug 的最初发现者表示:这可不是一个小错误,本质上是“打印到标准输出”的任务。
 
     主要使用的是 Linux 系统下的一个经典的设备文件,/dev/ full。
 
      /dev/ full 总是在写入时返回设备无剩余空间(错误码为 ENOSPC),常常用于测试程序能否正确处理 I / O 错误。
 
如果程序正常,那么就会返回错误报告:
 
$ echo "Hello World!" > /dev/full
bash: echo: write error: No space left on device
$ echo $?
1
而正如我们开头所示的代码,在用 C 语言进行输出时,hello 程序却报告成功,返回了 0。
 
用 strace 命令跟踪这一进程产生的系统调用可以发现,程序确实出现了故障:
 
$ strace -etrace=write ./hello > /dev/full
write(1, "Hello World!n", 13)          = -1 ENOSPC (No space left on device)
+++ exited with 0 +++
而以“错误不该被悄悄传递”为口号的 Python 也着了道。
 
程序向 stderr 打印了一条消息,丢失了信息,但最后也返回了 0:
 
$ python2 hello.py > /dev/full
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
$ echo $?
0
这个 Bug 严重吗?现实世界任何一个程序都不会拿 Hello World 当作关键性安全问题,但“打印到标准输出”却是现实中确实会有的程序任务。
 
而这也正是 Hello World 这个最简单的程序的本质。
 
目前,博主已经针对这一 Bug 给出了一些解决方案,比如在 C 语言环境中可以采用这样的方法:
 
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
    printf("Hello, World!n");
 
    if (fflush(stdout) != 0 || ferror(stdout) != 0) {
        return EXIT_FAILURE;
    }
 
    return EXIT_SUCCESS;
}
而评论区也贡献了 Java 环境中的解决方案,即添加一个方法来获得底层的、未包装的 OutputStream:
 
System.out.println("Hello World!");
    if (System.out.checkError()) throw new IOException();
下方还有人补充到,Java 已经引入的 RuntimeIOException 就可以用于 I / O 异常出现意外的情况:
 
因此我们可以引入一个新的类,比如 ErrorCheckingPrintStream,并将“ErrorCheckingPrintStream withErrorChecks ()”方法添加到 PrintStream 中。

(编辑:德州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读