0

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

alexander
  • 2,703
  • 18
  • 16
AbhishekSaha
  • 705
  • 3
  • 9
  • 24
  • This is OS related, a vital piece of information that you have not specified in your question. – barak manos May 03 '14 at 00:44
  • 2
    accessing an uninitialized variable does not necessarily cause a segfault – M.M May 03 '14 at 00:47
  • `sizeof(sigaction)` should be `sizeof(struct sigaction)` or `sizeof sa` – M.M May 03 '14 at 00:49
  • 2
    Uninitialized means the contents are undefined. In general you can't "detect" this but many compilers have ability to warn on usage of potentially unassigned variables. – Brandin May 03 '14 at 10:10

3 Answers3

3

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().

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

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.

LogicG8
  • 1,767
  • 16
  • 26
0

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.

jfly
  • 7,715
  • 3
  • 35
  • 65
  • To qualify the "sometimes" more: This depends on the compiler, operating system, and compiler flags. For example, without optimization, some compilers initialize all freshly allocated memory with 0s. In release, this might be overwritten with random data. It's best to use a tool such as valgrind as LogicG8 recommends. – Manuel May 13 '14 at 11:42