Encoding of PyFrameObject members
I need to access frame members from within a signal handler for tracing purpose. My first attempt to access co_filename was like this (omitting error checking): PyFrameObject *frame = PyEval_GetFrame(); PyObject *ob = PyUnicode_AsUTF8String(frame->f_code->co_filename) char *str = PyBytes_AsString(ob) However, the function PyUnicode_AsUTF8String() calls PyObject_Malloc(), which is not reentrant. If the signal handler nest over PyObject_Malloc(), it causes a segfault, and it could also deadlock. Instead, I access members directly: char *str = PyUnicode_DATA(frame->f_code->co_filename); size_t len = PyUnicode_GET_DATA_SIZE(frame->f_code->co_filename); Is it safe to assume that unicode objects co_filename and co_name are always UTF-8 data for loaded code? I looked at the PyTokenizer_FromString() and it seems to convert everything to UTF-8 upfront, and I would like to make sure this assumption is valid. Thanks! Francis
On Fri, Feb 6, 2015 at 10:27 AM, Francis Giraldeau <francis.giraldeau@gmail.com> wrote:
Instead, I access members directly: char *str = PyUnicode_DATA(frame->f_code->co_filename); size_t len = PyUnicode_GET_DATA_SIZE(frame->f_code->co_filename);
Is it safe to assume that unicode objects co_filename and co_name are always UTF-8 data for loaded code? I looked at the PyTokenizer_FromString() and it seems to convert everything to UTF-8 upfront, and I would like to make sure this assumption is valid.
I don't think you should be using _GET_DATA_SIZE with _DATA - they're mix-and-matched from old and new APIs. If you want a raw, no-allocation look at the data, you'd need to check PyUnicode_KIND and then read Latin-1, UCS-2, or UCS-4 data: https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_1BYTE_DATA (By the way, I don't think the name "UCS-1" is part of the Unicode spec. But it's an obvious parallel to UCS-2 and UCS-4.) Getting UTF-8 data out of the structure, if it had indeed been cached, ought to be possible. But I can't see a documented function or macro for doing it. Is there a way? Reaching into the structure and grabbing the utf8 and utf8_length members seems like a bad idea. ChrisA
On Thu Feb 05 2015 at 4:36:30 PM Francis Giraldeau < francis.giraldeau@gmail.com> wrote:
I need to access frame members from within a signal handler for tracing purpose. My first attempt to access co_filename was like this (omitting error checking):
PyFrameObject *frame = PyEval_GetFrame(); PyObject *ob = PyUnicode_AsUTF8String(frame->f_code->co_filename) char *str = PyBytes_AsString(ob)
However, the function PyUnicode_AsUTF8String() calls PyObject_Malloc(), which is not reentrant. If the signal handler nest over PyObject_Malloc(), it causes a segfault, and it could also deadlock.
Instead, I access members directly: char *str = PyUnicode_DATA(frame->f_code->co_filename); size_t len = PyUnicode_GET_DATA_SIZE(frame->f_code->co_filename);
Is it safe to assume that unicode objects co_filename and co_name are always UTF-8 data for loaded code? I looked at the PyTokenizer_FromString() and it seems to convert everything to UTF-8 upfront, and I would like to make sure this assumption is valid.
The faulthandler module calls into Python/traceback.c in signal context which has some low level code for extracting something useful from PyUnicode objects without triggering a conversion: https://hg.python.org/cpython/file/f1a82e949fb8/Python/traceback.c#l531 That code is written to write output to a fd. It's much more useful for signal handler tracing data collection from a signal handler if you refactor it to dump its output into a preallocated char* buffer. -gps
Thanks!
Francis _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ greg%40krypto.org
Hi Francis I don't think it's safe to assume f_code is properly filled by the time you might read it, depending a bit where you find the frame object. Are you sure it's not full of garbage? Besides, are you writing a profiler, or what exactly are you doing? On Fri, Feb 6, 2015 at 1:27 AM, Francis Giraldeau <francis.giraldeau@gmail.com> wrote:
I need to access frame members from within a signal handler for tracing purpose. My first attempt to access co_filename was like this (omitting error checking):
PyFrameObject *frame = PyEval_GetFrame(); PyObject *ob = PyUnicode_AsUTF8String(frame->f_code->co_filename) char *str = PyBytes_AsString(ob)
However, the function PyUnicode_AsUTF8String() calls PyObject_Malloc(), which is not reentrant. If the signal handler nest over PyObject_Malloc(), it causes a segfault, and it could also deadlock.
Instead, I access members directly: char *str = PyUnicode_DATA(frame->f_code->co_filename); size_t len = PyUnicode_GET_DATA_SIZE(frame->f_code->co_filename);
Is it safe to assume that unicode objects co_filename and co_name are always UTF-8 data for loaded code? I looked at the PyTokenizer_FromString() and it seems to convert everything to UTF-8 upfront, and I would like to make sure this assumption is valid.
Thanks!
Francis
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/fijall%40gmail.com
Hi, 2015-02-06 0:27 GMT+01:00 Francis Giraldeau <francis.giraldeau@gmail.com>:
I need to access frame members from within a signal handler for tracing purpose.
IMO you have a big technical or design issue here. Accessing Python internals in a signal handler is not reliable. A signal can occur anytime, between two instructions.
However, the function PyUnicode_AsUTF8String() calls PyObject_Malloc(), which is not reentrant. If the signal handler nest over PyObject_Malloc(), it causes a segfault, and it could also deadlock.
Yes, the list of async signal-safe function is very very short :-) It's something like: read(), write(), and use the stack (but not too much stack or you will get a stack overflow). I spent many weeks to implement the faulthandler module (try to write a safe and portable implementation). To write the traceback, I only use write(). But to read the traceback, I inspect Python internals which is completly unsafe. faulthandler is written to only be called when something really bad happen (a "crash"), so it's not so important if it does crash too :-) See also the tracemalloc module which also inspects the traceback, but it does *not* use signals (which would be unsafe). It uses hooks on the memory allocator. Python has sys.settrace() and sys.setprofile(). Why not using these functions? Victor
On 06.02.2015 00:27, Francis Giraldeau wrote:
I need to access frame members from within a signal handler for tracing purpose. My first attempt to access co_filename was like this (omitting error checking):
PyFrameObject *frame = PyEval_GetFrame(); PyObject *ob = PyUnicode_AsUTF8String(frame->f_code->co_filename) char *str = PyBytes_AsString(ob)
However, the function PyUnicode_AsUTF8String() calls PyObject_Malloc(), which is not reentrant. If the signal handler nest over PyObject_Malloc(), it causes a segfault, and it could also deadlock.
Instead, I access members directly: char *str = PyUnicode_DATA(frame->f_code->co_filename); size_t len = PyUnicode_GET_DATA_SIZE(frame->f_code->co_filename);
Is it safe to assume that unicode objects co_filename and co_name are always UTF-8 data for loaded code? I looked at the PyTokenizer_FromString() and it seems to convert everything to UTF-8 upfront, and I would like to make sure this assumption is valid.
The macros won't work in all cases, as they don't pay attention to the different kinds used in the Unicode implementation. I don't think there's any API you can use to extract the underlying data without going through PyObject_Malloc() at some point (you may be lucky if there already is a UTF-8 version available, but it's not guaranteed). I guess your best bet is to write your own UTF-8 codec which then copies the data to a buffer that you can control. Have a look at Objects/stringlib/codecs.h: utf8_encode. Alternatively, you can copy the data to a Py_UCS4 buffer which you allocate using code such as this (untested, adapted from the UTF-8 encoder): Py_UCS4 *p; enum PyUnicode_Kind repkind; void *repdata; Py_ssize_t repsize, k; if (PyUnicode_READY(rep) < 0) goto error; repkind = PyUnicode_KIND(rep); repdata = PyUnicode_DATA(rep); repsize = PyUnicode_GET_LENGTH(rep); p = malloc((repsize + 1) * sizeof(Py_UCS4)); for(k=0; k<repsize; k++) { *p++ = PyUnicode_READ(repkind, repdata, k); } /* 0-terminate */ *p++ = 0; ... free(p); -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 06 2015)
Python Projects, Coaching and Consulting ... http://www.egenix.com/ mxODBC Plone/Zope Database Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
Hi, On 6 February 2015 at 08:24, Maciej Fijalkowski <fijall@gmail.com> wrote:
I don't think it's safe to assume f_code is properly filled by the time you might read it, depending a bit where you find the frame object. Are you sure it's not full of garbage?
Yes, before discussing how to do the utf8 decoding, we should realize that it is really unsafe code starting from the line before. From a signal handler you're only supposed to read data that was written to "volatile" fields. So even PyEval_GetFrame(), which is done by reading the thread state's "frame" field, is not safe: this is not a volatile. This means that the compiler is free to do crazy things like *first* write into this field and *then* initialize the actual content of the frame. The uninitialized content may be garbage, not just NULLs. A bientôt, Armin.
2015-02-06 6:04 GMT-05:00 Armin Rigo <arigo@tunes.org>:
Hi,
On 6 February 2015 at 08:24, Maciej Fijalkowski <fijall@gmail.com> wrote:
I don't think it's safe to assume f_code is properly filled by the time you might read it, depending a bit where you find the frame object. Are you sure it's not full of garbage?
Yes, before discussing how to do the utf8 decoding, we should realize that it is really unsafe code starting from the line before. From a signal handler you're only supposed to read data that was written to "volatile" fields. So even PyEval_GetFrame(), which is done by reading the thread state's "frame" field, is not safe: this is not a volatile. This means that the compiler is free to do crazy things like *first* write into this field and *then* initialize the actual content of the frame. The uninitialized content may be garbage, not just NULLs.
Thanks for these comments. Of course accessing frames withing a signal handler is racy. I confirm that code encoded in non-ascii is not accessible from the uft8 buffer pointer. However, a call to PyUnicode_AsUTF8() encodes the data and caches it in the unicode object. Later access returns the byte buffer without memory allocation and re-encoding. I think it is possible to solve both safety problems by registering a handler with PyPyEval_SetProfile(). On function entry, the handler will call PyUnicode_AsUTF8() on the required frame members to make sure the utf8 encoded string is available. Then, we increment the refcount of the frame and assign it to a thread local pointer. On function return, the refcount is decremented. These operations occurs in the normal context and they are not racy. The signal handler will use the thread local frame pointer instead of calling PyEval_GetFrame(). Does that sounds good? Thanks again for your feedback! Francis
On Sat, Feb 7, 2015 at 12:48 AM, Francis Giraldeau <francis.giraldeau@gmail.com> wrote:
2015-02-06 6:04 GMT-05:00 Armin Rigo <arigo@tunes.org>:
Hi,
On 6 February 2015 at 08:24, Maciej Fijalkowski <fijall@gmail.com> wrote:
I don't think it's safe to assume f_code is properly filled by the time you might read it, depending a bit where you find the frame object. Are you sure it's not full of garbage?
Yes, before discussing how to do the utf8 decoding, we should realize that it is really unsafe code starting from the line before. From a signal handler you're only supposed to read data that was written to "volatile" fields. So even PyEval_GetFrame(), which is done by reading the thread state's "frame" field, is not safe: this is not a volatile. This means that the compiler is free to do crazy things like *first* write into this field and *then* initialize the actual content of the frame. The uninitialized content may be garbage, not just NULLs.
Thanks for these comments. Of course accessing frames withing a signal handler is racy. I confirm that code encoded in non-ascii is not accessible from the uft8 buffer pointer. However, a call to PyUnicode_AsUTF8() encodes the data and caches it in the unicode object. Later access returns the byte buffer without memory allocation and re-encoding.
I think it is possible to solve both safety problems by registering a handler with PyPyEval_SetProfile(). On function entry, the handler will call PyUnicode_AsUTF8() on the required frame members to make sure the utf8 encoded string is available. Then, we increment the refcount of the frame and assign it to a thread local pointer. On function return, the refcount is decremented. These operations occurs in the normal context and they are not racy. The signal handler will use the thread local frame pointer instead of calling PyEval_GetFrame(). Does that sounds good?
Thanks again for your feedback!
Francis
You still didn't explain what are you trying to achieve nor adressed armins questions about volatile. However, you can't access thread locals from signal handlers (since in some cases it mallocs, thread locals are built lazily if you're inside the .so, e.g. if python is built with --shared)
On 02/06/2015 11:48 PM, Francis Giraldeau wrote:
2015-02-06 6:04 GMT-05:00 Armin Rigo:
Hi,
On 6 February 2015 at 08:24, Maciej Fijalkowski <fijall@gmail.com <mailto:fijall@gmail.com>> wrote: > I don't think it's safe to assume f_code is properly filled by the > time you might read it, depending a bit where you find the frame > object. Are you sure it's not full of garbage?
Yes, before discussing how to do the utf8 decoding, we should realize that it is really unsafe code starting from the line before. From a signal handler you're only supposed to read data that was written to "volatile" fields. So even PyEval_GetFrame(), which is done by reading the thread state's "frame" field, is not safe: this is not a volatile. This means that the compiler is free to do crazy things like *first* write into this field and *then* initialize the actual content of the frame. The uninitialized content may be garbage, not just NULLs.
Thanks for these comments. Of course accessing frames withing a signal handler is racy. I confirm that code encoded in non-ascii is not accessible from the uft8 buffer pointer. However, a call to PyUnicode_AsUTF8() encodes the data and caches it in the unicode object. Later access returns the byte buffer without memory allocation and re-encoding.
I think it is possible to solve both safety problems by registering a handler with PyPyEval_SetProfile(). On function entry, the handler will call PyUnicode_AsUTF8() on the required frame members to make sure the utf8 encoded string is available. Then, we increment the refcount of the frame and assign it to a thread local pointer. On function return, the refcount is decremented. These operations occurs in the normal context and they are not racy. The signal handler will use the thread local frame pointer instead of calling PyEval_GetFrame(). Does that sounds good?
You could call Py_AddPendingCall() from your signal handler and access the frame members from the function scheduled by Py_AddPendingCall(). Xavier
Maciej Fijalkowski wrote:
However, you can't access thread locals from signal handlers (since in some cases it mallocs, thread locals are built lazily if you're inside the .so, e.g. if python is built with --shared)
You might be able to use Py_AddPendingCall to schedule what you want done outside the context of the signal handler. The call will be made by the main thread, though, so if you need to access the frame of whatever thread was running when the signal occured, you will have to track down its PyThreadState somehow and get the frame from there. Not sure what would be involved in doing that. -- Greg
To get at the Python thread state from a signal handler (using 2.7 as a reference here; but i don't believe 3.4 has changed this part much) you need to modify the interpreter to expose pystate.c's "autoTLSkey" and thread.c's "struct key" as well as "keyhead" and "keymutex".
From there, in your signal handler you must try to acquire the newly exposed keymutex and do nothing if you were unable to get it. If you did acquire it (rare not to), you can walk the keyhead list looking for autoTLSkey to find the current valid thread state.
I had an intern (hi Elena!) write a signal sampling based low overhead Python CPU profiler based on that last summer. I believe there are still bugs to shaken out (if they are even possible to fix... Armin's comments are true: signal handler code is super limited). I am stating this here because I want someone to pester me at PyCon if I haven't released our work as a proof of concept by then. The important take away: From what I could figure out, you need to modify the CPython interpreter to be more amenable to such introspection. A downside of a signal based profiler: *ALL* of the EINTR mishandling bugs within the Python interpreter, stdlib, and your own code will show up in your application. So until those are fixed (hooray for Antoine's PEP!), it may not be practical for use on production processes which is sort of the entire point of a low overhead sampling profiler... I'd like to get a buildbot setup that runs the testsuite while a continual barrage of signals are being generated. We really don't stress test that stuff (as evidence by the EINTR mishandling issues that are rampant) as non-fatal signals are so rare for most things... until they aren't. As a side note and encouragement: I wonder what PyPy could do for dynamically enabled and disabled low overhead CPU profiling. (take that as a hint that I want someone else to get extremely creative!) -gps On Sat Feb 07 2015 at 1:34:26 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Maciej Fijalkowski wrote:
However, you can't access thread locals from signal handlers (since in some cases it mallocs, thread locals are built lazily if you're inside the .so, e.g. if python is built with --shared)
You might be able to use Py_AddPendingCall to schedule what you want done outside the context of the signal handler.
The call will be made by the main thread, though, so if you need to access the frame of whatever thread was running when the signal occured, you will have to track down its PyThreadState somehow and get the frame from there. Not sure what would be involved in doing that.
-- Greg _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ greg%40krypto.org
Le 7 févr. 2015 22:34, "Greg Ewing" <greg.ewing@canterbury.ac.nz> a écrit : with --shared)
You might be able to use Py_AddPendingCall to schedule what you want done outside the context of the signal handler.
I don't how it could work. You have to increment the reference counting, but also maybe increment references to other frames. Again there is no guarantee that python structures are consistent in a signal handler. While a faulthandler is only called once, a profiler is called very frequently, up to once per python instruction. Unlikely bugs become very likely. Victor
Le 8 févr. 2015 05:39, "Gregory P. Smith" <greg@krypto.org> a écrit :
From there, in your signal handler you must try to acquire the newly exposed keymutex and (...)
Stop! Acquiring a lock in a signal handler is just a crazy idea. It's very far from an async signal-safe function.
So until those are fixed (hooray for Antoine's PEP!), ...
I wrote the PEP with Charles François Natali, but Charles wrote the whole implementation. Antoine also helped us and approved the PEP. It's the french connection! Just to say that Charles did most of the work. Victor
I'm working on vmprof (github.com/vmprof/vmprof-python) which works for both cpython and pypy (pypy has special support, cpython is patched on-the fly) On Sun, Feb 8, 2015 at 6:39 AM, Gregory P. Smith <greg@krypto.org> wrote:
To get at the Python thread state from a signal handler (using 2.7 as a reference here; but i don't believe 3.4 has changed this part much) you need to modify the interpreter to expose pystate.c's "autoTLSkey" and thread.c's "struct key" as well as "keyhead" and "keymutex".
From there, in your signal handler you must try to acquire the newly exposed keymutex and do nothing if you were unable to get it. If you did acquire it (rare not to), you can walk the keyhead list looking for autoTLSkey to find the current valid thread state.
I had an intern (hi Elena!) write a signal sampling based low overhead Python CPU profiler based on that last summer. I believe there are still bugs to shaken out (if they are even possible to fix... Armin's comments are true: signal handler code is super limited). I am stating this here because I want someone to pester me at PyCon if I haven't released our work as a proof of concept by then. The important take away: From what I could figure out, you need to modify the CPython interpreter to be more amenable to such introspection.
A downside of a signal based profiler: *ALL* of the EINTR mishandling bugs within the Python interpreter, stdlib, and your own code will show up in your application. So until those are fixed (hooray for Antoine's PEP!), it may not be practical for use on production processes which is sort of the entire point of a low overhead sampling profiler...
I'd like to get a buildbot setup that runs the testsuite while a continual barrage of signals are being generated. We really don't stress test that stuff (as evidence by the EINTR mishandling issues that are rampant) as non-fatal signals are so rare for most things... until they aren't.
As a side note and encouragement: I wonder what PyPy could do for dynamically enabled and disabled low overhead CPU profiling. (take that as a hint that I want someone else to get extremely creative!)
-gps
On Sat Feb 07 2015 at 1:34:26 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Maciej Fijalkowski wrote:
However, you can't access thread locals from signal handlers (since in some cases it mallocs, thread locals are built lazily if you're inside the .so, e.g. if python is built with --shared)
You might be able to use Py_AddPendingCall to schedule what you want done outside the context of the signal handler.
The call will be made by the main thread, though, so if you need to access the frame of whatever thread was running when the signal occured, you will have to track down its PyThreadState somehow and get the frame from there. Not sure what would be involved in doing that.
-- Greg _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/greg%40krypto.org
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/fijall%40gmail.com
2015-02-08 4:01 GMT-05:00 Maciej Fijalkowski <fijall@gmail.com>:
I'm working on vmprof (github.com/vmprof/vmprof-python) which works for both cpython and pypy (pypy has special support, cpython is patched on-the fly)
This looks interesting. I'm working on a profiler that is similar, but not based on timer. Instead, the signal is generated when an hardware performance counter overflows. It required a special linux kernel module, and the tracepoint is recorded using LTTng-UST. https://github.com/giraldeau/perfuser https://github.com/giraldeau/perfuser-modules https://github.com/giraldeau/python-profile-ust This is of course very experimental, requires a special setup, an I don't even know if it's going to produce good results. I'll report the results in the coming weeks. Cheers, Francis Giraldeau
Hi Francis Feel free to steal most of vmprof code, it should generally work without requiring to patch cpython (python 3 patches appreciated :-). As far as timer goes - it seems not to be going anywhere, I would rather use a background thread or something On Sun, Feb 8, 2015 at 10:03 PM, Francis Giraldeau <francis.giraldeau@gmail.com> wrote:
2015-02-08 4:01 GMT-05:00 Maciej Fijalkowski <fijall@gmail.com>:
I'm working on vmprof (github.com/vmprof/vmprof-python) which works for both cpython and pypy (pypy has special support, cpython is patched on-the fly)
This looks interesting. I'm working on a profiler that is similar, but not based on timer. Instead, the signal is generated when an hardware performance counter overflows. It required a special linux kernel module, and the tracepoint is recorded using LTTng-UST.
https://github.com/giraldeau/perfuser https://github.com/giraldeau/perfuser-modules https://github.com/giraldeau/python-profile-ust
This is of course very experimental, requires a special setup, an I don't even know if it's going to produce good results. I'll report the results in the coming weeks.
Cheers,
Francis Giraldeau
On 9 February 2015 at 09:11, Maciej Fijalkowski <fijall@gmail.com> wrote:
Hi Francis
Feel free to steal most of vmprof code, it should generally work without requiring to patch cpython (python 3 patches appreciated :-). As far as timer goes - it seems not to be going anywhere, I would rather use a background thread or something
What about setting a flag when the signal arrives and checking it at the next bytecode evaluation or something? -Rob
This is exactly how signals are implemented in Python :-) Victor Le lundi 9 février 2015, Robert Collins <robertc@robertcollins.net> a écrit :
On 9 February 2015 at 09:11, Maciej Fijalkowski <fijall@gmail.com <javascript:;>> wrote:
Hi Francis
Feel free to steal most of vmprof code, it should generally work without requiring to patch cpython (python 3 patches appreciated :-). As far as timer goes - it seems not to be going anywhere, I would rather use a background thread or something
What about setting a flag when the signal arrives and checking it at the next bytecode evaluation or something?
-Rob _______________________________________________ Python-Dev mailing list Python-Dev@python.org <javascript:;> https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/victor.stinner%40gmail.co...
On Sun Feb 08 2015 at 12:21:36 AM Victor Stinner <victor.stinner@gmail.com> wrote:
Le 8 févr. 2015 05:39, "Gregory P. Smith" <greg@krypto.org> a écrit :
From there, in your signal handler you must try to acquire the newly exposed keymutex and (...)
Stop! Acquiring a lock in a signal handler is just a crazy idea. It's very far from an async signal-safe function.
I'd normally agree... In this case, sem_trywait() is non-blocking. It is unfortunately not on the official POSIX list of async-signal-safe functions (of the SEMs, only sem_post() is) but many implementations actually are safe, documented or not. https://github.com/lattera/glibc/blob/master/nptl/sysdeps/unix/sysv/linux/x8... - appears safe. So long as the underlying semaphore is implemented using an atomic instruction on the target platform I wouldn't expect any implementation of sem_trywait to be async signal unsafe. (nor would I depend on that without checking) -gps
So until those are fixed (hooray for Antoine's PEP!), ...
I wrote the PEP with Charles François Natali, but Charles wrote the whole implementation. Antoine also helped us and approved the PEP. It's the french connection! Just to say that Charles did most of the work.
Victor
participants (10)
-
Armin Rigo
-
Chris Angelico
-
Francis Giraldeau
-
Greg Ewing
-
Gregory P. Smith
-
M.-A. Lemburg
-
Maciej Fijalkowski
-
Robert Collins
-
Victor Stinner
-
Xavier de Gaye