Re: dereferencing null

2012-03-05 Thread Nick Sabalausky
"Walter Bright"  wrote in message 
news:jj32l2$1dk$1...@digitalmars.com...
> On 3/5/2012 4:27 AM, Jacob Carlborg wrote:
>> On 2012-03-05 11:38, Walter Bright wrote:
>>> Notably, C and C++ do not do what you suggest.
>>
>> Just because C and C++ do something in a certain way doesn't make it a 
>> valid
>> reason to do the same thing in D.
>>
>> I think this is an argument we need to stop using immediately. It just 
>> shows
>> we're stuck in our ways, can't innovate and can't think for our self.
>
>
> Doing things differently than well established practice requires a strong 
> reason. There are often good reasons for that established practice that 
> aren't obvious.
>

Ok, then what's the strong reason for abandoning the practice here that's 
been well established by damn near everying other than C/C++?




Re: dereferencing null

2012-03-05 Thread H. S. Teoh
On Mon, Mar 05, 2012 at 06:12:43PM +0100, Andrej Mitrovic wrote:
[...]
> Also, I find your message signatures amusing. :P

I have a file of amusing quotes that I collected over the years from
various sources (including some not-so-funny ones I made up myself), and
a 1-line perl script hooked to my Mutt compose function that randomly
selects a quote and puts it on my signature line.  Once in a while it
can coincidentally pick a quote relevant to the actual discussion in the
message body, which makes it even funnier.


T

-- 
Laissez-faire is a French term commonly interpreted by Conservatives to
mean 'lazy fairy,' which is the belief that if governments are lazy
enough, the Good Fairy will come down from heaven and do all their work
for them.


Re: dereferencing null

2012-03-05 Thread H. S. Teoh
On Mon, Mar 05, 2012 at 11:06:40AM -0800, Walter Bright wrote:
> On 3/5/2012 8:07 AM, H. S. Teoh wrote:
> >A "file not found" exception should tell you what the offending filename is.
> 
> std.file.read("adsfasdf") gives:
> 
> std.file.FileException@std\file.d(305): adsfasdf: The system cannot
> find the file specified.

That's good to know. I just picked "file not found" as my favorite
whipping boy. :-) Now we just need this consistently across all the
standard exceptions. The including the wrong parameter part, not the
whipping part.


T

-- 
Today's society is one of specialization: as you grow, you learn more
and more about less and less. Eventually, you know everything about
nothing.


Re: dereferencing null

2012-03-05 Thread Walter Bright

On 3/5/2012 8:07 AM, H. S. Teoh wrote:

A "file not found" exception should tell you what the offending filename is.


std.file.read("adsfasdf") gives:

std.file.FileException@std\file.d(305): adsfasdf: The system cannot find the 
file specified.


Re: dereferencing null

2012-03-05 Thread Walter Bright

On 3/5/2012 4:27 AM, Jacob Carlborg wrote:

On 2012-03-05 11:38, Walter Bright wrote:

Notably, C and C++ do not do what you suggest.


Just because C and C++ do something in a certain way doesn't make it a valid
reason to do the same thing in D.

I think this is an argument we need to stop using immediately. It just shows
we're stuck in our ways, can't innovate and can't think for our self.



Doing things differently than well established practice requires a strong 
reason. There are often good reasons for that established practice that aren't 
obvious.




Re: dereferencing null

2012-03-05 Thread deadalnix

Le 05/03/2012 15:26, Steven Schveighoffer a écrit :

On Fri, 02 Mar 2012 10:19:13 -0500, deadalnix  wrote:


Le 02/03/2012 15:37, Jacob Carlborg a écrit :

Isn't it quite unsafe to throw an exception in a signal ?


One does not need to throw an exception. Just print a stack trace. I've
advocated for this multiple times. I agree it costs nothing to
implement, and who cares about safety when the app is about to crash?!


The signal handler is called on top of the stack, but the information
to retrieve the stack trace are system dependant. BTW, using lib like
libsigsegv can help a lot to make it safe. It isn't safe ATM, but it
is doable.


libsigsegv is used to perform custom handling of page faults (e.g.
loading pages of memory from a database instead of the MMC). You do not
need libsigsegv to handle SEGV signals.

-Steve


No you don't, but if you want to know if you are facing a stackoverflow 
or a null deference for exemple, this greatly help the implementation.


Re: dereferencing null

2012-03-05 Thread Andrej Mitrovic
On 3/5/12, H. S. Teoh  wrote:


Yep, agreed with everything you've said.

Also, I find your message signatures amusing. :P


Re: dereferencing null

2012-03-05 Thread Adam D. Ruppe

On Monday, 5 March 2012 at 06:19:53 UTC, Chad J wrote:

That's cool.  Maybe someone should stick it in Phobos?


I just made a patch and sent it up. It'll have to be
reviewed by the others, but I expect we'll have something
in std.typecons for the next release.


I also didn't know about @disabled; that's a nifty addition.


Yeah, we brought it up one of the previous null
discussions, and Walter+Andrei liked it as a general
solution to enable this and other checks, like ranged
integers.

Still somewhat new, though; havn't realized all its
potential yet.


Re: dereferencing null

2012-03-05 Thread H. S. Teoh
On Mon, Mar 05, 2012 at 02:30:14PM +0100, Andrej Mitrovic wrote:
> Personally I'd love to get more info about out-of-bounds errors. E.g.
> for arrays, which index the code attempted to access, and for hashes
> which key.

Personally, I'd love to see D's added string capabilities put to good
use in *all* exception messages. It's been how many decades since the
first C compiler was written? Yet we still haven't moved on from using
static strings in Exceptions. This is silly. A "file not found"
exception should tell you what the offending filename is. It's as simple
as:

throw new IOException("File '%s' not found".format(filename));

A range violation should say what the offending index was:

[...]
> enforce(key in aa, new RangeError(format(": Key %s not in hash. ", key)));
[...]
> core.exception.RangeError@: Key 1 not in hash. (20): Range violation

A numerical conversion error should say what the offending malformed
number was. Or at least, include the non-digit character that it choked
on.

A syntax error in getopt should tell you what the offending option was.
(How'd you like it if you ran some random program, and it says "command
line error" with no indication at all of what the error was?)

It's pure common sense. I mean, if the only message dmd ever gave was
"syntax error" without telling you *what* caused the syntax error or
*where* (file, line number, perhaps column), we'd all be beating down
Walter's door. So why should exceptions in other applications be any
different?


T

-- 
The volume of a pizza of thickness a and radius z can be described by
the following formula: pi zz a. -- Wouter Verhelst


Re: dereferencing null

2012-03-05 Thread H. S. Teoh
On Mon, Mar 05, 2012 at 02:50:25AM -0500, Chad J wrote:
[...]
> Problems:
> - I have to rerun the program in a debugger to see the stack trace.

Nope. You can run it on a dumped core.


[...]
> - 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/.

I use gdc, and it gives a full stack trace with line numbers on pretty
much every line.


> - 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!
[...]

I guess it depends on your customer base. The customers *my* company
deals with are unlikely to give any more info than "it crashed". (Worse
yet, they have rather odd definitions for the word "crash". I've seen an
actual case where somebody called an unexpected behaviour a "crash",
when it was actually a *correct* program response to wrong user input.)
Most of them have no idea what a stacktrace is... to them it's just some
meaningless crap the computer spews out when something goes wrong --
something you want to get off the screen, out of sight, out of mind,
ASAP.  They have no concept that *somebody* might actually find this
"meaningless" info useful.


T

-- 
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.


Re: dereferencing null

2012-03-05 Thread Steven Schveighoffer

On Fri, 02 Mar 2012 10:19:13 -0500, deadalnix  wrote:


Le 02/03/2012 15:37, Jacob Carlborg a écrit :

Isn't it quite unsafe to throw an exception in a signal ?


One does not need to throw an exception.  Just print a stack trace.  I've  
advocated for this multiple times.  I agree it costs nothing to implement,  
and who cares about safety when the app is about to crash?!


The signal handler is called on top of the stack, but the information to  
retrieve the stack trace are system dependant. BTW, using lib like  
libsigsegv can help a lot to make it safe. It isn't safe ATM, but it is  
doable.


libsigsegv is used to perform custom handling of page faults (e.g. loading  
pages of memory from a database instead of the MMC).  You do not need  
libsigsegv to handle SEGV signals.


-Steve


Re: dereferencing null

2012-03-05 Thread Andrej Mitrovic
Personally I'd love to get more info about out-of-bounds errors. E.g.
for arrays, which index the code attempted to access, and for hashes
which key.

Sure it's easy to use an enforce, but I'd rather have that inserted in
debug builds with bounds checking anyway. For example:

void main()
{
int[int] aa;
int key = 1;
auto a = aa[key];
}

core.exception.RangeError@test(22): Range violation

That's not too much information (well there's also that stacktrace
which is still broken on XP regardless of dbghelp.dll). This is
better:

