如何在C中检测变量uninitialized / catch segfault

时间:2014-05-03 00:37:45

标签: c segmentation-fault signals

我目前有一个程序,我需要测试作为参数传入的变量是否未初始化。到目前为止,在C中看起来很难做到,所以我的下一个想法是调用信号处理程序来捕获段错误。但是,我的代码在尝试访问未初始化的变量时没有调用信号处理程序,如下所示:

void segfault_sigaction(int signal, siginfo_t *si, void *arg)
{
    printf("Caught segfault at address %p\n", si->si_addr);
    exit(0);
}

void myfree(void*p, char * file, int line){

    struct sigaction sa;

    memset(&sa, 0, sizeof(sigaction));
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = segfault_sigaction;
    sa.sa_flags   = SA_SIGINFO;

    sigaction(SIGSEGV, &sa, NULL);

    char up = *((char*)p); //Segfault

编辑:在Linux系统上

3 个答案:

答案 0 :(得分:3)

这不是一个好主意。如果程序试图使用未初始化的变量,那么它总是一个bug。找到这个错误的正确方法是使用一个好的编译器,启用所有警告,或者更好的静态分析工具。在程序开发时应该找到并修复bug。不在运行时。

此外,通过良好的程序设计,调用者负责将正确的参数传递给函数。函数根本不需要关心调用者。如果通过引用传递了错误的参数,则所有投注都将关闭。

访问未初始化指针指向的内存会导致未定义的行为,其中包括以下结果:

  • 存在分段错误。
  • 程序崩溃。
  • 没有任何事情发生,但程序开始表现得很奇怪。
  • 没有任何事情发生,程序似乎工作正常。

如果你这样做是因为你想要防御性编程,你应该考虑对变量值进行某种形式的检查,最好是通过assert()或static_assert()。

答案 1 :(得分:1)

尝试将Valgrind与memcheck工具一起使用。它可以检测未初始化的内存访问以及许多其他无效访问模式。可以找到一个教程here。添加--track-origins = yes参数(需要版本3.4.0)可以更容易地找到未初始化内存的使用。

答案 2 :(得分:0)

如果您没有初始化指针,则指针没有默认值。有时它是NULL(如果pNULL,你可以抓住SIGSEGV),有时它会指向一个有效的记忆,似乎一切正常。他们拥有的价值就是他们现在正在使用的内存中的垃圾。至于你的问题,我建议编写你自己的malloc()free()版本,给分配内存的标题添加一个幻数,并测试它是否仍在那里释放。