Return-Path: X-Original-To: apmail-httpd-modules-dev-archive@minotaur.apache.org Delivered-To: apmail-httpd-modules-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4DE21E8ED for ; Mon, 27 May 2013 09:09:46 +0000 (UTC) Received: (qmail 48151 invoked by uid 500); 27 May 2013 09:09:45 -0000 Delivered-To: apmail-httpd-modules-dev-archive@httpd.apache.org Received: (qmail 47969 invoked by uid 500); 27 May 2013 09:09:44 -0000 Mailing-List: contact modules-dev-help@httpd.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: modules-dev@httpd.apache.org Delivered-To: mailing list modules-dev@httpd.apache.org Received: (qmail 47873 invoked by uid 99); 27 May 2013 09:09:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 May 2013 09:09:40 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of sorinm@gmail.com designates 209.85.214.44 as permitted sender) Received: from [209.85.214.44] (HELO mail-bk0-f44.google.com) (209.85.214.44) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 May 2013 09:09:33 +0000 Received: by mail-bk0-f44.google.com with SMTP id jc3so3591036bkc.31 for ; Mon, 27 May 2013 02:09:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=LyXl9NJxag08LuFZ0sX5QHuj7uU9V8V68Ox+jlTb5gc=; b=EqvukpkTGTz3asmACFJXT5ZGytlAY4XVKl6KbU5aKDd8q8b5R0beFIPQ3Ux2gWwF3d 5MMeFm+VE6W4/okjCMARmOU80fUbLSiw2lO0LGjAtxGHXGeJokDJdwShqabxW8Y9VvgP sHD5/pMQscrIIbkwRfN4NqZ+a39Xf8QuF0uxw+1NoT2pC0QYSPbXRQUoxTpXSwjjnup4 UyGvKns+fBly50Nt+CjXj2XBRHt2juS1y4duIGUjcBh2y+adb75TB9SbN3v/BIUOhU7y lwo/g1tiZ1QCVwQ3NifUgU2pxqxDlwggRx3uux7fhItb1gWGkhOhkBTOpPIvNPwcVjMJ asFw== X-Received: by 10.205.107.202 with SMTP id dz10mr2634594bkc.180.1369645753425; Mon, 27 May 2013 02:09:13 -0700 (PDT) Received: from ?IPv6:2a01:c9c0:a1:15:213:72ff:fe38:2e23? ([2a01:c9c0:a1:15:213:72ff:fe38:2e23]) by mx.google.com with ESMTPSA id so13sm7966574bkb.15.2013.05.27.02.09.11 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 27 May 2013 02:09:12 -0700 (PDT) Message-ID: <51A3229A.20804@gmail.com> Date: Mon, 27 May 2013 11:08:42 +0200 From: Sorin Manolache User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130518 Icedove/17.0.5 MIME-Version: 1.0 To: modules-dev@httpd.apache.org Subject: Re: Module exceptions can be handled before it crashes httpd? References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org 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