View mode: basic / threaded / horizontal-split · Log in · Help
May 30, 2012
Re: Exception/Error division in D
Le 30/05/2012 17:29, Don Clugston a écrit :
> There's a big difference. A segfault is a machine error. The integrity
> of the machine model has been violated, and the machine is in an
> out-of-control state. In particular, the stack may be corrupted, so
> stack unwinding may not be successful.
>
> But, in an assert error, the machine is completely intact; the error is
> at a higher level, which does not interfere with stack unwinding.
>
> Damage is possible only if you've written your destructors/finally code
> extremely poorly. Note that, unlike C++, it's OK to throw a new Error or
> Exception from inside a destructor.
> But with (say) a stack overflow, you don't necessarily know what code is
> being executed. It could do anything.
>

Most segfault are null deference or unintizialized pointer deference. 
Both are recoverable.
May 30, 2012
Re: Exception/Error division in D
On Thursday, May 31, 2012 00:01:16 deadalnix wrote:
> Le 30/05/2012 17:29, Don Clugston a écrit :
> > There's a big difference. A segfault is a machine error. The integrity
> > of the machine model has been violated, and the machine is in an
> > out-of-control state. In particular, the stack may be corrupted, so
> > stack unwinding may not be successful.
> > 
> > But, in an assert error, the machine is completely intact; the error is
> > at a higher level, which does not interfere with stack unwinding.
> > 
> > Damage is possible only if you've written your destructors/finally code
> > extremely poorly. Note that, unlike C++, it's OK to throw a new Error or
> > Exception from inside a destructor.
> > But with (say) a stack overflow, you don't necessarily know what code is
> > being executed. It could do anything.
> 
> Most segfault are null deference or unintizialized pointer deference.
> Both are recoverable.

If you dereferenced a null pointer, it's a bug in your code. Your code is 
assuming that the pointer was non-null, which was obviously incorrect, because 
it was null. That's _not_ recoverable in the general case. Your code was 
obviously written with the assumption that the pointer was non-null, so your 
code is wrong, and so continuing to execute it makes no sense, because it's in 
an invalid state and could do who-knows-what. If there's any possibility of a 
pointer being null, the correct thing to do is to check it before 
dereferencing it. If you don't, it's bug.

