0

Let be this C file:

#include <stdio.h>
#include <signal.h>

void handle(){
    return;
}

int main() {
    struct sigaction action;
    action.sa_handler = &handle;
    printf("%d\n", action.sa_flags);
    return 0;
}

Compiling with gcc-7 (Ubuntu 7.4.0-1ubuntu1~18.04.1) throws a warning:

src/flags.c:14:2: warning: ‘action.sa_flags’ is used uninitialized in this function [-Wuninitialized]
  printf("%d\n", action.sa_flags);

However, with gcc-5 (Ubuntu 5.4.0-6ubuntu1~16.04.11), no warning.

With gcc-7, the sa_flags value is really not initialized:

(gdb) x action.sa_flags
0x555545a0:    Cannot access memory at address 0x555545a0

where with gcc-5, it gets a strange value:

(gdb) x action.sa_flags
0x4004a0 <_start>:    0x8949ed31

I don't get why:

  • with gcc-7, sa_flags are not initiliazed to 0.
  • with gcc-5, sa_flags and the _start function have the same address.
matlink
  • 3
  • 1
  • Makes sense that a newer version of compiler gives more/better warnings. – Shawn Oct 14 '19 at 13:54
  • Uninitialized variables/elements of struct variables in a function have garbage values and trying to use them before setting them to something is undefined behavior. – Shawn Oct 14 '19 at 13:56
  • @Shawn the problem is that the manual (man sigaction) tells nothing about such a behavior. – matlink Oct 14 '19 at 13:59
  • `sa_flags and the _start function have the same address.` - the `sa_flags` contains a garbage value that happens to be equal to the address of `_start`. Which kind-of makes sense, probably a leftover from crt0. – KamilCuk Oct 14 '19 at 13:59
  • 1
    Er... it has nothing to do with `sigaction()`, and everything to do with the C language and [implicit initialization](https://en.cppreference.com/w/c/language/initialization#Implicit_initialization). – Shawn Oct 14 '19 at 14:01

1 Answers1

0

The struct sigaction action isn't initialized in either compiler. You set action.sa_handler but all other fields remain uninitialized. Starting with gcc-7 the compiler is smart enough to notice you only initialized some fields of the struct leaving other uninitialized. Gcc-5 simply isn't that smart but that doesn't mean the struct was ever initialized. What you see in action.sa_flags is simply whatever garbage is left on the stack from the crt0 code before main was called.

Although technically wrong for pointers in structs the general solution to this is to memset() the struct to 0.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42