import std.exception;
import core.exception;

void main()
{
int[int] aa;
int key = 1;
enforce(key in aa, new RangeError(format(": Key %s not in hash. ", key)));
auto a = aa[key];
}

core.exception.RangeError@: Key 1 not in hash. (20): Range violation

I'd rather not have to depend on debuggers or code duplication (even
mixins) for this basic information.

Side-note: RangeError is missing a constructor that takes a *message*
as the first parameter, the one that was called takes a file string
parameter. With the ctor fixed the error becomes:
core.exception.RangeError@test.d(20): Range violation: Key 1 not in hash.

That would help me so much without having to change code, recompile,
and then wait 20 seconds at runtime to reach that failing test again.


Re: dereferencing null

2012-03-05 Thread Martin Nowak
On Mon, 05 Mar 2012 10:43:22 +0100, David Nadlinger   
wrote:



On Monday, 5 March 2012 at 09:09:30 UTC, Jacob Carlborg wrote:

On 2012-03-05 07:25, Walter Bright wrote:

[…]
run (run your program)
bt (print a backtrace)
quit (exit gdb)
[…]

Is demangling supposed to work on Mac OS X?


As the D demangling support was added in GDB 7.,  
unfortunately no, as Apple ships an ancient (customized) version.


David


From GDB7.3 OSX MACH-O support is somewhat fixed, but it's buggy when being
used with dmd because it doesn't relocate the "__textcoal_nt" sections.


Re: dereferencing null

2012-03-05 Thread Jacob Carlborg

On 2012-03-05 11:38, Walter Bright wrote:

On 3/4/2012 11:50 PM, Chad J wrote:

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.


Notably, C and C++ do not do what you suggest.


Just because C and C++ do something in a certain way doesn't make it a 
valid reason to do the same thing in D.


I think this is an argument we need to stop using immediately. It just 
shows we're stuck in our ways, can't innovate and can't think for our self.


--
/Jacob Carlborg


Re: dereferencing null

2012-03-05 Thread deadalnix

Le 03/03/2012 21:10, Timon Gehr a écrit :

On 03/03/2012 09:00 PM, deadalnix wrote:

Le 03/03/2012 20:06, Walter Bright a écrit :

On 3/3/2012 2:13 AM, bearophile wrote:

Walter:


Adding in software checks for null pointers will dramatically slow
things
down.


Define this use of "dramatically" in a more quantitative and objective
way,
please. Is Java "dramatically" slower than C++/D here?


You can try it for yourself. Take some OOP code of yours, and insert a
null check in front of every dereference of the class handle.


Why would you want to check every time ? You program will get a signal
from the system if it try to deference a null pointer, so thing can be
done in the signal handler, and no cost is involved.


The signal will likely be the same for the following two code snippets:

void main(){
Object o;
o.toString();
}

void main(){
*cast(int*)0xDEADBEEF = 1337;
}


How to detect whether or not the access violation was actually caused by
a null pointer?


Signal hanlder are provided a - system dependant - structure that 
contains such informations.


This is used to detect stackoverflow as well a null pointer deference. 
Lib like libsigsegv can help a lot to implement such a thing.


Re: dereferencing null

2012-03-05 Thread Sandeep Datta


No hardware support for them, so no choice.



I am just going to leave this here...

*Fast Bounds Checking Using Debug Register*

http://www.ecsl.cs.sunysb.edu/tr/TR225.pdf


Re: dereferencing null

2012-03-05 Thread Walter Bright

On 3/4/2012 11:50 PM, Chad J wrote:

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.


I don't get this at all. I find it trivial to run the program with a debugger:

  gdb foo
  >run

that's it.


- 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/.


That's because the runtime library is compiled without debug symbols in it. If 
it was compiled with -g, the line numbers would be there. You of course can 
compile the library that way if you want. Debug symbols substantially increase 
your program size.




- 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!


I agree that customers emailing you a stack trace is a reasonable point. Andrei 
also brought up the point of the problems with using a debugger on a remote 
server machine.




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.


No hardware support for them, so no choice.



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.)


The added bloat for this would be substantial.



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.


Notably, C and C++ do not do what you suggest.


Re: dereferencing null

2012-03-05 Thread Jesse Phillips

On Monday, 5 March 2012 at 00:33:18 UTC, Nathan M. Swan wrote:

On Saturday, 3 March 2012 at 02:51:41 UTC, Walter Bright wrote:
Adding in software checks for null pointers will dramatically 
slow things down.


What about the debug/release difference? Isn't the point of 
debug mode to allow checks such as assert, RangeError, etc? 
"Segmentation fault: 11" prevents memory from corrupting, but 
it isn't helpful in locating a bug.


It can in linux. Enable debug symbols, and core dumps, open in gdb

$ ulimit -c unlimited
$ dmd files.d -gc
$ gdb ./files core


Re: dereferencing null

2012-03-05 Thread David Nadlinger

On Monday, 5 March 2012 at 09:09:30 UTC, Jacob Carlborg wrote:

On 2012-03-05 07:25, Walter Bright wrote:

[…]
run (run your program)
bt (print a backtrace)
quit (exit gdb)
[…]

Is demangling supposed to work on Mac OS X?


As the D demangling support was added in GDB 7., 
unfortunately no, as Apple ships an ancient (customized) version.


David


Re: dereferencing null

2012-03-05 Thread Jacob Carlborg

On 2012-03-05 07:25, 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

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:
...
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.
0x00401e45 in D main () at foo.d:13
13 bar.foo = 5;
(gdb) bt
#0 0x00401e45 in D main () at foo.d:13
#1 0x0040aa9b in rt.dmain2.main() ()
#2 0x00636010 in ?? ()
#3 0x77fdeae0 in ?? ()
#4 0x7fffeb30 in ?? ()
#5 0x7fffea00 in ?? ()
#6 0x0040a41b in rt.dmain2.main() ()
#7 0x0001 in ?? ()
#8 0x0019 in ?? ()
#9 0x00636020 in ?? ()
#10 0x7fffeb30 in ?? ()
#11 0x77ffe4c0 in ?? ()
#12 0x7fffe8b0 in ?? ()
#13 0x7fffeb30 in ?? ()
#14 0x7fffea30 in ?? ()
#15 0x0040aaee in rt.dmain2.main() ()
#16 0x0040aa84 in rt.dmain2.main() ()
#17 0x7fffeb30 in ?? ()
#18 0x7fffea80 in ?? ()
#19 0x0040a41b in rt.dmain2.main() ()
#20 0x0001 in ?? ()
#21 0x0019 in ?? ()
#22 0x00636020 in ?? ()
#23 0x0001 in ?? ()
#24 0x00636020 in ?? ()
#25 0x7fffee01 in ?? ()
#26 0x7fffeb30 in ?? ()
#27 0x7fffeb30 in ?? ()
#28 0x0040a3b3 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.


Is demangling supposed to work on Mac OS X?

--
/Jacob Carlborg


Re: dereferencing null

