DLL Hell - gracefull handling/app termination

  • Thread starter Thread starter Susan Baker
  • Start date Start date
S

Susan Baker

Hi,

I am writing a Win32 DLL. I want to be able to handle any SEGVs
(segmentation violations) gracefully, by using an error handler of sorts.

Currently, if a user of my DLL (typically a VB programmer) passes a null
(or invalid) pointer to my library - the entire application crashes,
leaving shared memory, database connections etc in a "dirty" state. I
would like a way of gracefully handling user "actions" like this -
without crashing spectacularly.

Any help much appreciated.
 
Susan Baker said:
I am writing a Win32 DLL. I want to be able to handle any SEGVs
(segmentation violations) gracefully, by using an error handler of sorts.

Currently, if a user of my DLL (typically a VB programmer) passes a null
(or invalid) pointer to my library - the entire application crashes,
leaving shared memory, database connections etc in a "dirty" state. I
would like a way of gracefully handling user "actions" like this - without
crashing spectacularly.

Any help much appreciated.

This is tricky business.

On the one hand one make the case that case that arguments past from those
who are prone to error should be checked. So, faced with a pointer p, one
might write:

if ( p == 0 )
// do some error / exception handling

else
{
// do some more checks
}

Now you know it is not null pointer that you are dealing with. But it might
be a "wild" pointer. So, one can make the case that pointers should be
checked with IsBadStringPtr() or one of its cousins. (Note that these
functions are _slow_).

If that check passes you know the pointer is good. Well, maybe. It is
possible that the pointer is valid, but the length it uses extends past the
length of the object to which it points and "overflows" into whatever
happens to be adjacent in memory - ( and heaven help us if the adjacent
locations are on the stack).

You could design your objects such that their first data member has a size
indicator and force your callers to set a size it.

But then how do you know that they set it properly? So, where do you draw
the line? How many tests do you make and how can you be sure bad things
won't happen?

You can use what is called structured exception handling

http://msdn.microsoft.com/library/d.../debug/base/structured_exception_handling.asp

to detect such things. With it you write "guarded" sections a filter and an
exception block

// Guarded section

__try
{
}

__except ( /* simple filter */ EXCEPTION_EXCEUTE_HANDLER )
{
// exception block cleans up
}

You try the iffy operation in the guarded section.

If something bad happens control passes to the filter. It returns an
indication of what to do next. Above, I unconditionally pass control to the
exception handler.

Then the exception handler tries to recover.

It sounds promising, and it is, but it is not a cure-all. That's because by
the time something really bad has happened your application's state may be
trashed to such an extent that continuing only makes things worse.

One strategy is to report the error, print a crash dump with
MiniDumpWriteDump() and find the guilty developer and chain him/her to the
desk until the bug is fixed.

Note that I am making the assumption that your application is more C than
C++ because you permit VB callers. If I am wrong there are another set of
issues to deal with.

In short, there really is no defense against bad programming. Sadly
applications can and will crash when written sloppily. I've sketched one way
to address the problem along the lines of your question.

Better solutions are at the language and environment level. Some would say
that in modern C++ there should be no "naked" pointers. Of course that's a
problem if your clients are written in VB. And the .Net platform tries to
hide pointers as much as possible.

Regards,
Will
 
William said:
This is tricky business.

On the one hand one make the case that case that arguments past from those
who are prone to error should be checked. So, faced with a pointer p, one
might write:

if ( p == 0 )
// do some error / exception handling

else
{
// do some more checks
}

Now you know it is not null pointer that you are dealing with. But it might
be a "wild" pointer. So, one can make the case that pointers should be
checked with IsBadStringPtr() or one of its cousins. (Note that these
functions are _slow_).

If that check passes you know the pointer is good. Well, maybe. It is
possible that the pointer is valid, but the length it uses extends past the
length of the object to which it points and "overflows" into whatever
happens to be adjacent in memory - ( and heaven help us if the adjacent
locations are on the stack).

You could design your objects such that their first data member has a size
indicator and force your callers to set a size it.

But then how do you know that they set it properly? So, where do you draw
the line? How many tests do you make and how can you be sure bad things
won't happen?

You can use what is called structured exception handling

http://msdn.microsoft.com/library/d.../debug/base/structured_exception_handling.asp

to detect such things. With it you write "guarded" sections a filter and an
exception block

// Guarded section

__try
{
}

__except ( /* simple filter */ EXCEPTION_EXCEUTE_HANDLER )
{
// exception block cleans up
}

You try the iffy operation in the guarded section.

If something bad happens control passes to the filter. It returns an
indication of what to do next. Above, I unconditionally pass control to the
exception handler.

Then the exception handler tries to recover.

It sounds promising, and it is, but it is not a cure-all. That's because by
the time something really bad has happened your application's state may be
trashed to such an extent that continuing only makes things worse.

One strategy is to report the error, print a crash dump with
MiniDumpWriteDump() and find the guilty developer and chain him/her to the
desk until the bug is fixed.

Note that I am making the assumption that your application is more C than
C++ because you permit VB callers. If I am wrong there are another set of
issues to deal with.

In short, there really is no defense against bad programming. Sadly
applications can and will crash when written sloppily. I've sketched one way
to address the problem along the lines of your question.

Better solutions are at the language and environment level. Some would say
that in modern C++ there should be no "naked" pointers. Of course that's a
problem if your clients are written in VB. And the .Net platform tries to
hide pointers as much as possible.

Regards,
Will

Very informative post.

Many thanks.

Regards,

Sue
 
Back
Top