Thankyou. On Mon, May 27, 2013 at 2:38 PM, Sorin Manolache <sor...@gmail.com> wrote:
> 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 > >