2012-03-04 Thread Chad J

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

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:
...
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.
0x00401e45 in D main () at foo.d:13
13 bar.foo = 5;
(gdb) bt
#0 0x00401e45 in D main () at foo.d:13
#1 0x0040aa9b in rt.dmain2.main() ()
#2 0x00636010 in ?? ()
#3 0x77fdeae0 in ?? ()
#4 0x7fffeb30 in ?? ()
#5 0x7fffea00 in ?? ()
#6 0x0040a41b in rt.dmain2.main() ()
#7 0x0001 in ?? ()
#8 0x0019 in ?? ()
#9 0x00636020 in ?? ()
#10 0x7fffeb30 in ?? ()
#11 0x77ffe4c0 in ?? ()
#12 0x7fffe8b0 in ?? ()
#13 0x7fffeb30 in ?? ()
#14 0x7fffea30 in ?? ()
#15 0x0040aaee in rt.dmain2.main() ()
#16 0x0040aa84 in rt.dmain2.main() ()
#17 0x7fffeb30 in ?? ()
#18 0x7fffea80 in ?? ()
#19 0x0040a41b in rt.dmain2.main() ()
#20 0x0001 in ?? ()
#21 0x0019 in ?? ()
#22 0x00636020 in ?? ()
#23 0x0001 in ?? ()
#24 0x00636020 in ?? ()
#25 0x7fffee01 in ?? ()
#26 0x7fffeb30 in ?? ()
#27 0x7fffeb30 in ?? ()
#28 0x0040a3b3 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.  Bo.


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.


Re: dereferencing null

2012-03-04 Thread Jonathan M Davis
On Sunday, March 04, 2012 21:31:21 Chad J wrote:
> On 03/03/2012 02:06 PM, Walter Bright wrote:
> > On 3/3/2012 2:13 AM, bearophile wrote:
> >> Walter:
> >>> Adding in software checks for null pointers will dramatically slow
> >>> things
> >>> down.
> >> 
> >> Define this use of "dramatically" in a more quantitative and objective
> >> way,
> >> please. Is Java "dramatically" slower than C++/D here?
> > 
> > You can try it for yourself. Take some OOP code of yours, and insert a
> > null check in front of every dereference of the class handle.
> 
> I have a hard time buying this as a valid reason to avoid inserting such
> checks.  I do think they should be optional, but they should be
> available, if not default, with optimizations for signal handlers and
> such taken in the cases where they apply.
> 
> Even if it slows my code down 4x, it'll be a huge win for me to avoid
> this stuff.  Because you know what pisses me off a helluva lot more than
> slightly slower code?  Spending hours trying to figure out what made my
> program say "Segmentation fault".  That's what.

Really? I rarely run into segfaults, and when I do, it's easy enough to enable 
core dumps, rerun the program, and then get an actual stack trace (along with 
the whole state of the program for that matter). Yes, upon occasion, it would 
be useful - especially if you're talking about a large program where you can't 
simply rerun it with core dumps enabled and quickly reproduce the problem, but 
in my experience, the reality of the matter is that it's a very rare 
occurence. And if it really is something that keeps causing you problems, on 
Linux at least, it's very easy to enable a signal handler to get you a stack 
trace.

So, I can see your complaint, but I find that it's rarely justified in practice.

- Jonathan M Davis


Re: dereferencing null

2012-03-04 Thread Walter Bright

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 
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:
...
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.
0x00401e45 in D main () at foo.d:13
13  bar.foo = 5;
(gdb) bt
#0  0x00401e45 in D main () at foo.d:13
#1  0x0040aa9b in rt.dmain2.main() ()
#2  0x00636010 in ?? ()
#3  0x77fdeae0 in ?? ()
#4  0x7fffeb30 in ?? ()
#5  0x7fffea00 in ?? ()
#6  0x0040a41b in rt.dmain2.main() ()
#7  0x0001 in ?? ()
#8  0x0019 in ?? ()
#9  0x00636020 in ?? ()
#10 0x7fffeb30 in ?? ()
#11 0x77ffe4c0 in ?? ()
#12 0x7fffe8b0 in ?? ()
#13 0x7fffeb30 in ?? ()
#14 0x7fffea30 in ?? ()
#15 0x0040aaee in rt.dmain2.main() ()
#16 0x0040aa84 in rt.dmain2.main() ()
#17 0x7fffeb30 in ?? ()
#18 0x7fffea80 in ?? ()
#19 0x0040a41b in rt.dmain2.main() ()
#20 0x0001 in ?? ()
#21 0x0019 in ?? ()
#22 0x00636020 in ?? ()
#23 0x0001 in ?? ()
#24 0x00636020 in ?? ()
#25 0x7fffee01 in ?? ()
#26 0x7fffeb30 in ?? ()
#27 0x7fffeb30 in ?? ()
#28 0x0040a3b3 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.


Re: dereferencing null

2012-03-04 Thread Chad J

On 03/04/2012 11:39 PM, Adam D. Ruppe wrote:

On Monday, 5 March 2012 at 03:24:32 UTC, Chad J wrote:

News to me. I've had bad runs with that back in the day, but maybe
things have improved a bit.


Strangely, I've never had a problem with gdb and D,
as far back as 2007.
(at least for the basic stack trace kind of stuff).

But, yeah, they've been improving a lot of things
recently too.


Non-nullable types would be really cool right about now.


Huh, I thought there was one in phobos by now.

You could spin your own with something like this:

struct NotNull(T) {
T t;
alias t this;
@disable this();
@disable this(typeof(null));
this(T value) {
assert(value !is null);
t = value;
}

@disable typeof(this) opAssign(typeof(null));
typeof(this) opAssign(T rhs) {
assert(rhs !is null);
t = rhs;
return this;
}
}


This will catch usages of the null literal at
compile time, and other null references at runtime
as soon as you try to use it.

With the disabled default constructor, you are forced
to provide an initializer when you use it, so no
accidental null will slip in.

The alias this means NotNull!T is substitutable for T,
so you can drop it into existing apis.



That's cool.  Maybe someone should stick it in Phobos?  I haven't had 
time to try it yet though.  I also didn't know about @disabled; that's a 
nifty addition.



It's that I simply cannot expect users to run my code in a debugger.


:) I'm lucky if I can get more from my users than
"the site doesn't work"!



Ugh!

This sort of thing has happened in non-web code at work.  This is on an 
old OpenVMS system with a DIBOL derivative language and people accessing 
it from character-based terminals.  Once I finally got the damn system 
capable of broadcasting emails reliably (!!) and without using disk IO 
(!!), I started having it send me stack traces of things before it dies. 
 The only thing left that's really annoying about this is I still have 
no way of determining whether an exception is going to be caught or not 
before I send out the email, so I can't use it in cases where things are 
expected to throw sometimes (ex: end of file exception, key not found 
exception).  So I can only do this effectively for errors that are 
pretty much guaranteed to be bad news.


I hope Phobos will have (or already have) the ability to print stack 
traces without crashing from an exception.  There are (surprisingly 
frequent) times when something abnormal happens and I want to know why, 
but it is safe to continue running the program and the last thing I want 
to do is crash on the user.  In those cases it is very useful for me to 
grab a stacktrace and send it to myself in an email.


I can definitely see web stuff being a lot less cut-and-dry than this 
though, and also having a lot of blind-spots in technologies that you 
can't control very easily.



The problem is that they don't help me when I missed a spot and didn't
use assertions, contracts, or invariants.


Aye, I've had it happen. The not null types might help,
though tbh I've never used anything like this in practice
so maybe not. I don't really know.




Re: dereferencing null

2012-03-04 Thread Adam D. Ruppe

On Monday, 5 March 2012 at 03:24:32 UTC, Chad J wrote:
News to me.  I've had bad runs with that back in the day, but 
maybe things have improved a bit.


Strangely, I've never had a problem with gdb and D,
as far back as 2007.
(at least for the basic stack trace kind of stuff).

But, yeah, they've been improving a lot of things
recently too.


Non-nullable types would be really cool right about now.


Huh, I thought there was one in phobos by now.

You could spin your own with something like this:

struct NotNull(T) {
  T t;
  alias t this;
  @disable this();
  @disable this(typeof(null));
  this(T value) {
 assert(value !is null);
 t = value;
  }