Now, it's perfectly possible to design code which never checks for null 
pointers and if a null pointer is dereferenced throws an Exception and 
attempts to recover from it (assuming that it's possible to detect the 
dereference and throw at that point, which AFAIK is impossible with segfaults 
- maybe it could be done on Windows with its Access Violations, but segfaults 
trigger a signal handler, and you're screwed at that point). But writing code 
which just assumes that pointers are non-null and will throw if they are null 
is incredibly sloppy. It means that you're treating pointers like you'd treat 
user input rather than as part of your code.

- Jonathan M Davis
May 31, 2012
Re: Exception/Error division in D
On Wednesday, 30 May 2012 at 22:22:01 UTC, Jonathan M Davis wrote:
> On Thursday, May 31, 2012 00:01:16 deadalnix wrote:
>> Most segfault are null deference or unintizialized pointer 
>> deference.
>> Both are recoverable.
>
> If you dereferenced a null pointer, it's a bug in your code. 
> Your code is
> assuming that the pointer was non-null, which was obviously 
> incorrect, because
> it was null. That's _not_ recoverable in the general case. Your 
> code was
> obviously written with the assumption that the pointer was 
> non-null, so your
> code is wrong, and so continuing to execute it makes no sense, 
> because it's in
> an invalid state and could do who-knows-what. If there's any 
> possibility of a
> pointer being null, the correct thing to do is to check it 
> before
> dereferencing it. If you don't, it's bug.
>
> Now, it's perfectly possible to design code which never checks 
> for null
> pointers and if a null pointer is dereferenced throws an 
> Exception and
> attempts to recover from it (assuming that it's possible to 
> detect the
> dereference and throw at that point, which AFAIK is impossible 
> with segfaults
> - maybe it could be done on Windows with its Access Violations, 
> but segfaults
> trigger a signal handler, and you're screwed at that point). 
> But writing code
> which just assumes that pointers are non-null and will throw if 
> they are null
> is incredibly sloppy. It means that you're treating pointers 
> like you'd treat
> user input rather than as part of your code.
>
> - Jonathan M Davis

All code has bugs in it. It's nice being notified about it and 
all, but if you release a server application, and it crashes 
every single time it encounters any bug... well, your customers 
will not have a fun time.
May 31, 2012
Re: Exception/Error division in D
On Thursday, 31 May 2012 at 00:58:42 UTC, Kapps wrote:
>
> All code has bugs in it. It's nice being notified about it and 
> all, but if you release a server application, and it crashes 
> every single time it encounters any bug... well, your customers 
> will not have a fun time.

Note that this assumes you're in a part of code where you can 
isolate and revert anything the error may cause. Roll back a 
database transaction, disconnect a client, abort their web page 
request, etc.
May 31, 2012
Re: Exception/Error division in D
On 05/31/12 00:21, Jonathan M Davis wrote:
> Now, it's perfectly possible to design code which never checks for null 
> pointers and if a null pointer is dereferenced throws an Exception and 
> attempts to recover from it (assuming that it's possible to detect the 
> dereference and throw at that point, which AFAIK is impossible with segfaults 
> - maybe it could be done on Windows with its Access Violations, but segfaults 
> trigger a signal handler, and you're screwed at that point). But writing code 

No, it's easily recoverable. That does not mean however that it would be a good
idea to map segfaults to exceptions as a language feature. And dereferencing a
null pointer is *not* guaranteed to trap, all you need is a large enough offset
and you will get silent data corruption.

  int i = 42;
  auto j = cast(size_t)&i;

  ubyte* p = null;
  p[j] = 13;
  assert(i!=42); // oops

artur
May 31, 2012
Re: Exception/Error division in D
On May 30, 2012, at 5:58 PM, "Kapps" <opantm2+spam@gmail.com> wrote:

> On Wednesday, 30 May 2012 at 22:22:01 UTC, Jonathan M Davis wrote:
>> On Thursday, May 31, 2012 00:01:16 deadalnix wrote:
>>> Most segfault are null deference or unintizialized pointer deference.
>>> Both are recoverable.
>> 
>> If you dereferenced a null pointer, it's a bug in your code. Your code is
>> assuming that the pointer was non-null, which was obviously incorrect, because
>> it was null. That's _not_ recoverable in the general case. Your code was
>> obviously written with the assumption that the pointer was non-null, so your
>> code is wrong, and so continuing to execute it makes no sense, because it's in
>> an invalid state and could do who-knows-what. If there's any possibility of a
>> pointer being null, the correct thing to do is to check it before
>> dereferencing it. If you don't, it's bug.
>> 
>> Now, it's perfectly possible to design code which never checks for null
>> pointers and if a null pointer is dereferenced throws an Exception and
>> attempts to recover from it (assuming that it's possible to detect the
>> dereference and throw at that point, which AFAIK is impossible with segfaults
>> - maybe it could be done on Windows with its Access Violations, but segfaults
>> trigger a signal handler, and you're screwed at that point). But writing code
>> which just assumes that pointers are non-null and will throw if they are null
>> is incredibly sloppy. It means that you're treating pointers like you'd treat
>> user input rather than as part of your code.
>> 
>> - Jonathan M Davis
> 
> All code has bugs in it. It's nice being notified about it and all, but if you release a server application, and it crashes every single time it encounters any bug... well, your customers will not have a fun time.

It's worth noting that Google apps abort on error. For server apps, a process crash is often designed to be invisible to the client, as much to allow seamless code upgrades as anything.
May 31, 2012
Re: Exception/Error division in D
On 5/30/2012 5:58 PM, Kapps wrote:
> All code has bugs in it. It's nice being notified about it and all, but if you
> release a server application, and it crashes every single time it encounters any
> bug... well, your customers will not have a fun time.

The correct response to a server app crashing is to restart it, not attempt to 
keep a program in an invalid state running.

Attempting to continue normal operation of a program that has entered an invalid 
state is bad news from front to back. It is wrong wrong wrong wrong.
May 31, 2012
Re: Exception/Error division in D
On 5/30/2012 2:32 AM, Don Clugston wrote:
> In fact, generally, the point of an AssertError is to prevent the program from
> entering an invalid state.

It's already in an invalid state when the assert fails, by definition.

It is not recoverable. The only option is a more or less graceful shutdown.
May 31, 2012
Re: Exception/Error division in D
On 5/30/2012 8:05 AM, Steven Schveighoffer wrote:
> I'd classify errors/exceptions into three categories:
>
> 1. corruption/segfault -- not recoverable under any reasonable circumstances.
> Special cases exist (such as a custom paging mechanism).
> 2. program invariant errors (i.e. assert errors) -- Recovery is not defined by
> the runtime, so you must do it manually. Any decision the runtime makes will be
> arbitrary, and could be wrong.
> 3. try/catch exceptions -- these are planned for and *expected* to occur because
> the program cannot control it's environment. e.g. EOF when none was expected.


A recoverable exception is NOT a logic bug in your program, which is why it is 
recoverable.

If there is recovery possible from a particular assert error, then you are using 
asserts incorrectly. Assert errors occur because your program has entered an 
unanticipated, invalid state. There's no such thing as knowing how to put it 
back into a valid state, because you don't know where it went wrong and how much 
is corrupted, etc.
May 31, 2012
Re: Exception/Error division in D
On 2012-05-30 23:16, Jonathan M Davis wrote:

> You can catch them to print out additional information or whatever is useful
> to generate more information about the Error. In fact, just what the Error
> gives you is already more useful: message, file, line number, stack trace, etc.
> That alone makes an Error more useful than a halt instruction.

If I recall correctly you has been arguing that Errors shouldn't be 
catchable, as they are today, and this needed to be fixed. Hmm, or was 
that Steven.

> You can catch them to attempt explicit cleanup that absolutely must be done
> for whatever reason (with the knowledge that it's potentially dangerous to do
> that cleanup due to the Error).
>
> You can catch them in very controlled circumstances where you know that
> continuing is safe (obviously this isn't the sort of thing that you do in
> @safe code). For instance, in some restricted cases, that could be done with
> an OutOfMemoryError. But when you do that sort of thing you have to catch the
> Error _very_ close to the throw point and be sure that there's no cleanup code
> in between. It only works when you can guarantee yourself that the program
> state is not being compromised by the Error, and you're able to guarantee that
> continuing from the catch point is safe. That works in some cases with
> AssertError in unit test code but becomes problematic as such code becomes
> more complex.

I'm mostly interested in letting the user know something went wrong and 
then exit the application.

-- 
/Jacob Carlborg
1 2 3 4 5 6 7 8
Top | Discussion index | About this forum | D home