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

Reply via email to