Problems with compilation of user-defined C functions for PostgreSQL 8.3.0 - Mailing list pgsql-hackers

From Denis Vnukov @ Nabble
Subject Problems with compilation of user-defined C functions for PostgreSQL 8.3.0
Date
Msg-id B1484F2033E549E1BD66F36C6A856209@dvhome
Whole thread Raw
List pgsql-hackers
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

pgsql-hackers by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: Better error message for select_common_type()
Next
From: Robert Lor
Date:
Subject: Re: [COMMITTERS] pgsql: Enable probes to work with Mac OS X Leopard and other OSes that