【问题标题】:MinGW fprintf (vswprintf) causing a segmentation faultMinGW fprintf (vswprintf) 导致分段错误
【发布时间】:2015-11-09 08:58:04
【问题描述】:

我有以下示例程序,它使用预处理器来定义一个简单的调试功能。

main.c

#include <stdio.h>
#ifdef DEBUG
#define __DEBUG 1
#else
#define __DEBUG 0
#endif
#define dbg_out(fmt, ...) \
    do {if (__DEBUG) fprintf(stdout, "%s:%s:%s():" fmt "\n", __FILE__, \
                           __LINE__, __FUNCTION__, __VA_ARGS__); } while (0)

int main (int argc, char **argv)
{
    dbg_out ("Printing argc: %d", argc);
    return 0;
}

我用调试符号和定义的 DEBUG 编译它,如下所示:

gcc main.c -g -DDEBUG -o test.exe

现在,当我编译并运行这个程序时,我会得到一个 SIGSEGV 并带有以下回溯:

Program received signal SIGSEGV, Segmentation fault.
0x75b7b090 in vswprintf () from C:\Windows\SysWOW64\msvcrt.dll

(gdb) bt

#0  0x75b7b090 in vswprintf () from C:\Windows\SysWOW64\msvcrt.dll
#1  0x75b73633 in msvcrt!fprintf () from C:\Windows\SysWOW64\msvcrt.dll
#2  0x75bb1228 in msvcrt!_iob () from C:\Windows\SysWOW64\msvcrt.dll
#3  0x0040a070 in __register_frame_info ()
#4  0x00401425 in main (argc=1, argv=0x4a2f08) at src/main.c:16

GCC (MinGW) 版本是4.8.1。为什么会发生这种崩溃?怎么解决?

【问题讨论】:

    标签: c gcc mingw


    【解决方案1】:

    预处理器宏__LINE__ 不是char *,而是int,所以:

    #define dbg_out(fmt, ...) \
        do {if (__DEBUG) fprintf(stdout, "%s:%s:%s():" fmt "\n", __FILE__, \
                               __LINE__, __FUNCTION__, __VA_ARGS__); } while (0)
    

    需要:

    #define dbg_out(fmt, ...) \
        do {if (__DEBUG) fprintf(stdout, "%s:%d:%s():" fmt "\n", __FILE__, \
                               __LINE__, __FUNCTION__, __VA_ARGS__); } while (0)
    

    请注意,gcc 会在启用警告的情况下进行编译(例如 gcc -Wall ...)。

    【讨论】:

    • 是的,我确实在我的大型项目中使用了-Wall,但是我有很多未使用的变量错误,所以我错过了。当我制作这个测试用例时,我完全忘记了它。我会牢记在心,以备不时之需。如此简单的错误,但有时却很难注意到。谢谢。
    • 是的,这就是为什么总是修复警告和“编译干净”很重要 - 尽管许多警告可能是无害的(例如未使用的变量),这些无害警告的噪音可能会导致您错过一些重要的事情。
    【解决方案2】:
    Please refer the following code.
    
        #include <stdio.h>
    #define DEBUG 1
    #ifdef DEBUG
    #define __DEBUG 1
    #else
    #define __DEBUG 0
    #endif
    #define dbg_out(fmt, ...) \
        do {if (__DEBUG) fprintf(stdout, "%s:%d:%s():" fmt "\n", __FILE__, \
                               __LINE__, __FUNCTION__, __VA_ARGS__); } while (0)
    
    int main (int argc, char **argv)
    {
        dbg_out ("Printing argc: %d", argc);
        return 0;
    }
    ~                                                                                 
    

    ~

    【讨论】:

    • 为什么有人给了-1分?查看我的帖子和上一个帖子之间的时差。我没有注意到上面的解决方案。
    • 答案因低质量而被否决:(a) 没有解释,(b) 包含冗余代码,(c) 格式混乱,(d) 与现有答案基本相同。
    • 所以你也没有提供任何理由投了反对票。而且作者只有一个错误,所以我以为他能理解。虽然提问的标准也很低。
    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2020-12-31
    • 2019-07-21
    • 2018-07-28
    相关资源
    最近更新 更多