How to detect if variable uninitialized/catch segfault in C

社会主义新天地 提交于 2019-12-25 07:09:10

问题


I currently have a program where I need to test if a variable passed in as a parameter is uninitialized. So far it seems like this is pretty hard to do in C, so my next idea was to invoke a signal handler to catch the segfault. However, my code isn't calling upon the signal handler when it tries to access the uninitialized variable, like so:

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

EDIT: On Linux system


回答1:


This is not a good idea. If the program attempts to use an uninitialized variable, then it is always a bug. The correct way of finding this bug is to use a good compiler with all warnings enabled, or better yet a static analysing tool. The bug should be found and fixed when the program is developed. Not in runtime.

Furthermore, with good program design the caller is responsible of passing correct parameters to a function. The function should not need to concern itself with the caller at all. If an incorrect parameter is passed by reference, all bets are off.

Accessing the memory pointed at by an uninitialized pointer leads to undefined behavior, which includes the following results:

  • There is segmentation fault.
  • There is a program crash.
  • Nothing happens but the program starts to behave in weird ways.
  • Nothing happens and the program seems to work just fine.

If you are doing this because you want defensive programming, you should consider some kind of sanity check of the variable values instead, preferably through assert() or static_assert().




回答2:


Try using Valgrind with the memcheck tool. It can detect uninitialized memory access as well as a number of other invalid access patterns. A tutorial can be found here. Adding the --track-origins=yes argument (requires version 3.4.0) can make it easier to find uses of uninitialized memory.




回答3:


Pointers have no default value if you didn't initialize it. Sometimes it's NULL(if p is NULL, you can catch the SIGSEGV), sometimes it points to a valid memory and seems everything is OK. The value they have is just whatever junk was in the memory they're using now. As to your problem, I'd suggest writing your own version of malloc() and free(), put a magic number to the header of allocated memory, and test whether it's still there when freeing.



来源:https://stackoverflow.com/questions/23438915/how-to-detect-if-variable-uninitialized-catch-segfault-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!