7

We have a code written in C that sometimes doesn’t handle zero pointers very well.

The code was originally written on Solaris and such pointers cause a segmentation fault. Not ideal but better than ploughing on.

Our experience is that if you read from a null pointer on AIX you get 0. If you use the xlc compiler you can add an option -qcheck=all to trap these pointers. But we use gcc (and want to continue using that compiler). Does gcc provide such an option?

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
justintime
  • 3,601
  • 4
  • 22
  • 37
  • 1
    What do you mean by "doesn’t handle zero pointers very well"? – Renan Greinert Jan 24 '12 at 16:30
  • 3
    Personally I consider all references to NULL (which technically is `0`) as bugs, and would add code to check for that instead of trusting the compiler to do it for me. Especially since the compiler don't know what I want to do if there is a `NULL` pointer? Sometimes it's okay to skip over the code accessing the pointer, sometimes it's a fatal error that needs to abort the program. – Some programmer dude Jan 24 '12 at 16:30
  • 1
    AFAIK dereferencing a NULL pointer leads to undefined behaviour. – Luca Martini Jan 24 '12 at 16:33
  • Seems that `xlc` has a `-qcheck=nullptr` option that *performs runtime checking of addresses contained in pointer variables used to reference storage. The address is checked at the point of use; a trap will occur if the value is less than 512.* Interesting. – ouah Jan 24 '12 at 16:37
  • 9
    You need to fix your code and stop trying to pretend that the problems can be fixed some other way. Don't de-reference the null pointer. End of story. – David Heffernan Jan 24 '12 at 16:43
  • If it uses the word NULL, then maybe you can define your own NULL, which points somewhere to a memory page which does not have either read or write access. You can map such page with mmap, and give protection rights by using mprotect. Also see this post about redefining NULL, http://stackoverflow.com/questions/5142251/redefining-null – MetallicPriest Jan 24 '12 at 16:50
  • @MetallicPriest: I thought of the same thing, but that would break any code that uses a `NULL` pointer in a boolean context. – Drew Dormann Jan 24 '12 at 16:57
  • 2
    Why do so many responses scold the OP about fixing his code? I read the question as asking if the compiler can be convinced to help with detecting bugs, not asking to have the compiler 'fix' or hide problems (a trap doesn't exactly hide a problem). – Michael Burr Jan 24 '12 at 19:46
  • Also, you may need `-fno-delete-null-pointer-checks` – ninjalj Jan 24 '12 at 19:59
  • (A note: historically, AIX-kernel starts at address zero. You can read from it via NULL-pointer, but at least you cannot write into.) – Lorinczy Zsigmond Feb 11 '16 at 06:28

2 Answers2

7

Does gcc provide such an option?

I'm sheepishly volunteering the answer no, it doesn't. Although I can't cite the absence of information regarding gcc and runtime NULL checks.

The problem you're tackling is that you're trying to make undefined behavior a little more defined in a program that's poorly-written.

I recommend that you bite the bullet and either switch to xlc or manually add NULL checks to the code until the bad behavior has been found and removed.

Consider:

  • Making a macro to null-check a pointer
  • Adding that macro after pointer assignments
  • Adding that macro to the entry point of functions that accept pointers

As bugs are removed, you can begin to remove these checks.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
4
  1. Please do us all a favor and add proper NULL checks to your code. Not only will you have a slight gain in performance by checking for NULL only when needed, rather than having the compiler perform the check everywhere, but your code will be more portable to other platforms.

    And let's not mention the fact that you will be more likely to print a proper error message rather than have the compiler drop some incomprehensible stack dump/source code location/error code that will not help your users at all.

  2. AIX uses the concept of a NULL page. Essentially, NULL (i.e. virtual address 0x0) is mapped to a location that contains a whole bunch of zeros. This allows string manipulation code e.t.c. to continue despite encountering a NULL pointer.

    This is contrary to most other Unix-like systems, but it is not in violation of the C standard, which considers dereferencing NULL an undefined operation. In my opinion, though, this is woefully broken: it takes an application that would crash violently and turns it into one that ignores programming errors silently, potentially producing totally incorrect results.

  3. As far as I know, GCC has no options to work around fundamentally broken code. Even historically supported patterns, such as writable string literals, have been slowly phased out in newer GCC versions.

    There might be some support when using memory debugging options such as -fmudflap, but I don't really know - in any case you should not use debugging code in production systems, especially for forcing broken code to work.

Bottom line: I don't think that you can avoid adding explicit NULL checks.

Unfortunately we now come to the basic question: Where should the NULL checks be added?. I suppose having the compiler add such checks indiscriminately would help, provided that you add an explicit check when you discover an issue.

Unfortunately, there is no Valgrind support for AIX. If you have the cash, you might want to have a look at IBM Rational Purify Plus for AIX - it might catch such errors.

It might also be possible to use xlc on a testing system and gcc for everything else, but unfortunately they are not fully compatible.

thkala
  • 84,049
  • 23
  • 157
  • 201