  @disable typeof(this) opAssign(typeof(null));
  typeof(this) opAssign(T rhs) {
  assert(rhs !is null);
  t = rhs;
  return this;
  }
}


This will catch usages of the null literal at
compile time, and other null references at runtime
as soon as you try to use it.

With the disabled default constructor, you are forced
to provide an initializer when you use it, so no
accidental null will slip in.

The alias this means NotNull!T is substitutable for T,
so you can drop it into existing apis.

It's that I simply cannot expect users to run my code in a 
debugger.


:) I'm lucky if I can get more from my users than
"the site doesn't work"!

The problem is that they don't help me when I missed a spot and 
didn't use assertions, contracts, or invariants.


Aye, I've had it happen. The not null types might help,
though tbh I've never used anything like this in practice
so maybe not. I don't really know.


Re: dereferencing null

2012-03-04 Thread Chad J

On 03/04/2012 09:43 PM, Adam D. Ruppe wrote:

On Monday, 5 March 2012 at 02:32:12 UTC, Chad J wrote:

I hate hate HATE vague error messages that don't help me.


In a lot of cases, getting more info is very, very easy:

$ dmd -g -debug test9
$ ./test9
Segmentation fault
$ gdb ./test9
GNU gdb (GDB) 7.1
[...]
(gdb) r
Starting program: /home/me/test9
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x08067a57 in _Dmain () at test9.d:12
12 bar.foo = 5;
(gdb) where
#0 0x08067a57 in _Dmain () at test9.d:12
#1 0x0806eaf8 in _D2rt6dmain24mainUiPPaZi7runMainMFZv ()
#2 0x0806e605 in _D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv ()
#3 0x0806eb3f in _D2rt6dmain24mainUiPPaZi6runAllMFZv ()
#4 0x0806e605 in _D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv ()
#5 0x0806e5b4 in main ()
(gdb) print bar
$1 = (struct test9.Bar *) 0x0



My gdb is out of the box unmodified; you don't need anything
special to get basic info like this.



News to me.  I've had bad runs with that back in the day, but maybe 
things have improved a bit.






There's two cases where null annoys me though:

1) if it is stored somewhere where it isn't supposed to be.
Then, the location of the dereference doesn't help - the
question is how it got there in the first place.



True, but that's a different problem space to me.  Non-nullable types 
would be really cool right about now.



2) Segfaults in the middle of a web app, where running it under
the same conditions again in the debugger is a massive pain in
the butt.



THIS.  This is why I expect what I expect.  It's not web apps in my 
case.  It's that I simply cannot expect users to run my code in a 
debugger.  That is just /not acceptable/.




I've trained myself to use assert (or functions with assert
in out contracts/invariants) a lot to counter these.


*quiver*
It's not that I don't like assertions, contracts, or invariants.  These 
are very cool.  The problem is that they don't help me when I missed a 
spot and didn't use assertions, contracts, or invariants.  Back to 
spending a bunch of time inserting writefln statements to do something 
that I should be able to accomplish with my eyeballs and a stack trace 
pretty much instantaneously.


Re: dereferencing null

2012-03-04 Thread H. S. Teoh
On Mon, Mar 05, 2012 at 03:43:15AM +0100, Adam D. Ruppe wrote:
[...]
> There's two cases where null annoys me though:
> 
> 1) if it is stored somewhere where it isn't supposed to be.
> Then, the location of the dereference doesn't help - the
> question is how it got there in the first place.

And having the compiler insert explicit null checks doesn't help here
either.


> 2) Segfaults in the middle of a web app, where running it under the
> same conditions again in the debugger is a massive pain in the butt.

I've come to the conclusion after years of fighting with making the
debugger work over the network to debug embedded apps, that fprintf is a
lot less painful than using a debugger. (Yes I heard that groan.) A
well-placed fprintf can narrow down the location of the problem
considerably. A nicely-wrapped multiprocess-safe fprintf that appends to
a debug file complete with getpid() information is even better.
Especially as a debug library optionally linked into the app. :-) The
only downside is that if your app takes a long time to build (or takes
too much effort to install) then a debugger is the better ticket.


[...]
> I've trained myself to use assert (or functions with assert in out
> contracts/invariants) a lot to counter these.

Yeah, asserts and DbC is extremely useful in detecting the problem at
its source rather than who knows how long later down the road where all
traces to the source is practically already non-existent. Thing is, you
have to consistently do this, everywhere in your code. And everyone else
on the project as well. Leave out one place, and it will just be that
very place that eventually causes problems. Murphy's law at work. :-)


T

-- 
Having a smoking section in a restaurant is like having a peeing section
in a swimming pool. -- Edward Burr 


Re: dereferencing null

2012-03-04 Thread Adam D. Ruppe

On Monday, 5 March 2012 at 02:32:12 UTC, Chad J wrote:

I hate hate HATE vague error messages that don't help me.


In a lot of cases, getting more info is very, very easy:

$ dmd -g -debug test9
$ ./test9
Segmentation fault
$ gdb ./test9
GNU gdb (GDB) 7.1
[...]
(gdb) r
Starting program: /home/me/test9
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x08067a57 in _Dmain () at test9.d:12
12  bar.foo = 5;
(gdb) where
#0  0x08067a57 in _Dmain () at test9.d:12
#1  0x0806eaf8 in _D2rt6dmain24mainUiPPaZi7runMainMFZv ()
#2  0x0806e605 in _D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv ()
#3  0x0806eb3f in _D2rt6dmain24mainUiPPaZi6runAllMFZv ()
#4  0x0806e605 in _D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv ()
#5  0x0806e5b4 in main ()
(gdb) print bar
$1 = (struct test9.Bar *) 0x0



My gdb is out of the box unmodified; you don't need anything
special to get basic info like this.




There's two cases where null annoys me though:

1) if it is stored somewhere where it isn't supposed to be.
Then, the location of the dereference doesn't help - the
question is how it got there in the first place.

2) Segfaults in the middle of a web app, where running it under
the same conditions again in the debugger is a massive pain in
the butt.


I've trained myself to use assert (or functions with assert
in out contracts/invariants) a lot to counter these.


Re: dereferencing null

2012-03-04 Thread Chad J

On 03/03/2012 02:06 PM, Walter Bright wrote:

On 3/3/2012 2:13 AM, bearophile wrote:

Walter:


Adding in software checks for null pointers will dramatically slow
things
down.


Define this use of "dramatically" in a more quantitative and objective
way,
please. Is Java "dramatically" slower than C++/D here?


You can try it for yourself. Take some OOP code of yours, and insert a
null check in front of every dereference of the class handle.


I have a hard time buying this as a valid reason to avoid inserting such 
checks.  I do think they should be optional, but they should be 
available, if not default, with optimizations for signal handlers and 
such taken in the cases where they apply.


Even if it slows my code down 4x, it'll be a huge win for me to avoid 
this stuff.  Because you know what pisses me off a helluva lot more than 
slightly slower code?  Spending hours trying to figure out what made my 
program say "Segmentation fault".  That's what.


I hate hate HATE vague error messages that don't help me.  I really want 
to emphasize how super dumb and counterproductive this is.


If I find that my code is too slow all of a sudden, then let me turn off 
the extra checks.  Otherwise, I expect my crashes to give me some 
indication of what happened.


This is reminding me that I can't do stuff like this:

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!
(And totally NOT worth whatever optimization this buys me.)


Re: dereferencing null

2012-03-04 Thread Nathan M. Swan

On Saturday, 3 March 2012 at 02:51:41 UTC, Walter Bright wrote:
Adding in software checks for null pointers will dramatically 
slow things down.


What about the debug/release difference? Isn't the point of debug 
mode to allow checks such as assert, RangeError, etc? 
"Segmentation fault: 11" prevents memory from corrupting, but it 
isn't helpful in locating a bug.


Re: dereferencing null

2012-03-03 Thread Sandeep Datta
If you're dealing with plugins from an unknown source, it's a 
good design to separate plugins and such as entirely separate 
processes. Then, when one goes down, it cannot bring down 
anyone else, since there is no shared address space.


They can communicate with the OS-supplied interprocess 
communications API.


