From: | Peter Geoghegan <peter(dot)geoghegan86(at)gmail(dot)com> |
---|---|
To: | Craig Ringer <craig(at)postnewspapers(dot)com(dot)au> |
Cc: | Bruce Momjian <bruce(at)momjian(dot)us>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Igor <igor(at)carcass(dot)ath(dot)cx>, pgsql-general(at)postgresql(dot)org |
Subject: | Re: server-side extension in c++ |
Date: | 2010-06-02 11:17:17 |
Message-ID: | AANLkTinnqthHfIbAXwcvnanZxNYAas8M0ZdKNGBx9W2l@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
> Letting an exception thrown from C++ code cross into C code will be
> EXTREMELY ugly. The C++-to-C boundaries *must* have unconditional catch
> blocks to convert thrown exceptions into appropriate error codes, even
> if the C++ code in question never knowingly throws an exception. C++ may
> throw std::bad_alloc on failure of operator new(), among other things,
> so the user must _always_ have an unconditional catch. Letting an
> exception propagate out to the C-based Pg backend is rather likely to
> result in a backend crash.
Right, but I don't think that this differs from the general C++ case.
Allowing exceptions to propagate across module boundaries was always a
bad idea, as was managing memory across module boundaries. Aside from
being very messy, they had to have exactly compatible runtimes and so
on.
> If the C++ libraries you are using will put up with it, compile your C++
> code with -fno-exceptions to make your life much, much easier, as you
> can avoid worrying about this entirely. OTOH, you must then check for
> NULL return from operator new().
That's the pre-standard behaviour of operator new(), and operator
new() continues to behave that way on some platforms, typically
embedded systems.
> If you can't do that: My usual rule is that any "extern C" function
> *must* have an unconditional catch. I also require that any function
> that may be passed as a function pointer to C code must be "extern C"
> and thus must obey the previous rule, so that covers function pointers
> and dlopen()ed access to functions.
>
Seems reasonable, and not overly difficult.
>
> Similarly, calling Pg code that may use Pg's error handling from within
> C++ is unsafe. It should be OK if you know for absolute certain that the
> C++ call tree in question only has plain-old-data (POD) structs and
> simple variables on the stack, but even then it requires caution. C++
> code that uses Pg calls can't do anything it couldn't do if you were
> using 'goto' and labels in each involved function, but additionally has
> to worry about returning and passing non-POD objects between functions
> in a call chain by value, as a longjmp may result in dtors not being
> properly called.
Really? That seems like an *incredibly* arduous requirement.
Intuitively, I find it difficult to believe. After all, even though
using longjmp in C++ code is a fast track to undefined behaviour, I
would have imagined that doing so in an isolated C module with a well
defined interface, called from C++ would be safe. I would have
imagined that ultimately, the call to the Pg C function must return,
and therefore cannot affect stack unwinding within the C++ part of the
program.
To invoke a reductio ad absurdum argument, if this were the case,
calling C functions from C++ would be widely considered a dangerous
thing to do, which it is not. After all, setjmp()/longjmp() are part
of the C standard library...in general, it's difficult to know whether
or not a third party module may use them. Have you ever seen a C
library marked as C++ safe or C++ unsafe? No, me neither.
Perhaps I'm missing something though...does the error handling portion
of the pg code potentially need a hook into the C++ code, from where
the longjmp() must be performed? I don't know what you mean by "a call
chain by value".
The bottom line is that *I think* you're fine as long as you don't do
setjmp()/longjmp() from within C++. You may even be okay if you just
do setjmp() from within C++. The longjmp() will hopefully only affect
stack unwinding before we get down to the C++ part of the stack, where
that matters.
--
Regards,
Peter Geoghegan
From | Date | Subject | |
---|---|---|---|
Next Message | Stephen Frost | 2010-06-02 11:31:12 | Re: Disable executing external commands from psql? |
Previous Message | Ivan Voras | 2010-06-02 10:42:22 | tsearch2 & dictionaries - possible problem |