-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Darren New wrote:
> Christopher Smith wrote:
>> No, but you'd probably want that CGI script's process to die and core
>> dump, while the web server goes about its business. 
> 
> Right. Or, I could use a safe language in a sandbox, and not dump core
> at all, but rather be able to provide a nice message back to the
> customer saying what happened, and etc.

Well, you could provide a nice message back to the customer, or you
could be presenting them with someone else's credit card number. ;-)

> Either way works. You're either writing the code in your own process
> space, or you're writing it in the kernel's process space. I don't see a
> compellingly good reason to pick one over the other globally.

Because you've detected an unexpected error in your own process. It
*could* be that the kernel is messed up and won't know how to deal with
things properly, in which case whatever you do in your own process would
get messed up anyway, but you have a good chance that the problem only
exists in your process.

>> This is exactly what I described as happening with our systems. Why
>> does everyone think dumping core is the end of the world?
> 
> I don't. I just prefer to use a safe language where I'm in charge of
> dumping core, *and* where when something happens that shouldn't, I know
> I *do* get an error.

Huh? How do you know that you'll get an error when something happens
that shouldn't?

>> Okay, if the OS can't clean up file handles, sockets, and memory when
>> your process dies, I very much doubt you're going to have much luck
>> doing so in some catch block. Similarly for your database with
>> database transactions. Seriously, process death is about as safe a way
>> as you can find to clean up from an undefined error.
> 
> I'm not sure I agree. Of course, if that's the goal, then certainly
> after you do application-specific cleanup, you can exit your process and
> do all the stuff you want too.
> 
> But if you don't have a way to catch errors in the first place (such as
> array bounds checking, bounds checking on integers, and so on)

I assure you that C++ is capable of doing such things. Oddly enough,
even if a language doesn't require such things there is nothing to stop
a programmer from ensuring it. Indeed, most languages that automatically
do array bounds checking, bounds checking on integers, and so on are
written in C or C++. ;-) It's nice when a language does this stuff for
you, although it can be annoying when you can't turn it off when it gets
in your way, but then you can always switch to an unsafe language. ;-)

>> Yes, because your interpreter/compiler is inherently having to trust
>> all kinds of other code beyond the OS to be implemented correctly.
> 
> Like what?  Mind doesn't.

What is this magical tool?

>> Most of that code doesn't have a good way to work from the "I don't
>> trust any of this stuff" perspective, nor has it been tested in that
>> regard nearly as much.
> 
> Um, I'd have to disagree, I think.
> 
> If you're relying on a core dump to detect an error, my process will
> dump core in exactly the same way as yours does if there's an error in
> stdio or something.

Nah, 'cause your code will turn it in to an IO exception or a null
pointer exception, etc., unwind the stack a bit until it thinks it can
start all over again.

>> Sure, but there are far more subtle errors that pretty much or only
>> going to show up in the form of your code finding itself in an
>> unexpected state.
> 
> Certainly. I've had bad sectors in swap space.

That is not exactly a subtle error.

>>> There are some errors you don't bother trying to recover from
>>> automatically. (Altho that last one I actually wrote a script to
>>> recover from.)
>> I couldn't agree more. Unexpected errors are very dangerous to try to
>> recover from, particularly because by their very nature you can't be
>> sure whether you really have a recoverable problem or not. Even
>> exiting a process is no guarantee, but it is probably the best you can
>> do.
> 
> Yeah. But the error of "division by zero actually means I overwrote my
> socket descriptors" isn't high on the list of likely suspects.

No, but you probably have two issues to consider: 1) my math is totally
broken, and I gotta stop what I'm doing, figure out how exactly how this
happened, and fix it before all hell breaks loose or 2) some kind of bug
in the "unsafe" portion of the code has put my entire program in an
unsafe state, so notions of safety are now out the window and I gotta
stop what I'm doing, figure out exactly how this happened, and fix it
before all hell breaks loose. Oddly enough, the results are the same.