Yes I think this is a good idea in general but the process/IPC 
overhead can be substantial if you have a lot of (small) plugins. 
I think Google chrome uses this trick (among others) to good 
effect in providing fault tolerance ( 
http://www.geekosystem.com/google-chrome-hacking-prize/ ).


Re: dereferencing null

2012-03-03 Thread Sandeep Datta
1. SEH isn't portable. There's no way to make it work under 
non-Windows systems.


Ok after some digging around it appears (prima facie) that Linux 
doesn't have anything close to SEH. I am aware of POSIX signals 
but I am not sure if they work for individual threads in a 
process. Last I checked the whole process has to be hosed when 
you receive a segfault and there isn't much you can do about it. 
I am a Linux newbie but I am almost seriously considering 
implementing SEH for linux (in the kernel). Any Linux Gurus here 
who think this is a good idea?


Re: dereferencing null

2012-03-03 Thread Sandeep Datta
A misbehaving plugin could easily corrupt your process. 
Destroying data

is always much worse than crashing.


At this point I usually say memory corruption is not an option 
for type safe languages but D doesn't really provide runtime type 
safety guarantees, or does it?


I think in the future (D 4.0 or something) we could seriously 
consider something like proof carrying code etc to take 
memory/type safety to the next level. People interested in this 
will be aware of Google's effort in this direction NaCl ( 
http://code.google.com/p/nativeclient/ )


Re: dereferencing null

2012-03-03 Thread Martin Nowak
On Sun, 04 Mar 2012 03:53:53 +0100, Sandeep Datta  
 wrote:


It's been there for 10 years, and turns out to be a solution looking  
for a problem.


I beg to differ, the ability to catch and respond to such asynchronous  
exceptions is vital to the stable operation of long running software.


It is not hard to see how this can be useful in programs which depend on  
plugins to extend functionality (e.g. IIS, Visual Studio, OS with  
drivers as plugins etc). A misbehaving plugin has the potential to bring  
down the whole house if hardware exceptions cannot be safely handled  
within the host application. Thus the inability of handling such  
exceptions undermines D's ability to support dynamically loaded modules  
of any kind and greatly impairs modularity.



A misbehaving plugin could easily corrupt your process. Destroying data
is always much worse than crashing. The only sensible reaction to an async
exception is dumping/tracing. If you want stable plugins you'll have to run
them in another process.


Re: dereferencing null

2012-03-03 Thread Walter Bright

On 3/3/2012 8:20 PM, H. S. Teoh wrote:

Don't know how this would work on Windows, but presumably there are
clean ways of doing it that doesn't endanger the health of the process
creating the sandbox.


If you're dealing with plugins from an unknown source, it's a good design to 
separate plugins and such as entirely separate processes. Then, when one goes 
down, it cannot bring down anyone else, since there is no shared address space.


They can communicate with the OS-supplied interprocess communications API.


Re: dereferencing null

2012-03-03 Thread H. S. Teoh
On Sat, Mar 03, 2012 at 07:34:50PM -0800, Walter Bright wrote:
[...]
> 3. Intercepting and recovering from seg faults, div by 0, etc., all
> sounds great on paper. In practice, it is almost always wrong. The
> only exception (!) to the rule is when sandboxing a plugin (as you
> suggested). Making such a sandbox work is highly system specific, and
> doesn't always fit into the D exception model (in fact, it never does
> outside of Windows).
[...]

I wonder if there's some merit to a std.sandbox module in Phobos...

In Linux (any Posix), for example, it could run the sandbox code inside
a fork()ed process, and watch for termination by signal, for example.
Data could be returned via a pipe, or maybe a shared memory segment of
some sort.

Don't know how this would work on Windows, but presumably there are
clean ways of doing it that doesn't endanger the health of the process
creating the sandbox.


T

-- 
Freedom of speech: the whole world has no right *not* to hear my spouting off!


Re: dereferencing null

