Hi, I am trying to create a kind of simple procedural language for PostgreSQL. The first version was compiled with MinGW/gcc for PostgreSQL 8.2.6 and it worked OK.
When PostgreSQL 8.3.0 was shipped, I tried to recompile all my code for this version, but it didn't work (almost every Postgres call crashed the server with exception 0xC0000005). I recompiled the code with msvc++ but without much success - the server still crashes. I removed almost all the code from the project and still cannot make it work. Here's the simplest example: ------------------------------------------------------------------------------------------------------------------------- e.c: #include "executor/spi.h" #include "fmgr.h" #include "funcapi.h" #include "postgres.h" #include "access/heapam.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "commands/trigger.h" #include "storage/ipc.h" #include "utils/date.h" #include "utils/syscache.h" /* * Compiled and tested only without HAVE_INT64_TIMESTAMP option */ #ifdef HAVE_INT64_TIMESTAMP #error not implemented with HAVE_INT64_TIMESTAMP option #endif /* * Include the 'magic block' that PostgreSQL 8.2 and up will use to ensure * that a module is not loaded into an incompatible server. */ #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif /* * Function handler implementation */ extern Datum my_call_handler(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(my_call_handler); Datum my_call_handler(PG_FUNCTION_ARGS) { Datum retval = 0; ereport(LOG, (errmsg("::0"))); PG_TRY(); { ereport(LOG, (errmsg("::1"))); } PG_CATCH(); { ereport(LOG, (errmsg("::2"))); } PG_END_TRY(); ereport(LOG, (errmsg("::3"))); return retval; } ------------------------------------------------------------------------------------------------------------------------- build.cmd: @echo off SET PG_INC=c:\utils\PostgreSQL\src\postgresql-8.3.0\src\include SET PG_LIB=c:\utils\PostgreSQL\8.3\lib call "c:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat" x86 rem include postgres files SET INCLUDE=%PG_INC%\port\win32_msvc;%INCLUDE% SET INCLUDE=%PG_INC%\port\win32;%INCLUDE% SET INCLUDE=%PG_INC%;%INCLUDE% echo Compiling... cl /nologo /c /O2 /EHsc /W4 /MD /wd4127 /wd4100 /D ENABLE_THREAD_SAFETY /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WIN32__" /D "EXEC_BACKEND" /D WIN32_STACK_RLIMIT=4194304 /D "BUILDING_DLL" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_USE_32BIT_TIME_T" e.c if ERRORLEVEL 1 goto lError echo Linking... link kernel32.lib user32.lib advapi32.lib shfolder.lib wsock32.lib secur32.lib /nologo /subsystem:windows /dll /incremental:no /machine:i386 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:uuid.lib /NODEFAULTLIB:OLDNAMES.lib /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib /MANIFEST:NO /EXPORT:my_call_handler /OUT:e.dll *.obj %PG_LIB%\postgres.lib if ERRORLEVEL 1 goto lError echo Done :lError pause ------------------------------------------------------------------------------------------------------------------------- test.sql: DROP FUNCTION my_call_handler() CASCADE; CREATE FUNCTION my_call_handler() RETURNS language_handler AS E'e' LANGUAGE C; CREATE TRUSTED LANGUAGE e HANDLER my_call_handler; CREATE FUNCTION e_test() RETURNS int AS $$ nothing $$ LANGUAGE e; SELECT e_test(); When I run test.sql, I get the following output in data\pg_log: 2008-03-18 20:32:59 EET LOG: database system was shut down at 2008-03-18 20:32:56 EET 2008-03-18 20:32:59 EET LOG: database system is ready to accept connections 2008-03-18 20:33:00 EET LOG: autovacuum launcher started 2008-03-18 20:34:19 EET NOTICE: drop cascades to language e 2008-03-18 20:34:19 EET NOTICE: drop cascades to function e_test() 2008-03-18 20:34:19 EET LOG: ::0 2008-03-18 20:34:19 EET STATEMENT: DROP FUNCTION my_call_handler() CASCADE; CREATE FUNCTION my_call_handler() RETURNS language_handler AS E'e' LANGUAGE C; CREATE TRUSTED LANGUAGE e HANDLER my_call_handler; CREATE FUNCTION e_test() RETURNS int AS $$ nothing $$ LANGUAGE e; SELECT e_test(); 2008-03-18 20:34:23 EET LOG: server process (PID 4084) was terminated by exception 0xC0000005 2008-03-18 20:34:23 EET HINT: See C include file "ntstatus.h" for a description of the hexadecimal value. 2008-03-18 20:34:23 EET LOG: terminating any other active server processes 2008-03-18 20:34:23 EET WARNING: terminating connection because of crash of another server process 2008-03-18 20:34:23 EET DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. 2008-03-18 20:34:23 EET HINT: In a moment you should be able to reconnect to the database and repeat your command. 2008-03-18 20:34:23 EET WARNING: terminating connection because of crash of another server process 2008-03-18 20:34:23 EET DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. 2008-03-18 20:34:23 EET HINT: In a moment you should be able to reconnect to the database and repeat your command. 2008-03-18 20:34:23 EET LOG: all server processes terminated; reinitializing 2008-03-18 20:34:24 EET FATAL: pre-existing shared memory block is still in use 2008-03-18 20:34:24 EET HINT: Check if there are any old server processes still running, and terminate them. After commenting out PG_TRY/PG_CATCH/PG_END_TRY the code works ok. When I looked into PG_TRY macros, I found out that the following line crashes the server: do { sigjmp_buf *save_exception_stack = PG_exception_stack; ErrorContextCallback *save_context_stack = error_context_stack; sigjmp_buf local_sigjmp_buf; if (sigsetjmp(local_sigjmp_buf, 0) == 0) { PG_exception_stack = &local_sigjmp_buf; /* !!! this line crashes the server !!! */ MSVC++ version is Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86. I'm working on Vista. It would be great if you could help me with this. Thanks, Denis