Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #60799 > unrolled thread

Null Pointer exceptions

Started byjeff <nospam@nospam.com>
First post2015-04-22 21:34 +0000
Last post2015-04-23 12:32 -0400
Articles 12 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Null Pointer exceptions jeff <nospam@nospam.com> - 2015-04-22 21:34 +0000
    Re: Null Pointer exceptions James Kuyper <jameskuyper@verizon.net> - 2015-04-22 18:02 -0400
      Re: Null Pointer exceptions Stephen Sprunk <stephen@sprunk.org> - 2015-04-22 18:30 -0500
        Re: Null Pointer exceptions James Kuyper <jameskuyper@verizon.net> - 2015-04-22 19:44 -0400
          Re: Null Pointer exceptions Stephen Sprunk <stephen@sprunk.org> - 2015-04-23 11:53 -0500
            Re: Null Pointer exceptions Richard Heathfield <rjh@cpax.org.uk> - 2015-04-23 18:59 +0100
    Re: Null Pointer exceptions Barry Schwarz <schwarzb@dqel.com> - 2015-04-22 15:17 -0700
      Re: Null Pointer exceptions James Dow Allen <gmail@jamesdowallen.nospam> - 2015-04-23 04:11 +0000
    Re: Null Pointer exceptions Robert Wessel <robertwessel2@yahoo.com> - 2015-04-22 17:19 -0500
    Re: Null Pointer exceptions Ben Bacarisse <ben.lists@bsb.me.uk> - 2015-04-22 23:46 +0100
    Re: Null Pointer exceptions Nobody <nobody@nowhere.invalid> - 2015-04-23 03:14 +0100
      Re: Null Pointer exceptions James Kuyper <jameskuyper@verizon.net> - 2015-04-23 12:32 -0400

#60799 — Null Pointer exceptions

Fromjeff <nospam@nospam.com>
Date2015-04-22 21:34 +0000
SubjectNull Pointer exceptions
Message-ID<mh9451$ib4$1@speranza.aioe.org>
Howdy

I've got a large C codebase that frequently triggers bugs where pointers 
that shouldn't be null, somehow end up getting nulled.

It's easy enough to fix up each individual bug when it gets reported, 
just by adding a null check:

if
((void*) ptr != (void*)NULL)
{
        // existing code that triggered a crash
}

However, as these null conditions only show up occasionally, there always 
seem to be more bugs left to find.

My question is: is there a way to deal with all of these problems in one 
swoop, by ignoring all code that dereferences a null pointer, i.e. null 
dereference becomes a NO-OP instead of triggering an exception. ?

Respectfully,
jeff

[toc] | [next] | [standalone]


#60807

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-04-22 18:02 -0400
Message-ID<55381A74.3000107@verizon.net>
In reply to#60799
On 04/22/2015 05:34 PM, jeff wrote:
> Howdy
> 
> I've got a large C codebase that frequently triggers bugs where pointers 
> that shouldn't be null, somehow end up getting nulled.
> 
> It's easy enough to fix up each individual bug when it gets reported, 
> just by adding a null check:
> 
> if
> ((void*) ptr != (void*)NULL)
> {
>         // existing code that triggered a crash
> }
> 
> However, as these null conditions only show up occasionally, there always 
> seem to be more bugs left to find.
> 
> My question is: is there a way to deal with all of these problems in one 
> swoop, by ignoring all code that dereferences a null pointer, i.e. null 
> dereference becomes a NO-OP instead of triggering an exception. ?

Every time a pointer that shouldn't be null gets dereferenced, you
should investigate to find out why it was null. Don't simply patch over
the problem by checking whether it is null - find out why it was
unexpectedly null. Fix that problem. Then look for other similar
problems - if this problem comes up repeatedly, you've probably made the
same kind of mistake (whatever that mistake might be) in many different
location.
You'll never get anywhere with debugging your code if you concentrate
your efforts on covering up symptoms, rather than tracking down causes.
You're like a doctor who sees a patient coughing up blood, and
concentrates his attention on cleaning up the blood. A proper doctor
need to figure out why the patient is bleeding internally before the
doctor can put a stop to it, otherwise the bleeding will just continue
until the patient dies as a result.

[toc] | [prev] | [next] | [standalone]


#60830

