RejectedSoftware Forums

Sign up

Pages: 1 2

Have vibe.d continue to operate on out-of-bounds error?

I just found that vibe.d crashes completely when a fiber tries to access
an OOB element of an array. This was a programing error and not a memory
corruption.

Other exceptions will just print an exception to the web page and
continue running. With a web server, it's kind of expected that any
error in a web page will not bring down the whole thing. Is there a way
to specifically catch RangeError and continue to run?

-Steve

Re: Have vibe.d continue to operate on out-of-bounds error?

On Tue, 30 May 2017 09:54:19 -0400, Steven Schveighoffer wrote:

I just found that vibe.d crashes completely when a fiber tries to access
an OOB element of an array. This was a programing error and not a memory
corruption.

Other exceptions will just print an exception to the web page and
continue running. With a web server, it's kind of expected that any
error in a web page will not bring down the whole thing. Is there a way
to specifically catch RangeError and continue to run?

-Steve

The big problem is that a RangeError that gets thrown within a call stack that contains nothrow functions can cause struct destructors on the stack to get skipped. So basically, unless it can be proven that no such construct exists, the process must be considered to be in a corrupted state after any Error has been thrown.

So really only the application can "safely" decide to catch RangeError in situations where it is clear that this won't cause any issues.

Re: Have vibe.d continue to operate on out-of-bounds error?

On 5/30/17 10:10 AM, Sönke Ludwig wrote:

On Tue, 30 May 2017 09:54:19 -0400, Steven Schveighoffer wrote:

I just found that vibe.d crashes completely when a fiber tries to access
an OOB element of an array. This was a programing error and not a memory
corruption.

Other exceptions will just print an exception to the web page and
continue running. With a web server, it's kind of expected that any
error in a web page will not bring down the whole thing. Is there a way
to specifically catch RangeError and continue to run?

The big problem is that a RangeError that gets thrown within a call stack that contains nothrow functions can cause struct destructors on the stack to get skipped. So basically, unless it can be proven that no such construct exists, the process must be considered to be in a corrupted state after any Error has been thrown.

So really only the application can "safely" decide to catch RangeError in situations where it is clear that this won't cause any issues.

Ugh, good point.

So this means I basically have to manually turn range errors into
exceptions (i.e. convert builtin arrays to something that throws on
indexing), or somehow auto-restart the server on crashing. Annoying...

I'll drum up a discussion on the main forums about this. It doesn't seem
like something that is easy to solve, and seems like a harsh penalty to
pay for a simple invalid index.

-Steve

Re: Have vibe.d continue to operate on out-of-bounds error?

On Tue, 30 May 2017 12:08:43 -0400, Steven Schveighoffer wrote:

Ugh, good point.

So this means I basically have to manually turn range errors into
exceptions (i.e. convert builtin arrays to something that throws on
indexing), or somehow auto-restart the server on crashing. Annoying...

You should have something auto-restarting the server anyway :)

I'll drum up a discussion on the main forums about this. It doesn't seem
like something that is easy to solve, and seems like a harsh penalty to
pay for a simple invalid index.

Oh, errors vs exceptions again. That will be a, fun discussion :)

/Jacob Carlborg

Re: Have vibe.d continue to operate on out-of-bounds error?

On 5/31/17 5:01 AM, Jacob Carlborg wrote:

On Tue, 30 May 2017 12:08:43 -0400, Steven Schveighoffer wrote:

Ugh, good point.

So this means I basically have to manually turn range errors into
exceptions (i.e. convert builtin arrays to something that throws on
indexing), or somehow auto-restart the server on crashing. Annoying...

You should have something auto-restarting the server anyway :)

I added it as a service to my systemd startup. I'm very new to systemd,
so I'm not sure how to get it to restart automatically.

I'll drum up a discussion on the main forums about this. It doesn't seem
like something that is easy to solve, and seems like a harsh penalty to
pay for a simple invalid index.

Oh, errors vs exceptions again. That will be a, fun discussion :)

The aspect of this is that you may have an off-by-one error that is
about to corrupt memory, but doesn't actually because you have bounds
checking. Does this mean we must crash the entire application? D gives
us no choice. We must treat the simple 'index is bad' error as 'the
entire memory could be corrupt'.

Thinking some more about it, we can't really make them exceptions,
because then nothrow code becomes nearly impossible to write, or as
painful as writing Java code. Likely the only good solution is to make
custom array types. That comes with its own problems.

Bottom line is, if I compare vibe.d to other frameworks, none of them
actually crash the web server for an out-of-bounds error. I find the
situation very awkward. Restarting the whole server seems like a huge
penalty.

-Steve

Re: Have vibe.d continue to operate on out-of-bounds error?

