Re: [PATCH] *(int*)0 = 0 & variations

Jeff Garzik (jgarzik@pobox.com)
Wed, 23 Jun 1999 20:33:39 -0400


Riley Williams wrote:
>
> Hi Jeff.
>
> > assert should definitely be more informative, and an assertion
> > failure is more than a debug statement. The following functions
> > more like the userland version:
>
> > #ifndef NDEBUG
> > # define kassert(cond) \
> > if (!(cond)) { \
> > printk (KERN_ERR "kassert failed in function %s, file %s, line %d:
> > %s\n", \
> > __FUNCTION__, \
> > __FILE__, \
> > __LINE__, \
> > __STRING(cond)); \
> > *(int*)0 = 0; \
> > }
> > #else
> > # define kassert(cond)
> > #endif
>
> > You could put some additional switches in there to enable or
> > disable the oops after the printk, or to change KERN_ERR to
> > something else.
>
> I would suggest you think about the context in which kassert would be
> used before implementing the above in the kernel. Perhaps I can point
> out some relevant issues that you appear to have overlooked:
>
> 1. Whatever the assertion that failed, the kernel NEEDS to keep
> running. Therefore, an OOPS is usually NOT appropriate.

Personally I disagree, but I do agree that for the general population
you are right.

How about a switch in kassert.h that optionally causes an oops? If you
wanted to get really fancy, take that print-backtrace code that someone
posted in this thread, and use that before _optionally_ killing the
kernel.

> 2. You state that an "assertion failure is more than a debug
> statement" without providing any explanation for your claim.
> As I see it, and taking kassert in its purest way, its ONLY
> purpose is debugging, and it is thus ideal for KERN_DEBUG.

If an assertion fails something is REALLY WRONG, and should be printed
out as a kernel message. The most typical use I've seen for assertions
is to warn if a null pointer if about to be dereferenced, and you
definitely want to make that known. loudly.

Assertions should NOT occur, even in debug kernels. An assertion is not
a FIXME. Failure of an assertion means the impossible just occured.

> 3. As far as actually seeing the error reports are concerned,
> the majority of users would have NO idea what to do if some
> application started spewing "assertion failure" messages all
> over their screen, so using a reporting level that is often
> set up to spew all suchlike messages to all logged in users
> is not a particularly good idea.

They will report it as a bug report like a good little user.

> 4. The way that I would see such a facility used is for users
> with enough interest to help with the kernel to set up their
> system such that KERN_DEBUG errors get logged to a specific
> file, which would then serve as a central repository for ALL
> kernel debugging messages.
>
> The default setting, used by the majority of the users (who have
> no interest in debugging Linux) being that suchlike messages are
> logged in either /var/log/messages or in /dev/null as preferred.

I disagree, see above. Assertion failures are very important.

> 5. The choice of '#ifndef NDEBUG' or '#ifdef DEBUG' matters, as the
> two forms have different implications. Personally, I believe the
> latter has the correct implication in the kernel context, but the
> former has the correct implication in an application context:
>
> '#ifndef NDEBUG' sayd "Disable debugging only if the variable
> NDEBUG is defined", thus implying that the normal case is WITH
> debugging.
>
> '#ifdef DEBUG' says "Enable debugging only if the variable DEBUG
> is defined", thus implying that the normal case will be without
> debugging.

I know.

I, and the C designers, used '#ifndef NDEBUG' on purpose.

> 6. Whilst the format of the userland version is interesting, it is
> not necessarily a useful guide to the format the kernel version
> should take. Remember that both the circumstances of its use and
> the results thereof are considerably different.
>
> For these reasons, and taking into account the various comments made
> so far, I would suggest the following patch instead:

Does this print out the expression correctly?? I would think that this
is more correct:

#define kassert(cond)
if (!cond)
printf("assertion '" #cond "' failed\n");

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/