FromStephen Sprunk <stephen@sprunk.org>
Date2015-04-22 18:30 -0500
Message-ID<mh9at9$q53$1@dont-email.me>
In reply to#60807
On 22-Apr-15 17:02, James Kuyper wrote:
> On 04/22/2015 05:34 PM, jeff wrote:
>> My question is: is there a way to deal with all of these problems
>> in one swoop, by ignoring all code that dereferences a null
>> pointer, i.e. null dereference becomes a NO-OP instead of
>> triggering an exception. ?
> 
> Every time a pointer that shouldn't be null gets dereferenced, you 
> should investigate to find out why it was null. Don't simply patch
> over the problem by checking whether it is null - find out why it
> was unexpectedly null. Fix that problem. Then look for other similar 
> problems - if this problem comes up repeatedly, you've probably made
> the same kind of mistake (whatever that mistake might be) in many
> different location. You'll never get anywhere with debugging your
> code if you concentrate your efforts on covering up symptoms, rather
> than tracking down causes. You're like a doctor who sees a patient
> coughing up blood, and concentrates his attention on cleaning up the
> blood. A proper doctor need to figure out why the patient is bleeding
> internally before the doctor can put a stop to it, otherwise the
> bleeding will just continue until the patient dies as a result.

Figuring out the cause (and treating it) takes time, and if you do
nothing for the symptoms in the meantime, the patient may die anyway.
If no cure exists for the particular disease, then all you can do is
manage the symptoms.

For unreproducible bugs, managing the symptoms may be the only option
because you don't have enough data (or time) to find the root cause.
You can add some sanity checks and maybe some extra logging in case it
happens again, but then you move on to the next bug in the queue.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#60831

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-04-22 19:44 -0400
Message-ID<5538327A.2090208@verizon.net>
In reply to#60830
On 04/22/2015 07:30 PM, Stephen Sprunk wrote:
> On 22-Apr-15 17:02, James Kuyper wrote:
...
>> than tracking down causes. You're like a doctor who sees a patient
>> coughing up blood, and concentrates his attention on cleaning up the
>> blood. A proper doctor need to figure out why the patient is bleeding
>> internally before the doctor can put a stop to it, otherwise the
>> bleeding will just continue until the patient dies as a result.
> 
> Figuring out the cause (and treating it) takes time, and if you do
> nothing for the symptoms in the meantime, the patient may die anyway.

True - symptoms do need to be treated - but that should generally not be
the only thing you do about them.

At a minimum, you should seek a diagnosis. The diagnosis might indicate
that there is no need for anything more than symptomatic relief, or it
might indicated that there is no known cure, in which case symptomatic
relief is the best you can do - but it could also identify a treatment
plan that should be put into effect as soon as possible. Until you at
least attempt diagnosis, you can't be sure which of those cases apply.

> If no cure exists for the particular disease, then all you can do is
> manage the symptoms.

Granted - but seldom completely relevant to computer bugs. Almost all
computer bugs are solvable, once you identify them sufficiently well -
the hard part is identifying them.

[toc] | [prev] | [next] | [standalone]


#60916

FromStephen Sprunk <stephen@sprunk.org>
Date2015-04-23 11:53 -0500
Message-ID<mhb818$on$1@dont-email.me>
In reply to#60831
On 22-Apr-15 18:44, James Kuyper wrote:
> On 04/22/2015 07:30 PM, Stephen Sprunk wrote:
>> On 22-Apr-15 17:02, James Kuyper wrote:
>>> You're like a doctor who sees a patient coughing up blood, and
>>> concentrates his attention on cleaning up the blood. A proper
>>> doctor need to figure out why the patient is bleeding internally
>>> before the doctor can put a stop to it, otherwise the bleeding
>>> will just continue until the patient dies as a result.
>> 
>> Figuring out the cause (and treating it) takes time, and if you do 
>> nothing for the symptoms in the meantime, the patient may die
>> anyway.
> 
> True - symptoms do need to be treated - but that should generally not
> be the only thing you do about them.
> 
> At a minimum, you should seek a diagnosis. The diagnosis might
> indicate that there is no need for anything more than symptomatic
> relief, or it might indicated that there is no known cure, in which
> case symptomatic relief is the best you can do - but it could also
> identify a treatment plan that should be put into effect as soon as
> possible. Until you at least attempt diagnosis, you can't be sure
> which of those cases apply.

Of course; that's why I said "in the meantime".

>> If no cure exists for the particular disease, then all you can do
>> is manage the symptoms.
> 
> Granted - but seldom completely relevant to computer bugs. Almost
> all computer bugs are solvable, once you identify them sufficiently
> well - the hard part is identifying them.

Indeed, and that was the point behind the following paragraph that
discussed unreproducible bugs.

My experience is that if we can reproduce a bug, we can almost certainly
fix it--and usually with very little effort unless it requires a design
change.  However, if we can't reproduce a bug, it's much more likely we
can't fix it--and even if we try, we can't be sure we actually did so.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#60921

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-04-23 18:59 +0100
Message-ID<mhbbrf$g49$1@dont-email.me>
In reply to#60916
On 23/04/15 17:53, Stephen Sprunk wrote:

<snip>

> My experience is that if we can reproduce a bug, we can almost certainly
> fix it--and usually with very little effort unless it requires a design
> change.  However, if we can't reproduce a bug, it's much more likely we
> can't fix it--and even if we try, we can't be sure we actually did so.

Unreproducible bugs /tend/ to be pointer- or array-related. That is not, 
of course, universally true, but it can be (forgive me) a pointer in the 
right direction.

If I can't reproduce a bug, I'll try to do the next best thing, which is 
to look for "clever" code. The chances are good that it isn't as clever 
as it likes to make out. It is, at least, a starting point.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#60812

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-04-22 15:17 -0700
Message-ID<7a7gjahajc3j6f83u69g6aoon25us5vptv@4ax.com>
In reply to#60799
On Wed, 22 Apr 2015 21:34:25 +0000 (UTC), jeff <nospam@nospam.com>
wrote:

>Howdy
>
>I've got a large C codebase that frequently triggers bugs where pointers 
>that shouldn't be null, somehow end up getting nulled.
>
>It's easy enough to fix up each individual bug when it gets reported, 
>just by adding a null check:
>
>if
>((void*) ptr != (void*)NULL)
>{
>        // existing code that triggered a crash
>}

As has been mentioned, this fixes nothing and serves only to
camouflage the problem.

But on the rare occasion when this is the "proper" approach, what is
with those useless casts?

>However, as these null conditions only show up occasionally, there always 
>seem to be more bugs left to find.
>
>My question is: is there a way to deal with all of these problems in one 
>swoop, by ignoring all code that dereferences a null pointer, i.e. null 
>dereference becomes a NO-OP instead of triggering an exception. ?

The way to deal with the problems is to perform a proper evaluation of
the code and correct the design/coding errors that allow the situation
to occur in the first place.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#60837

FromJames Dow Allen <gmail@jamesdowallen.nospam>
Date2015-04-23 04:11 +0000
Message-ID<XnsA48571C3C132Ajamesdowallen@178.63.61.175>
In reply to#60812
Barry Schwarz <schwarzb@dqel.com> might have writ, in 
news:7a7gjahajc3j6f83u69g6aoon25us5vptv@4ax.com:
> As has been mentioned, this fixes nothing and serves only to
> camouflage the problem.

Yes.

[true anecdote] Twenty-six years ago I was a consultant to Sun 
Microsystems charged with investigating I/O performance problems.  A new 
SCSI feature allowed multiple drives to interleave data on the same 
cable, but customers complained that they weren't getting the expected 
performance boost.  Sure enough, I saw that when attempting concurrent 
accesses, a few would occur and then the system would drop down to one-
at-a-time scheduling.

I traced the problem to a line in the SCSI device driver:
       if (ctrlp != NULL)
             start_whatever(ctrlp);
I didn't know why ctrlp had gone NULL in the hugely complicated driver 
but I set ctrlp to point to the controller structure, called 
start_whatever(), and got the expected performance boost.

I left the details of the fix (why was ctrlp null anyway???) to one of 
the several guys on the SCSI device driver team.  (I don't recall his 
name; I think he was a young guy with blong hair).

James Dow Allen

[toc] | [prev] | [next] | [standalone]


#60814

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-04-22 17:19 -0500
Message-ID<ru6gjad6sm3l0694qb2ju68chg40m4goj6@4ax.com>
In reply to#60799
On Wed, 22 Apr 2015 21:34:25 +0000 (UTC), jeff <nospam@nospam.com>
wrote:

>Howdy
>
>I've got a large C codebase that frequently triggers bugs where pointers 
>that shouldn't be null, somehow end up getting nulled.
>
>It's easy enough to fix up each individual bug when it gets reported, 
>just by adding a null check:
>
>if
>((void*) ptr != (void*)NULL)
>{
>        // existing code that triggered a crash
>}
>
>However, as these null conditions only show up occasionally, there always 
>seem to be more bugs left to find.
>
>My question is: is there a way to deal with all of these problems in one 
>swoop, by ignoring all code that dereferences a null pointer, i.e. null 
>dereference becomes a NO-OP instead of triggering an exception. ?


Short answer: no.

Longer answer: that's would not actually be fixing the problem, just
patching around the symptom.  Either the caller is broken, in that
it's passing a null pointer to a a routine that requires a valid
pointer, or the routine is broken in it's handling of a null pointer
as an input (and the simplistic fix you illustrated above may or may
not actually fix the problem, and quite possibly may introduce further
problems), or the interface is underspecified when it comes to
handling null pointers.