On 2017-05-31 14:44, Steven Schveighoffer wrote:

I added it as a service to my systemd startup. I'm very new to systemd,
so I'm not sure how to get it to restart automatically.

This seems to be a good tutorial for System V, Upstart and systemd init
systems [1].

Bottom line is, if I compare vibe.d to other frameworks, none of them
actually crash the web server for an out-of-bounds error. I find the
situation very awkward.

The languages that these other frameworks are written in don't have the
same distinction of exceptions and errors as D has, in my experience.
Certainly not any framework written in Ruby, where the only way that can
happen if there's a bug in the interpreter.

[1]
https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples

/Jacob Carlborg

Re: Have vibe.d continue to operate on out-of-bounds error?

On Tue, 30 May 2017 09:54:19 -0400, Steven Schveighoffer wrote:

Other exceptions will just print an exception to the web page and
continue running. With a web server, it's kind of expected that any
error in a web page will not bring down the whole thing. Is there a way
to specifically catch RangeError and continue to run?

Why don't you wrap the request handler into a try-catch block?

void foo(HTTPServerRequest req, HTTPServerResponse res)
{
   string[string] map = [
      "eins": "one"
   ];
   res.writeBody (map["9"]);
}

T wrap(T) (T f)
{
   return (HTTPServerRequest i, HTTPServerResponse j) {
      try
         f (i, j);
      catch (Throwable) {
         import std.stdio;
         stderr.writeln ("caught something");
      }
   };
}
...
   router.get("/test", toDelegate (&foo).wrap);
...

Re: Have vibe.d continue to operate on out-of-bounds error?

Am 02.06.2017 um 00:01 schrieb Stefan:

On Tue, 30 May 2017 09:54:19 -0400, Steven Schveighoffer wrote:

Other exceptions will just print an exception to the web page and
continue running. With a web server, it's kind of expected that any
error in a web page will not bring down the whole thing. Is there a way
to specifically catch RangeError and continue to run?

Why don't you wrap the request handler into a try-catch block?

void foo(HTTPServerRequest req, HTTPServerResponse res)
{
   string[string] map = [
      "eins": "one"
   ];
   res.writeBody (map["9"]);
}

T wrap(T) (T f)
{
   return (HTTPServerRequest i, HTTPServerResponse j) {
      try
         f (i, j);
      catch (Throwable) {
         import std.stdio;
         stderr.writeln ("caught something");
      }
   };
}
...
   router.get("/test", toDelegate (&foo).wrap);
...

Definitely a possibility as long as it is absolutely certain that no
RAII is going on within the try block and as long as the compiler still
supports catching Errors.

Re: Have vibe.d continue to operate on out-of-bounds error?

On Wed, 31 May 2017 08:44:55 -0400, Steven Schveighoffer wrote:

Thinking some more about it, we can't really make them exceptions,
because then nothrow code becomes nearly impossible to write, or as
painful as writing Java code.

This is one of the reasons why I will never try to do any commercial web jobs with D again. We so badly want to write nothrow code (WHY??), so let's make the language completely inappropriate for web programming! In fact, the current std library implementation destroyed the declared difference between the Error and the Exception. The standard library just overfilled by asserts(), so it needs a lot of work to make it more or less tolerant to really recoverable errors. I don't think it will happen. :(

Re: Have vibe.d continue to operate on out-of-bounds error?

Am 30.06.2017 um 17:49 schrieb Alexey Kulentsov:

On Wed, 31 May 2017 08:44:55 -0400, Steven Schveighoffer wrote:

Thinking some more about it, we can't really make them exceptions,
because then nothrow code becomes nearly impossible to write, or as
painful as writing Java code.
This is one of the reasons why I will never try to do any commercial web jobs with D again. We so badly want to write nothrow code (WHY??), so let's make the language completely inappropriate for web programming! In fact, the current std library implementation destroyed the declared difference between the Error and the Exception. The standard library just overfilled by asserts(), so it needs a lot of work to make it more or less tolerant to really recoverable errors. I don't think it will happen. :(

I agree that this is can be very painful at times. Personally, I can
tolerate range errors and assertions, but the ones that are just an
artifact of the particular GC implementation (OutOfMemoryError and
`InvalidMemoryOperationErrors') really bother me.

But I think it would be sensible to add a compiler option to make
catching Error always safe on a low level (i.e. to always insert stack
cleanup code, even in nothrow functions). It would be a performance
trade-off that everyone can decide on on their own. Of course, this
would still leave GC errors as unsafe, because the implementation lacks
the proper cleanup logic.

For everything else it would be correct to just drop the current fiber
and to assume that other fibers (or threads) are unaffected, as long as
no shared data is affected.

Pages: 1 2