>> Why do you need a range-checking language? 
> 
> Because running outside an array is a huge cause of errors, and if I can
> have my language or compiler check that instead of doing it by hand,
> it's both more efficient and safer.

Hmm... let me place some emphasis in that sentence for clarity:

Why do you need a range-checking *language*.

>> How about a range checking range? 
> 
> I'm not sure what that means, but I'd certainly appreciate if my range
> checked my ranges and turned down the heat instead of boiling over.

hehe.

In C++ it is not at all uncommon for folks to use collections and
iterators that do range checking. It is done in the library, rather than
in the language, following the pearl of wisdom that if you can do
something in a library instead of the syntax of a language, it's a good
thing.

>> Is there some magic that comes from having a range-checking
>> language that calls down to code in a non-range checking language vs.
>> uses a range-checked iterator that calls down to code written in a
>> non-range checked language?
> 
> Is there some magic in using an OO language instead of
> structures-with-function-pointers? Is there some magic in using Lint? Is
> there some magic in implementing "automatic pointers"?
> 
> Answer: Yes, in the same way there's magic in using device drivers
> instead of having every application code pokes to the hardware itself.

I think you missed my point. I'm not questioning that automatic range
checking is useful. I'm just questioning why it has to be embedded in to
the definition of the syntax of a programming language. I write C++ code
that automatically checks against range boundaries, null pointers,
integer overflows and all kinds of other badness. Indeed by doing so I
can automatically catch a lot of errors that go undetected in a number
of "safe" languages without manual coding.

>> Because I've been burned by people doing exactly this kind of well
>> intentioned coding far too often. Their stack has been corrupted, and
>> they don't realize it, so instead of simply failing, they try to
>> "recover" from the problem, only their stack is corrupted, so their
>> "recovery" that is supposed to just clean things up ends up setting
>> someone's account balance to zero, or causes the system that provably
>> can't deadlock to deadlock, etc.
> 
> Yes. That's why it really only works well for safe languages, which is
> the premise I at least was starting with.

Safe language != stack never gets corrupted. I can tell you this from a
lot of first hand experience.

> If you have an unexpected
> error in an unsafe language, you have no idea what state is screwed up.
> If you have an unexpected error in a safe language, you can, with high
> confidence, continue to use the infrastructure of the language, because
> as far as the *language* is concerned, it's not an error.

Actually, just the opposite. If I have a "safe" language, and I find a
value or condition that is defined to not be possible, I actually have
all the more reason to assume the worst.

> Is invoking a method on a null pointer in Java as bad as invoking a
> method on a null pointer in C++? No. Why? Because it's not an error to
> do that in Java.

template <typename T>
class Ptr {
public:
    Ptr(T* a) : ptr(a) {}
    Ptr(Ptr<T>& a) : ptr(a.ptr) {}
    T& operator*() const { return *operator->(); }
    T* operator->() const { if (nullptr == a) { throw
null_pointer_exception(); } return a; }
    bool operator==(const Ptr<T>& a) const { return ptr == a.ptr; }
    Ptr<T>& operator=(const Ptr<T>& a) { ptr = a.ptr; }

private:
    T* ptr;
};

Now you can avoid that error in C++ (not to mention abusing pointer
arithmetic). You're welcome.

>> I didn't say that good error handling can't be done, merely that if
>> you expectation is that you are recovering from a logical error, I'd
>> sure like the recovery code to be the product of some other
>> development process.
> 
> I'm not sure why recovery code at the top level of the stack needs to be
> held to a higher standard than recovery code lower down.

Well, it depends on what you mean by "lower down", but hopefully code
that is local to the error understands the nature of the problem and can
correct it or at least avoid it.

- --Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGbdGyOagjPOywMBARAsKXAJ9AzOoKUcXm0hLl43HeWHzAQViEiACfcExc
hnqS6vQ7cIQ/lY+YH111gp4=
=HGgQ
-----END PGP SIGNATURE-----

-- 
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg

Reply via email to