Return-Path: Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: (qmail 87380 invoked from network); 5 Jan 2005 00:07:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 5 Jan 2005 00:07:03 -0000 Received: (qmail 73988 invoked by uid 500); 5 Jan 2005 00:07:01 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 73943 invoked by uid 500); 5 Jan 2005 00:07:01 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 73778 invoked by uid 99); 5 Jan 2005 00:07:00 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: neutral (hermes.apache.org: local policy) Received: from mail08.syd.optusnet.com.au (HELO mail08.syd.optusnet.com.au) (211.29.132.189) by apache.org (qpsmtpd/0.28) with ESMTP; Tue, 04 Jan 2005 16:06:56 -0800 Received: from [192.168.69.126] (c211-30-78-105.belrs2.nsw.optusnet.com.au [211.30.78.105]) by mail08.syd.optusnet.com.au (8.12.11/8.12.11) with ESMTP id j0506pDX009526; Wed, 5 Jan 2005 11:06:52 +1100 Mime-Version: 1.0 (Apple Message framework v619) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: <97F95E22-5EAD-11D9-97F7-000D936DB8F4@algorithm.com.au> Content-Transfer-Encoding: 7bit Cc: Zentaro Kavanagh From: Andre Pang Subject: Bug with __stdcall modules on Windows Date: Wed, 5 Jan 2005 11:06:05 +1100 To: Apache httpd Developers X-Mailer: Apple Mail (2.619) X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Hi all, I've been writing some Apache 2.0 (HTTP Server) modules, and I've found a problem with Windows calling conventions. Apache assumes that the module is compiled with Windows' __cdecl calling convention. This is OK. If an Apache module is compiled with a __stdcall calling convention, the compiler should stop the compilation and prevent linking from taking place. However, the compiler merrily proceeds to compile and link things, resulting in a segfault at run-time. Normally, the compiler will catch the calling convention incompatibility, but this doesn't happen with APR because since the module is compiled with __stdcall, the Apache _headers_ (which are included by the module's source code) that declare the function prototypes are also assumed to be __stdcall. The bug fix is to put the __cdecl pragma directly into the APR/Apache headers, so that the compiler knows that any entry points into the module should be __cdecl. This is similar to how APR has an AP_MODULE_DECLARE_DATA macro which expands to __declspec(dllexport): what is needed is another macro (e.g. "APR_MODULE_ENTRY_POINT") which expands to __cdecl. I suspect that the right place to put this is in APR, but httpd may also need to have some of its headers changed. Since it's all a bit complex, I've pasted in some example code from my project which shows what I currently have to do, which may shed some light on what's happening. So, a standard module declaration which currently looks like this: module AP_MODULE_DECLARE_DATA timeslice_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ NULL, /* table of config file commands */ foo_register_hooks /* register hooks */ }; When a module is compiled as __stdcall, the foo_register_hooks function is thus assumed to be __stdcall, when it should really be __cdecl, since that's what Apache expects. To solve this, I've added a macro to declare the function as __cdecl: #ifdef WIN32 # define AP_MODULE_ENTRY_POINT __cdecl #else # define AP_MODULE_ENTRY_POINT #endif static void AP_MODULE_ENTRY_POINT foo_register_hooks(apr_pool_t *p) { ap_hook_handler(foo_handler, NULL, NULL, APR_HOOK_MIDDLE); } Note that foo_register_hooks registers foo_handler as an ap_hook_handler, which means that foo_handler also has to be declared __cdecl (since it's a direct entry point into the module, called by Apache). This doesn't quite work however, because foo_handler is declared to be of the ap_HOOK_handler_t type. Since the ap_HOOK_handler_t typedef is declared in the Apache headers files without __cdecl, the compiler type-checks ap_HOOK_handler_t as __stdcall (because the header files are included by the module, and since the module is compiled with __stdcall, any header declarations are also presumed to be __stdcall). I'm currently "solving" this problem by type-casting the function argument to ap_hook_handler as __stdcall (which is actually a lie!), like so: #ifdef WIN32 # define AP_HOOK_HANDLER_FUNCTION(x) (ap_HOOK_handler_t (__stdcall *)) x #else # define AP_HOOK_HANDLER_FUNCTION(x) x #endif static void AP_MODULE_ENTRY_POINT foo_register_hooks(apr_pool_t *p) { ap_hook_handler(AP_HOOK_HANDLER_FUNCTION(foo_handler), NULL, NULL, APR_HOOK_MIDDLE); } This forces the compiler to think that foo_handler is an __stdcall so it can be used as a parameter to ap_hook_handler, thus complying with the incorrect header file declarations. The same problem exists for any function arguments in the module declaration. I think the proper solution is to: * Add an AP_MODULE_ENTRY_POINT macro to declare direct function entry points into a module, similar to how AP_MODULE_DECLARE_DATA is needed for module declarations. Or, change the AP_MODULE_DECLARE_NONSTD macro so that it contains __cdecl on Windows. * Modify the ap_HOOK_handler_t typedef in FOO.h so that any function parameters are __cdecl. * Similarly, modify the module typedef in BAR.h so that any function parameters are __cdecl. I'd offer a patch, but I can't find where the module/ap_HOOK_handler_t typedefs are in the Apache header files. Can anybody assist me here? A complete example can be found at http://trac.xiph.org/cgi-bin/trac.cgi/browser/trunk/oggdsf/src/tools/ mod_timeslice/ for those interested. In particular, see the mod_timeslice.cpp and apr_stdcall.h files. -- % Andre Pang : trust.in.love.to.save