IOW, you have bugs in your program, the correct solution is to fix
them, rather than attempting to patch the symptoms.

Ugly answer: you might be able to write highly platform specific code
that intercepts the abend, attempts to patch things up, and resumes
the code.  That's been attempted many times, the usual end results are
terrible (after a few months or years you discover that while you have
been blissfully free of abends, your database is now hopelessly
corrupted, turning a nuisance into an existential crisis).

[toc] | [prev] | [next] | [standalone]


#60822

FromBen Bacarisse <ben.lists@bsb.me.uk>
Date2015-04-22 23:46 +0100
Message-ID<87r3rb93xm.fsf@bsb.me.uk>
In reply to#60799
jeff <nospam@nospam.com> writes:

> I've got a large C codebase that frequently triggers bugs where pointers 
> that shouldn't be null, somehow end up getting nulled.
>
> It's easy enough to fix up each individual bug when it gets reported, 
> just by adding a null check:
>
> if
> ((void*) ptr != (void*)NULL)

if (ptr != NULL) is enough.  You don't need the casts.  In fact,
if (ptr) is enough, though some consider that too terse.

> {
>         // existing code that triggered a crash
> }
>
> However, as these null conditions only show up occasionally, there always 
> seem to be more bugs left to find.

This sounds very odd.  You aren't fixing bugs, you are patching up the
effect of bugs.  Putting sticking plasters on a gaping wound comes to
mind.

> My question is: is there a way to deal with all of these problems in one 
> swoop, by ignoring all code that dereferences a null pointer, i.e. null 
> dereference becomes a NO-OP instead of triggering an exception. ?

I don't think should not be considering that sort of thing at all.
There is almost certainly some other underlying problem that needs to be
fixed.  The pointers should not be null, you say, and you don't know why
they become null, so that's where the effort needs to go -- finding out
why, and stopping it.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#60836

FromNobody <nobody@nowhere.invalid>
Date2015-04-23 03:14 +0100
Message-ID<pan.2015.04.23.02.14.12.829000@nowhere.invalid>
In reply to#60799
On Wed, 22 Apr 2015 21:34:25 +0000, jeff wrote:

> My question is: is there a way to deal with all of these problems in one 
> swoop, by ignoring all code that dereferences a null pointer, i.e. null 
> dereference becomes a NO-OP instead of triggering an exception. ?

In a sense, existing mechanisms already ignore "all code that dereferences
a null pointer", i.e. they terminate the process, resulting in the code
(i.e. the remainder of the program) being ignored. Maybe you meant to
suggest that it should ignore some smaller portion of the code? In which
case: which portion? How should the implementation determine that?

As for treating null dereference as a no-op: how can it? Pointer
dereference yields a value; what value should dereferencing a null pointer
yield? Just use whatever value happened to already be in the memory (or
register)? That's likely to just result in cascading failures; if the
value is itself a pointer, offset or index (or is used in the calculation
of such), you're going to end up accessing random memory locations.

And simply testing for a null pointer and conditionalising code which
depends upon the value obtained by dereferencing is often a workaround
rather than a fix. If null isn't a legitimate value, any fix would deal
with the reasons why the pointer was null, not the consequences.

[toc] | [prev] | [next] | [standalone]


#60914

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-04-23 12:32 -0400
Message-ID<55391E84.9020703@verizon.net>
In reply to#60836
On 04/22/2015 10:14 PM, Nobody wrote:
> On Wed, 22 Apr 2015 21:34:25 +0000, jeff wrote:
> 
>> My question is: is there a way to deal with all of these problems in one 
>> swoop, by ignoring all code that dereferences a null pointer, i.e. null 
>> dereference becomes a NO-OP instead of triggering an exception. ?
> 
> In a sense, existing mechanisms already ignore "all code that dereferences
> a null pointer", i.e. they terminate the process, resulting in the code
> (i.e. the remainder of the program) being ignored. Maybe you meant to
> suggest that it should ignore some smaller portion of the code? ...

He seemed quite specific to me: "null dereference becomes a NO-OP".
That's a very small portion of the code, often just a single instruction.

...
> As for treating null dereference as a no-op: how can it? ...

Well, the following seems the obvious interpretation of what he's saying:

> ... Just use whatever value happened to already be in the memory (or
> register)? That's likely to just result in cascading failures; if the
> value is itself a pointer, offset or index (or is used in the calculation
> of such), you're going to end up accessing random memory locations.

If that bothered him (as it should) he wouldn't be asking this question.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web