3

I am attempting to fix a build error.

The offending line of code is as follows:

fprintf(crashLog, "RIP: %lX\n", context->uc_mcontext.gregs[REG_RIP]);

And hence:

  • gregs is of type gregset_t
  • gregs[i] is of type greg_t

Now this code (which is for producing a core dump and stack trace) has been working for a very long time, but recently, GCC 4.7.3 (Ubuntu 13.04) has started to reject it:

error: format ‘%lX’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘greg_t {aka long long int}’ [-Werror=format]

Fine. So I change the offending line to:

fprintf(crashLog, "RIP: %llX\n", context->uc_mcontext.gregs[REG_RIP]);

But GCC 4.6.3 (Ubuntu 12.04) complains instead:

error: format ‘%llX’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘greg_t {aka long int}’ [-Werror=format]

There's already ifdef's in this section of code for the various registers, so I can add another, but is there a nice clean way to do this (especially without needing the extra ifdef)?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Damien
  • 785
  • 3
  • 8
  • 18
  • Is the typedef directly to a base type like that, or is there a `uintN_t` or `intptr_t` or something like that in between somewhere? – Carl Norum May 21 '13 at 22:31
  • Just cast it to `unsigned long long` for the `printf`? – Daniel Fischer May 21 '13 at 22:34
  • It seems to correspond to neither a specific intptr_t type, nor a specific uintN_t type. I'd rather not cast it to something because there is probably a reason why there are the different widths. Afterthought: As far as I can gather, greg_t is a kernel defintion, not something from GCC. Hence, the difference in GCC versions may be a red herring.... time to investigate. – Damien May 21 '13 at 22:51
  • .... OK. in glibc is where greg_t is defined for gcc 4.7: /* Type for general register. */ __extension__ typedef long long int greg_t; /* Number of general registers. */ #define NGREG 23 /* Container for all general registers. */ typedef greg_t gregset_t[NGREG]; – Damien May 21 '13 at 22:54
  • @Damien IMO, `unsigned long long` is required for exotic LLP64 systems (WINDOWS only?), for example if you compile for a w64 mingw target... Since it's for printing registers, intptr_t should work on most platforms. – aka.nice Oct 20 '19 at 21:04

0 Answers0