2012-03-03 Thread H. S. Teoh
On Sun, Mar 04, 2012 at 04:29:27AM +0100, Adam D. Ruppe wrote:
> On Sunday, 4 March 2012 at 03:15:19 UTC, Sandeep Datta wrote:
> >All we have to do now is provide a more specific exception (say
> >NullReferenceException) so that the programmer has the ability to
> >provide a specific exception handler for NullReferenceException etc.
> 
> Looks like it is pretty easy to do. Check out
> 
> dmd2/src/druntime/src/rt/deh.d
> 
> The Access Violation error is thrown on about
> line 635. There's a big switch that handles a bunch
> of errors.
> 
> >I gave it a try on Linux but unfortunately it leads to a segfault
> 
> Yeah, Linux does it as a signal which someone has tried to turn into
> an exception before, which kinda works but is easy to break. (I don't
> remember exactly why it didn't work right, but there were problems.)

Yeah, according to the Posix specs, trying to continue execution after
catching SIGSEGV or SIGILL is ... to say the least, extremely dangerous.
Basically you'll have to unwind the stack and run the rest of the
program inside signal handler context, which means certain operations
(like calling signal unsafe syscalls) are not guaranteed to do what
you'd expect.

Of course, there are ways around it, but it does depend on the specific
way Linux implements signal handling, which is not guaranteed to not
change across Linux versions (because it's not part of the Posix spec).
So it would be very fragile, and prone to nasty bugs.


T

-- 
This is a tpyo.


Re: dereferencing null

2012-03-03 Thread Walter Bright

On 3/3/2012 6:53 PM, Sandeep Datta wrote:

It's been there for 10 years, and turns out to be a solution looking for a
problem.


I beg to differ, the ability to catch and respond to such asynchronous
exceptions is vital to the stable operation of long running software.

It is not hard to see how this can be useful in programs which depend on plugins
to extend functionality (e.g. IIS, Visual Studio, OS with drivers as plugins
etc). A misbehaving plugin has the potential to bring down the whole house if
hardware exceptions cannot be safely handled within the host application. Thus
the inability of handling such exceptions undermines D's ability to support
dynamically loaded modules of any kind and greatly impairs modularity.

Also note hardware exceptions are not limited to segfaults there are other
exceptions like division by zero, invalid operation, floating point exceptions
(overflow, underflow) etc.

Plus by using this approach (SEH) you can eliminate the software null checks and
avoid taking a hit on performance.

So in conclusion I think it will be worth our while to supply something like a
NullReferenceException (and maybe NullPointerException for raw pointers) which
will provide more context than a simple segfault (and that too without a core
dump). Additional information may include things like a stacktrace (like
Vladimir said in another post) with line numbers, file/module names etc. Please
take a look at C#'s exception hierarchy for some inspiration (not that you need
any but it's nice to have some consistency across languages too). I am just a
beginner in D but I hope D has something like exception chaining in C# using
which we can chain exceptions as we go to capture the chain of events which led
to failure.


As I said, it already does that (on Windows). There is an access violation 
exception. Try it on windows, you'll see it.


1. SEH isn't portable. There's no way to make it work under non-Windows systems.

2. Converting SEH to D exceptions is not necessary to make a stack trace dump 
work.

3. Intercepting and recovering from seg faults, div by 0, etc., all sounds great 
on paper. In practice, it is almost always wrong. The only exception (!) to the 
rule is when sandboxing a plugin (as you suggested). Making such a sandbox work 
is highly system specific, and doesn't always fit into the D exception model (in 
fact, it never does outside of Windows).





Re: dereferencing null

2012-03-03 Thread Adam D. Ruppe

On Sunday, 4 March 2012 at 03:15:19 UTC, Sandeep Datta wrote:
All we have to do now is provide a more specific exception (say 
NullReferenceException) so that the programmer has the ability 
to provide a specific exception handler for 
NullReferenceException etc.


Looks like it is pretty easy to do. Check out

dmd2/src/druntime/src/rt/deh.d

The Access Violation error is thrown on about
line 635. There's a big switch that handles a bunch
of errors.

I gave it a try on Linux but unfortunately it leads to a 
segfault


Yeah, Linux does it as a signal which someone has
tried to turn into an exception before, which kinda
works but is easy to break. (I don't remember
exactly why it didn't work right, but there
were problems.)


Re: dereferencing null

2012-03-03 Thread Sandeep Datta

You can catch it in D (on Windows):


This is great. All we have to do now is provide a more specific 
exception (say NullReferenceException) so that the programmer has 
the ability to provide a specific exception handler for 
NullReferenceException etc.


I gave it a try on Linux but unfortunately it leads to a segfault 
(DMD 2.056, x86-64).


Re: dereferencing null

2012-03-03 Thread Adam D. Ruppe

On Sunday, 4 March 2012 at 02:53:54 UTC, Sandeep Datta wrote:
Thus the inability of handling such exceptions undermines D's 
ability to support dynamically loaded modules of any kind and 
greatly impairs modularity.


You can catch it in D (on Windows):

import std.stdio;
void main() {
int* a;
try {
*a = 0;
} catch(Throwable t) {
writefln("I caught it! %s", t.msg);
}
}

dmd test9
test9
I caught it! Access Violation



Re: dereferencing null

2012-03-03 Thread Sandeep Datta
It's been there for 10 years, and turns out to be a solution 
looking for a problem.


I beg to differ, the ability to catch and respond to such 
asynchronous exceptions is vital to the stable operation of long 
running software.


It is not hard to see how this can be useful in programs which 
depend on plugins to extend functionality (e.g. IIS, Visual 
Studio, OS with drivers as plugins etc). A misbehaving plugin has 
the potential to bring down the whole house if hardware 
exceptions cannot be safely handled within the host application. 
Thus the inability of handling such exceptions undermines D's 
ability to support dynamically loaded modules of any kind and 
greatly impairs modularity.


Also note hardware exceptions are not limited to segfaults there 
are other exceptions like division by zero, invalid operation, 
floating point exceptions (overflow, underflow) etc.


Plus by using this approach (SEH) you can eliminate the software 
null checks and avoid taking a hit on performance.


So in conclusion I think it will be worth our while to supply 
something like a NullReferenceException (and maybe 
NullPointerException for raw pointers) which will provide more 
context than a simple segfault (and that too without a core 
dump). Additional information may include things like a 
stacktrace (like Vladimir said in another post) with line 
numbers, file/module names etc. Please take a look at C#'s 
exception hierarchy for some inspiration (not that you need any 
but it's nice to have some consistency across languages too). I 
am just a beginner in D but I hope D has something like exception 
chaining in C# using  which we can chain exceptions as we go to 
capture the chain of events which led to failure.


Re: dereferencing null

2012-03-03 Thread Vladimir Panteleev

On Saturday, 3 March 2012 at 22:24:59 UTC, Walter Bright wrote:

On 3/3/2012 12:29 PM, Sandeep Datta wrote:
I would recommend doing what Microsoft does in this case, use 
SEH (Structured exception handling) on windows i.e. use OS 
facilities to trap and convert hardware exceptions into 
software exceptions.


D for Windows already does that.

It's been there for 10 years, and turns out to be a solution 
looking for a problem.


Getting a stack trace without having to start a debugger is kinda 
nice.


Re: dereferencing null

2012-03-03 Thread Walter Bright

On 3/3/2012 12:29 PM, Sandeep Datta wrote:

I would recommend doing what Microsoft does in this case, use SEH
(Structured exception handling) on windows i.e. use OS facilities
to trap and convert hardware exceptions into software exceptions.


D for Windows already does that.

It's been there for 10 years, and turns out to be a solution looking for a 
problem.


Re: dereferencing null

2012-03-03 Thread Sandeep Datta

I would recommend doing what Microsoft does in this case, use SEH
(Structured exception handling) on windows i.e. use OS facilities
to trap and convert hardware exceptions into software exceptions.

See the /EHa flag in the Microsoft C++ compiler.

I hope Linux has something similar, then we are all set!

ref:
http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

On Saturday, 3 March 2012 at 02:51:41 UTC, Walter Bright wrote:

On 3/1/2012 8:51 PM, Jonathan M Davis wrote:

It's defined. The operating system protects you.


Not exactly. It's a feature of the hardware. You get this for 
free, and your code runs at full speed.


Adding in software checks for null pointers will dramatically 
slow things down.




Re: dereferencing null

2012-03-03 Thread Timon Gehr

On 03/03/2012 09:00 PM, deadalnix wrote:

Le 03/03/2012 20:06, Walter Bright a écrit :

On 3/3/2012 2:13 AM, bearophile wrote:

Walter:


Adding in software checks for null pointers will dramatically slow
things
down.


Define this use of "dramatically" in a more quantitative and objective
way,
please. Is Java "dramatically" slower than C++/D here?


You can try it for yourself. Take some OOP code of yours, and insert a
null check in front of every dereference of the class handle.


Why would you want to check every time ? You program will get a signal
from the system if it try to deference a null pointer, so thing can be
done in the signal handler, and no cost is involved.


The signal will likely be the same for the following two code snippets:

void main(){
Object o;
o.toString();
}

void main(){
*cast(int*)0xDEADBEEF = 1337;
}


How to detect whether or not the access violation was actually caused by 
a null pointer?


Re: dereferencing null

2012-03-03 Thread deadalnix

Le 03/03/2012 20:06, Walter Bright a écrit :

On 3/3/2012 2:13 AM, bearophile wrote:

Walter:


Adding in software checks for null pointers will dramatically slow
things
down.


Define this use of "dramatically" in a more quantitative and objective
way,
please. Is Java "dramatically" slower than C++/D here?


You can try it for yourself. Take some OOP code of yours, and insert a
null check in front of every dereference of the class handle.


Why would you want to check every time ? You program will get a signal 
from the system if it try to deference a null pointer, so thing can be 
done in the signal handler, and no cost is involved.


Re: dereferencing null

2012-03-03 Thread Walter Bright

On 3/3/2012 2:13 AM, bearophile wrote:

Walter:


Adding in software checks for null pointers will dramatically slow things
down.


Define this use of "dramatically" in a more quantitative and objective way,
please. Is Java "dramatically" slower than C++/D here?


You can try it for yourself. Take some OOP code of yours, and insert a null 
check in front of every dereference of the class handle.


Re: dereferencing null

2012-03-03 Thread James Miller
On 3 March 2012 23:13, bearophile  wrote:
> Walter:
>
>> Adding in software checks for null pointers will dramatically slow things 
>> down.
>
> Define this use of "dramatically" in a more quantitative and objective way, 
> please. Is Java "dramatically" slower than C++/D here?
>
> Bye,
> bearophile

Not to be too cheeky here, but since its done in hardware, and
therefore no software checks are done, I'm going to say that it is
infinitely slower. Since even 1 extra instruction is infinitely more
than the current 0.


Re: dereferencing null

2012-03-03 Thread Tove

On Saturday, 3 March 2012 at 10:13:34 UTC, bearophile wrote:

Walter:

Adding in software checks for null pointers will dramatically 
slow things down.


Define this use of "dramatically" in a more quantitative and 
objective way, please. Is Java "dramatically" slower than C++/D 
here?


Bye,
bearophile


It's not a fair comparison, because the Java JIT will optimize 
the null checks away...


Signal handlers might be the answer though, if the same behavior 
can be guaranteed on all major platforms...




Re: dereferencing null

2012-03-03 Thread bearophile
Walter:

> Adding in software checks for null pointers will dramatically slow things 
> down.

Define this use of "dramatically" in a more quantitative and objective way, 
please. Is Java "dramatically" slower than C++/D here?

Bye,
bearophile


Re: dereferencing null

2012-03-02 Thread Daniel Murphy
"Peter Alexander"  wrote in message 
news:jxloisomieykanavm...@forum.dlang.org...
> On Friday, 2 March 2012 at 10:01:32 UTC, Daniel Murphy wrote:
>> "Peter Alexander"  wrote in message
>> news:vicaibqyaerogseqs...@forum.dlang.org...

 It's defined. The operating system protects you. You get a segfault on 
 *nix and
 an access violation on Windows.
>>>
>>> False.
>>>
>>> [snip]
>>>
>>> You only get an error if there is a memory access involved (vtable, 
>>> member data etc.)
>>>
>>
>> It _is_ defined, you get an access violation whenever there's a 
>> dereference.
>> Yes, you can call some types of member functions without any 
>> dereferences,
>> but this is alse well defined and sometimes quite useful.
>
> Ok, if it is defined, then please tell me what the defined behaviour of my 
> code snippet is.

Assertion failure in debug mode, prints the message in release mode. (I 
think) 




Re: dereferencing null

2012-03-02 Thread Walter Bright

On 3/1/2012 8:51 PM, Jonathan M Davis wrote:

It's defined. The operating system protects you.


Not exactly. It's a feature of the hardware. You get this for free, and your 
code runs at full speed.


Adding in software checks for null pointers will dramatically slow things down.


Re: dereferencing null

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 16:19:13 deadalnix wrote:
> Le 02/03/2012 15:37, Jacob Carlborg a écrit :
> > On 2012-03-02 14:00, deadalnix wrote:
> >> Le 02/03/2012 05:51, Jonathan M Davis a écrit :
> >>> On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
>  Am I correct that trying to use an Object null results in
>  undefined behavior?
>  
>  Object o = null;
>  o.opCmp(new Object); // segmentation fault on my OSX machine
>  
>  This seems a bit non-D-ish to me, as other bugs like this throw
>  Errors (e.g. RangeError).
>  
>  It would be nice if it would throw a NullPointerError or
>  something like that, because I spent a long time trying to find a
>  bug that crashed the program before writeln-debugging statements
>  could be flushed.
> >>> 
> >>> It's defined. The operating system protects you. You get a segfault on
> >>> *nix and
> >>> an access violation on Windows. Walter's take on it is that there is
> >>> no point
> >>> in checking for what the operating system is already checking for -
> >>> especially
> >>> when it adds additional overhead. Plenty of folks disagree, but that's
> >>> the way
> >>> it is.
> >> 
> >> The assertion that it has overhead isn't true.You'll find solutions
> >> without overhead (using libsigsegv in druntime for example).
> >> 
> >> BTW, object should be non nullable by default, if you ask me. The
> >> drawback of null is way bigger than any benefit.
> > 
> > Isn't it quite unsafe to throw an exception in a signal ?
> 
> The signal handler is called on top of the stack, but the information to
> retrieve the stack trace are system dependant. BTW, using lib like
> libsigsegv can help a lot to make it safe. It isn't safe ATM, but it is
> doable.

You could definitely set it up to print a stack trace in the signal handler on 
at least some systems, but throwing an exception would _not_ be a good idea. 
So, a NullPointerException _would_ require additional overhead, because it 
would require checking the pointer/reference for null every time that you 
dereference it.

Of course, it wouldn't work if anyone installed their own signal handler, so 
using a signal handler has its limits anyway, but it could be done.

- Jonathan M Davis


Re: dereferencing null

2012-03-02 Thread Peter Alexander

On Friday, 2 March 2012 at 10:01:32 UTC, Daniel Murphy wrote:
"Peter Alexander"  wrote in 
message

news:vicaibqyaerogseqs...@forum.dlang.org...


It's defined. The operating system protects you. You get a 
segfault on *nix and

an access violation on Windows.


False.

[snip]

You only get an error if there is a memory access involved 
(vtable, member data etc.)




It _is_ defined, you get an access violation whenever there's a 
dereference.
Yes, you can call some types of member functions without any 
dereferences,

but this is alse well defined and sometimes quite useful.


Ok, if it is defined, then please tell me what the defined 
behaviour of my code snippet is.


Re: dereferencing null

2012-03-02 Thread Martin Nowak

Technically speaking, there is no dereference of null occurring there. It
*looks* like there is because of the "foo.bar" notation, but remember,
calling a member function is not really dereferencing. It's just sugar  
for:


foo.vtable[index_of_bar](foo);


But usually there's an class invariant.


Re: dereferencing null

2012-03-02 Thread Nick Sabalausky
"Peter Alexander"  wrote in message 
news:vicaibqyaerogseqs...@forum.dlang.org...
> On Friday, 2 March 2012 at 04:53:02 UTC, Jonathan M Davis wrote:
>>
>> It's defined. The operating system protects you. You get a segfault on 
>> *nix and
>> an access violation on Windows.
>
> False.
>
> ---
> import std.stdio;
>
> class Foo
> {
> final void bar()
> {
> writeln("I'm null!");
> }
> }
>
> void main()
> {
> Foo foo;
> foo.bar();
> }
> ---
>
> % dmd test.d -O -release -inline
> % ./test
> I'm null!
> %
>
> ---
>
> You only get an error if there is a memory access involved (vtable, member 
> data etc.)
>

Technically speaking, there is no dereference of null occurring there. It 
*looks* like there is because of the "foo.bar" notation, but remember, 
calling a member function is not really dereferencing. It's just sugar for:

foo.vtable[index_of_bar](foo);

Since "bar()" is a final member of "Foo" and "foo" is statically known to be 
type "Foo", the usual vtable indirection is unnecessary, so it reduces to:

bar(foo);

Passing null into a function doesn't involve dereferening the null, and 
bar() doesn't dereference "this", so there's never any dereferencing of 
null. Therefore the rule about null dereferences always being caught does 
still hold true.

It is counter-intuitive, though.





Re: dereferencing null

2012-03-02 Thread deadalnix

Le 02/03/2012 15:37, Jacob Carlborg a écrit :

On 2012-03-02 14:00, deadalnix wrote:

Le 02/03/2012 05:51, Jonathan M Davis a écrit :

On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:

Am I correct that trying to use an Object null results in
undefined behavior?

Object o = null;
o.opCmp(new Object); // segmentation fault on my OSX machine

This seems a bit non-D-ish to me, as other bugs like this throw
Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or
something like that, because I spent a long time trying to find a
bug that crashed the program before writeln-debugging statements
could be flushed.


It's defined. The operating system protects you. You get a segfault on
*nix and
an access violation on Windows. Walter's take on it is that there is
no point
in checking for what the operating system is already checking for -
especially
when it adds additional overhead. Plenty of folks disagree, but that's
the way
it is.



The assertion that it has overhead isn't true.You'll find solutions
without overhead (using libsigsegv in druntime for example).

BTW, object should be non nullable by default, if you ask me. The
drawback of null is way bigger than any benefit.


Isn't it quite unsafe to throw an exception in a signal ?



The signal handler is called on top of the stack, but the information to 
retrieve the stack trace are system dependant. BTW, using lib like 
libsigsegv can help a lot to make it safe. It isn't safe ATM, but it is 
doable.


Re: dereferencing null

2012-03-02 Thread Jacob Carlborg

On 2012-03-02 14:00, deadalnix wrote:

Le 02/03/2012 05:51, Jonathan M Davis a écrit :

On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:

Am I correct that trying to use an Object null results in
undefined behavior?

Object o = null;
o.opCmp(new Object); // segmentation fault on my OSX machine

This seems a bit non-D-ish to me, as other bugs like this throw
Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or
something like that, because I spent a long time trying to find a
bug that crashed the program before writeln-debugging statements
could be flushed.


It's defined. The operating system protects you. You get a segfault on
*nix and
an access violation on Windows. Walter's take on it is that there is
no point
in checking for what the operating system is already checking for -
especially
when it adds additional overhead. Plenty of folks disagree, but that's
the way
it is.



The assertion that it has overhead isn't true.You'll find solutions
without overhead (using libsigsegv in druntime for example).

BTW, object should be non nullable by default, if you ask me. The
drawback of null is way bigger than any benefit.


Isn't it quite unsafe to throw an exception in a signal ?

--
/Jacob Carlborg


Re: dereferencing null

2012-03-02 Thread deadalnix

Le 02/03/2012 14:30, Marco Leise a écrit :

Am 02.03.2012, 14:01 Uhr, schrieb deadalnix :


Le 02/03/2012 11:56, Jacob Carlborg a écrit :


You only get an error if there is a memory access involved (vtable,
member data etc.)



I never thought about that.



This is a common C++ interview question.


Don't scare him! I only had interviews in small companies with
self-educated programmers. One question was, what Delphi cannot do. I
said, writing a kernel and cross-platform development wouldn't work, but
the answer the employer was looking for was COBRA. (And I think even at
that time there was already a solution for that.)
The difficulty really depends on how sophisticated a company's personnel
department is. :-)


Yes, many company don't go that far in interview. But this is a red flag 
to me.


Re: dereferencing null

2012-03-02 Thread Marco Leise

Am 02.03.2012, 14:01 Uhr, schrieb deadalnix :


Le 02/03/2012 11:56, Jacob Carlborg a écrit :


You only get an error if there is a memory access involved (vtable,
member data etc.)



I never thought about that.



This is a common C++ interview question.


Don't scare him! I only had interviews in small companies with self-educated 
programmers. One question was, what Delphi cannot do. I said, writing a kernel 
and cross-platform development wouldn't work, but the answer the employer was 
looking for was COBRA. (And I think even at that time there was already a 
solution for that.)
The difficulty really depends on how sophisticated a company's personnel 
department is. :-)


