dereferencing null
Chad J
chadjoan at __spam.is.bad__gmail.com
Sun Mar 4 23:50:25 PST 2012
On 03/05/2012 01:25 AM, Walter Bright wrote:
> On 3/4/2012 6:31 PM, Chad J wrote:
>> class Bar
>> {
>> int foo;
>> }
>>
>> void main()
>> {
>> Bar bar;
>> try {
>> bar.foo = 5;
>> } catch ( Exception e ) {
>> writefln("%s",e);
>> }
>> }
>>
>> DMD 2.057 on Gentoo Linux, compiled with "-g -debug". It prints this:
>> Segmentation fault
>>
>> Very frustrating!
>
> This is what I get (I added in an import std.stdio;):
>
> dmd foo -gc
> gdb foo
> GNU gdb (GDB) 7.2-ubuntu
> Copyright (C) 2010 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Reading symbols from /home/walter/cbx/mars/foo...done.
> (gdb) run
> Starting program: /home/walter/cbx/mars/foo
> [Thread debugging using libthread_db enabled]
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000401e45 in D main () at foo.d:13
> 13 bar.foo = 5;
> (gdb) bt
> #0 0x0000000000401e45 in D main () at foo.d:13
> #1 0x000000000040aa9b in rt.dmain2.main() ()
> #2 0x0000000000636010 in ?? ()
> #3 0x00007ffff7fdeae0 in ?? ()
> #4 0x00007fffffffeb30 in ?? ()
> #5 0x00007fffffffea00 in ?? ()
> #6 0x000000000040a41b in rt.dmain2.main() ()
> #7 0x0000000000000001 in ?? ()
> #8 0x0000000000000019 in ?? ()
> #9 0x0000000000636020 in ?? ()
> #10 0x00007fffffffeb30 in ?? ()
> #11 0x00007ffff7ffe4c0 in ?? ()
> #12 0x00007fffffffe8b0 in ?? ()
> #13 0x00007fffffffeb30 in ?? ()
> #14 0x00007fffffffea30 in ?? ()
> #15 0x000000000040aaee in rt.dmain2.main() ()
> #16 0x000000000040aa84 in rt.dmain2.main() ()
> #17 0x00007fffffffeb30 in ?? ()
> #18 0x00007fffffffea80 in ?? ()
> #19 0x000000000040a41b in rt.dmain2.main() ()
> #20 0x0000000000000001 in ?? ()
> #21 0x0000000000000019 in ?? ()
> #22 0x0000000000636020 in ?? ()
> #23 0x0000000000000001 in ?? ()
> #24 0x0000000000636020 in ?? ()
> #25 0x00007fffffffee01 in ?? ()
> #26 0x00007fffffffeb30 in ?? ()
> #27 0x00007fffffffeb30 in ?? ()
> #28 0x000000000040a3b3 in main ()
> (gdb)
>
> By running it under gdb (the debugger), it tells me what file and line
> it failed on, and gives a lovely stack trace.
>
> There really are only 3 gdb commands you need (and the only ones I
> remember):
>
> run (run your program)
> bt (print a backtrace)
> quit (exit gdb)
>
> Voila!
>
> Also, a null pointer exception is only one of a whole menagerie of
> possible hardware-detected errors. There's a limit on the compiler
> instrumenting code to detect these. At some point, it really is worth
> learning how to use the debugger.
Problems:
- I have to rerun the program in a debugger to see the stack trace.
This is a slow workflow. It's a big improvement if the segfault is hard
to find, but only a small improvement if the segfault is easy to find.
Very bad if I'm prototyping experimental code and I have a bunch to go
through.
- It only gives one line number. I imagine there's a way to get it to
spill the rest? At least it's the most important line number.
Nonetheless, I commonly encounter cases where the real action is
happening a few levels into the stack, which means I want to see ALL the
line numbers /at one time/.
- As I mentioned in another post, it is unreasonable to expect others to
run your programs in a debugger. I like it when my users can send me
stacktraces. (And they need to have ALL the line numbers displayed with
no extra coercion.) There are a number of occasions where I don't even
need to ask how to reproduce the bug, because I can just tell by looking
at the trace. Super useful!
- It doesn't seem to be possible to catch() these hardware errors. Booooo.
I wouldn't even expect ALL hardware errors to be instrumented in the
compiler. At least get the common ones. Null dereference is remarkably
common. I can't actually think of others I care about right now. Array
boundary errors and assertions already seem to have their own exceptions
now; they were great pests back in the day when this was not so. The
error messages could use a lot of work though. (Range Violation should
print the index used and the index boundaries, and simpler assertions
such as equality should print the values of their operands.)
I'm pretty sure other languages like C# and Java get this right.
Haven't used those two in a while though. Haxe... totally got this
right. Also Actionscript 3 by proxy. Hell, even Synergy/DE, the DIBOL
(!!) derivative that I use at work, /gets this right/. I get
stacktraces for null dereferences in these languages. It's /really/
convenient and useful. I consider D to be very backwards in this regard.
More information about the Digitalmars-d
mailing list