1
    FILE *file = fopen(argv[1], "r");
    if(file != NULL){
        char command[MAX_BUFFER];
        while(fgets(command, MAX_BUFFER, file) != NULL){ //read line
            //operations
        }
        fclose(file);
    }
    else write(fileno(stderr), ERROR_MESSAGE, strlen(ERROR_MESSAGE));

我正在研究一个非常基本的 UNIX shell 实现,它从文件中逐行读取和执行。从上面的代码中,我试图弄清楚为什么fclose()可能会失败,因为 valgrind 似乎告诉我我已经打开了这个文件描述符。

我是否正确假设泄漏摘要中的“仍然可达”568 字节以fclose()某种方式失败?

==25428== FILE DESCRIPTORS: 4 open at exit.
==25428== Open file descriptor 3: test
==25428==    at 0x4F186B0: __open_nocancel (syscall-template.S:82)
==25428==    by 0x4EAC628: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:233)
==25428==    by 0x4EA1265: __fopen_internal (iofopen.c:93)
==25428==    by 0x400C0C: main (in /home/Desktop/sh)
==25428== 
==25428== Open file descriptor 2: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== Open file descriptor 1: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== Open file descriptor 0: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== LEAK SUMMARY:
==25428==    definitely lost: 0 bytes in 0 blocks
==25428==    indirectly lost: 0 bytes in 0 blocks
==25428==      possibly lost: 0 bytes in 0 blocks
==25428==    still reachable: 568 bytes in 1 blocks
==25428==         suppressed: 0 bytes in 0 blocks
4

3 回答 3

1

对了,检查返回值,也贴一个错误来简单解释一下。如果您想确认它仍然打开,请尝试 lsof,但您可能需要使用 grep 来获取程序名称或 pid,因为可能有几十个。

于 2013-01-18T05:12:49.050 回答
0

您的可见代码看起来不错。但是要回答您的问题:可能,但问题出在其他地方;-)

要调试您的程序,请注释掉“操作”,这样您就有了一个空循环。valgrind 还在抱怨吗?

不:问题很可能出在您命名为“操作”的代码中。

删除注释并在 (-g) 上使用调试符号进行编译,并将 valgrind 与以下选项一起使用: valgrind --leak-check=yes --show-reachable=yes --track-origins=yes yourprogram

是的:(非常不可能)其他东西被破坏了,尝试使用更多注释代码进行 valgrind。

要在编译时查找错误,请使用编译器的标志(例如 gcc 具有 -Wall -Wextra -Wwrite-strings -Wformat=2 -Wformat -Wformat-security -D_FORTIFY_SOURCE=2 等)。

并使用静态分析器,例如 llvm/clang(使用 clang --analyze yourprogram.c 编译)

于 2013-01-18T08:17:59.123 回答
0

@rockdaboot 建议注释掉我的操作表明我仍然失去了记忆,但至少我知道它不是来自 fclose ......谢谢大家的提示!回到调试!

于 2013-01-18T15:41:29.810 回答