Re: dereferencing null

2012-03-02 Thread Marco Leise

Am 02.03.2012, 05:37 Uhr, schrieb Nathan M. Swan :


I spent a long time trying to find a
bug that crashed the program before writeln-debugging statements
could be flushed.


Instead of writeln use stdout.writeln.


Re: dereferencing null

2012-03-02 Thread deadalnix

Le 02/03/2012 11:56, Jacob Carlborg a écrit :


False.

---
import std.stdio;

class Foo
{
final void bar()
{
writeln("I'm null!");
}
}

void main()
{
Foo foo;
foo.bar();
}
---

% dmd test.d -O -release -inline
% ./test
I'm null!
%

---

You only get an error if there is a memory access involved (vtable,
member data etc.)



I never thought about that.



This is a common C++ interview question.


Re: dereferencing null

2012-03-02 Thread deadalnix

Le 02/03/2012 05:51, Jonathan M Davis a écrit :

On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:

Am I correct that trying to use an Object null results in
undefined behavior?

  Object o = null;
  o.opCmp(new Object); // segmentation fault on my OSX machine

This seems a bit non-D-ish to me, as other bugs like this throw
Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or
something like that, because I spent a long time trying to find a
bug that crashed the program before writeln-debugging statements
could be flushed.


It's defined. The operating system protects you. You get a segfault on *nix and
an access violation on Windows. Walter's take on it is that there is no point
in checking for what the operating system is already checking for - especially
when it adds additional overhead. Plenty of folks disagree, but that's the way
it is.



