On 2013-05-27 10:30, Sindhi Sindhi wrote:
Hello,

Is there a way to handle the exceptions (access violation, heap corruption
etc) thrown by an output filter module within the module itself so that it
does not propagate till the httpd.exe server resulting in a server crash?

The C++ output filter module that I have written makes use of native memory
allocation methods like     malloc/new in some cases. I have not used the
APR request pool here since the allocations in these  methods are very much
short lived and are called many times within a single request. So rather
than waiting for the request completion and then the pool manager releasing
this memory, I'm using native new/delete calls to do the
allocation/deallocation so that I can release the memory immediately after
use.

The issue is, in some rare case scenarios I saw a httpd.exe crash that was
due to heap corruption and access violation during new/delete calls in
these methods. Is there a way I can gracefully handle these within the
module by catching such exceptions and trying to handle them, rather
that propagating this exception resulting in httpd.exe crash?

Worst case even if no filtering happened due to a crash in the module, I'd
prefer that the filter sent back the original data (that was passed to the
filter when the filter callback was made by the server) down the filter
chain, ofcourse after logging this information for later troubleshooting.


Heap corruption/access violation are, most likely, due to bugs in your code. These kind of errors are totally different from an out-of-memory error, for example. Also they give you a high degree of uncertainty about what you're doing and unpredictibility regarding the impacts. It's a very bad idea to tolerate them.

If you corrupt some pointers in your structures only, then let us say that you could tolerate them, not in principle, as I strongly advise against, but at least technically.

However, if you corrupt some pointers in the structures of apache that apache reuses for other requests (for example the server_rec, or the conf pool, or the array of pointers to module configuration objects), then tolerating these kind of errors is impossible, even from a technical point of view.

In the first case (when only your structures are corrupt), you could catch (at least in Unix) the signal that Unix throws when it detects such a violation. But even then your options are limited, because you have no idea what you can do without reproducing the violation in the violation handler! You can't rely on your data.

(I don't know how these violations are caught in Windows, but I am sure they can be caught.)

However, if you corrupted apache's structures, the access violation may occur later, not when apache runs your code, but when it runs its code or 3rd party code. Then again, in your handler you would not have any clue where the violation comes from and how to handle it.


So my advice is to debug your code. Compile it with debug symbols, execute it in a debugger, reproduce the scenarios in which it crashes.

If the errors occur only occasionally, then I suspect one of the following cases:

*) concurrency problems. To check for this, start running your module at low throughput and steadily increase the throughput. If the error rate is low at the beginning but increases with throughput, then it could be a concurrency problem. You could also start apache with a single thread. If it never crashes with a single thread, then again it could be a concurrency problem. Check if the libs that you use are thread-safe or not.

*) data-related problem. Run the same request at high throughput. If it never crashes, then maybe it is not a concurrency error, but rather dependent on the data that you use for testing. So it could be an algorithmic problem in your filter.

*) Try to test your corner cases, especially the case is which a string to replace is broken between two invocations of the filter. Think of the scenario in which the string to replace is contained in _3_ different buffers.

Sorin

Reply via email to