Cliff
Cliff

Reputation: 145

Returning struct in C function causes segmentation fault

I'm asking this question more out of curiosity than actual need, but this has been baffling me for a while. I'd really like to know what's wrong with my code below. BTW don't try to understand the aim of the function - it's just meant to show the problem.

The code below causes a segmentation fault when run on Linux (using gcc), but it works just fine on Windows (using Visual Studio). As far as I know, there's nothing wrong with returning a struct by value, so what am I doing wrong below?

#include <time.h>
#include <stdint.h>

using namespace std;

struct tm testFunc(const uint32_t rawtime) {
  struct tm * localTime;
  localTime = gmtime ((const time_t*)&rawtime);
  struct tm testval = *localTime;
  return testval;
}

int main() {
  uint32_t now = 1538442104;
  testFunc(now);
}

Upvotes: 3

Views: 368

Answers (2)

Fire Lancer
Fire Lancer

Reputation: 30115

The gmtime line results in undefined behaviour. localTime = gmtime((const time_t*)&rawtime); is converting a uint32_t* to a time_t* but there is no guarantee the sizes are the same, indeed on many modern platforms time_t is 64bits.

If that does not crash it, then gmtime likely gets junk and then returns null, at which point the testval = *localtime will crash on reading from a null pointer.

Upvotes: 3

ShadowRanger
ShadowRanger

Reputation: 155333

time_t on Linux (at least on my RHEL6 box) is a signed long, which will be 64 bits in size on a 64 bit build. You're passing the address of an uint32_t, which means gmtime is reading four garbage bytes, invoking undefined behavior.

Windows seems to default to a 64 bit time_t as well, but it has the option to make it use a 32 bit type at the expense of triggering the Y2038 bug eventually. Either way, it might just work on Windows by coincidence (after all, undefined behavior can include "works as expected").

When the value is huge garbage, gmtime can end up returning NULL, which will cause a segfault if you attempt to read it.

Upvotes: 3

Related Questions