The assertion that it has overhead isn't true.You'll find solutions 
without overhead (using libsigsegv in druntime for example).


BTW, object should be non nullable by default, if you ask me. The 
drawback of null is way bigger than any benefit.


Re: dereferencing null

2012-03-02 Thread Jacob Carlborg

On 2012-03-02 12:05, Jonathan M Davis wrote:

On Friday, March 02, 2012 11:56:52 Jacob Carlborg wrote:

I never thought about that.


It's the same in C++. I was quite surprised when I first ran into it. But as
Daniel points out, the behavior is still defined, just less expected. If you
actually use this (or any member variable, since that would use this) inside
of that member function though, you'll get a segfault just like if it had been
dereferenced before calling the function like it would be with a virtual
function.

- Jonathan M Davis


Yeah, that makes sense. A final method, not accessing "this", would be 
just as a static method. Which is like a free function scoped in a class.


--
/Jacob Carlborg


Re: dereferencing null

2012-03-02 Thread David Nadlinger

On Friday, 2 March 2012 at 09:22:28 UTC, Peter Alexander wrote:
You only get an error if there is a memory access involved 
(vtable, member data etc.)


By the way, my favorite application of that in C++ is debug 
helper member functions (think: using DMD's toChar() in GDB), 
which don't crash when invoked on a null pointer by checking if 
(this == 0) before accessing member variables.


David


Re: dereferencing null

2012-03-02 Thread Timon Gehr

On 03/02/2012 10:22 AM, Peter Alexander wrote:

You only get an error if there is a memory access involved (vtable,
member data etc.)



In non-release mode you get an assertion failure.


Re: dereferencing null

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 11:56:52 Jacob Carlborg wrote:
> I never thought about that.

It's the same in C++. I was quite surprised when I first ran into it. But as 
Daniel points out, the behavior is still defined, just less expected. If you 
actually use this (or any member variable, since that would use this) inside 
of that member function though, you'll get a segfault just like if it had been 
dereferenced before calling the function like it would be with a virtual 
function.

- Jonathan M Davis


Re: dereferencing null

2012-03-02 Thread Jacob Carlborg

On 2012-03-02 10:22, Peter Alexander wrote:

On Friday, 2 March 2012 at 04:53:02 UTC, Jonathan M Davis wrote:

On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:

Am I correct that trying to use an Object null results in
undefined behavior?

Object o = null;
o.opCmp(new Object); // segmentation fault on my OSX machine

This seems a bit non-D-ish to me, as other bugs like this throw
Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or
something like that, because I spent a long time trying to find a
bug that crashed the program before writeln-debugging statements
could be flushed.


It's defined. The operating system protects you. You get a segfault on
*nix and
an access violation on Windows.


False.

---
import std.stdio;

class Foo
{
final void bar()
{
writeln("I'm null!");
}
}

void main()
{
Foo foo;
foo.bar();
}
---

% dmd test.d -O -release -inline
% ./test
I'm null!
%

---

You only get an error if there is a memory access involved (vtable,
member data etc.)



I never thought about that.

--
/Jacob Carlborg


Re: dereferencing null

2012-03-02 Thread Daniel Murphy
"Peter Alexander"  wrote in message 
news:vicaibqyaerogseqs...@forum.dlang.org...
>>
>> It's defined. The operating system protects you. You get a segfault on 
>> *nix and
>> an access violation on Windows.
>
> False.
>
> [snip]
>
> You only get an error if there is a memory access involved (vtable, member 
> data etc.)
>

It _is_ defined, you get an access violation whenever there's a dereference. 
Yes, you can call some types of member functions without any dereferences, 
but this is alse well defined and sometimes quite useful. 




Re: dereferencing null

2012-03-02 Thread Peter Alexander

On Friday, 2 March 2012 at 04:53:02 UTC, Jonathan M Davis wrote:

On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:

Am I correct that trying to use an Object null results in
undefined behavior?

 Object o = null;
 o.opCmp(new Object); // segmentation fault on my OSX 
machine


This seems a bit non-D-ish to me, as other bugs like this throw
Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or
something like that, because I spent a long time trying to 
find a
bug that crashed the program before writeln-debugging 
statements

could be flushed.


It's defined. The operating system protects you. You get a 
segfault on *nix and

an access violation on Windows.


False.

---
import std.stdio;

class Foo
{
final void bar()
{
writeln("I'm null!");
}
}

void main()
{
Foo foo;
foo.bar();
}
---

% dmd test.d -O -release -inline
% ./test
I'm null!
%

---

You only get an error if there is a memory access involved 
(vtable, member data etc.)




Re: dereferencing null

2012-03-01 Thread Jonathan M Davis
On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
> Am I correct that trying to use an Object null results in
> undefined behavior?
> 
>  Object o = null;
>  o.opCmp(new Object); // segmentation fault on my OSX machine
> 
> This seems a bit non-D-ish to me, as other bugs like this throw
> Errors (e.g. RangeError).
> 
> It would be nice if it would throw a NullPointerError or
> something like that, because I spent a long time trying to find a
> bug that crashed the program before writeln-debugging statements
> could be flushed.

It's defined. The operating system protects you. You get a segfault on *nix and 
an access violation on Windows. Walter's take on it is that there is no point 
in checking for what the operating system is already checking for - especially 
when it adds additional overhead. Plenty of folks disagree, but that's the way 
it is.

If you really care about checking for it, then just assert:

assert(obj !is null);

or

assert(obj);

(the second one will also call the object's invariant).

- Jonathan M Davis


<    1   2