From: | Craig Ringer <craig(at)postnewspapers(dot)com(dot)au> |
---|---|
To: | Peter Geoghegan <peter(dot)geoghegan86(at)gmail(dot)com> |
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 12:36:00 |
Message-ID: | 4C065030.6060209@postnewspapers.com.au |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On 02/06/10 19:17, Peter Geoghegan wrote:
>> 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.
Not necessarily. It's only safe if setjmp/longjmp calls occur only
within the C code without "breaking" call paths involving C++.
This is ok:
[ C ]
entrypoint()
callIntoCppCode()
[ C++ ]
someCalls()
callIntoCCode()
[ C ]
setjmp()
doSomeStuff()
longjmp()
This is really, really not:
[ C ]
entrypoint()
setjmp() <----
callIntoCppCode()
[ C++ ]
someCalls()
callIntoCCode()
[ C ]
doSomeStuff()
longjmp()
See the attached demo (pop all files in the same directory then run "make").
> 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.
That's the whole point; a longjmp breaks the call chain, and the
guarantee that eventually the stack will unwind as functions return.
It's OK if you setjmp(a), do some work, setjmp(b), longjmp(a), do some
work, longjmp(b), return.
My understanding, which is likely imperfect, is that Pg's error handling
does NOT guarantee that, ie it's quite possible that a function may call
longjmp() without preparing any jmp_env to "jump back to" and therefore
will never return.
> 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.
If those C functions use setjmp/longjmp, it *is* a dangerous thing to
do. Most libraries that use setjmp/longjump in ways that may affect
calling code DO document this, and it's expected that the user of the
library will know what that entails.
If the library uses setjmp/longjmp entirely internally, so that it never
http://stackoverflow.com/questions/1376085/c-safe-to-use-longjmp-and-setjmp
--
Craig Ringer
Tech-related writing: http://soapyfrogs.blogspot.com/
Attachment | Content-Type | Size |
---|---|---|
cppmodule.cpp | text/x-c++src | 2.1 KB |
main.c | text/x-csrc | 1.2 KB |
Makefile | text/plain | 471 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Scott Marlowe | 2010-06-02 12:49:19 | Re: create index concurrently - duplicate index to reduce time without an index |
Previous Message | Andreas Kretschmer | 2010-06-02 12:25:14 | Re: Is it possible to make the order of output the same as the order of input parameters? |