I need a list of Async-Signal-Safe Functions from glibc
Finally latest versions of man 7 signal-safety
contain interested list: signal-safety.7.html
Is sysinfo() async. signal safe?
sysinfo
is just thin system call wrapper and async-signal-safe:
00000000000feb00 <sysinfo@@GLIBC_2.2.5>:
feb00: mov $0x63,%eax
feb05: syscall
feb07: cmp $0xfffffffffffff001,%rax
feb0d: jae feb10 <sysinfo@@GLIBC_2.2.5+0x10>
feb0f: retq
feb10: mov 0xbf359(%rip),%rcx
feb17: neg %eax
feb19: mov %eax,%fs:(%rcx)
feb1c: or $0xffffffffffffffff,%rax
feb20: retq
But there is no vDSO acceleration for it, so it is going to be much slower than clock_gettime
with either CLOCK_REALTIME
or CLOCK_MONOTONIC
on current systems.
Do functions which are not defined as async-safe, such as mmap(2), effect other async-safe functions called in signal handler?
Yes.
If your substitute open()
calls a function that is not async-signal-safe, then it is not safe for a signal handler to call your function. That it has the same name and signature as a standard function that is async-signal-safe is irrelevant. That it calls the replaced function or other async-signal-safe functions is irrelevant. That the prospective signal handler's call to a function that is not async-signal-safe would not be a direct one is irrelevant.
In response to the question update: in the event that the function presented in the question is called as a signal handler, it has undefined behavior on account of its call to mmap()
. The details of that UB cannot be predicted, at least not from the relevant standards. That's what "undefined" means. There is no reason whatever to suppose that the actual and apparent effects of the open()
call would be somehow protected from interference. Nor the general signal-handling mechanism. Nor anything else in the program.
The further you get from the locus of the UB, the less likely is any noticeable effect, and the more likely the OS is to contain it, but UB is not something to mess with. In principle, it may manifest as any behavior or behaviors within the power of your computer to produce, such as wiping your disk, turning off your CPU fan, or mailing your password to hackers.
Is pthread_kill async signal safe on Linux?
Summarizing Craig Estey's answers here (thanks, dude!):
In all (recent enough) man pages pthread_kill
is listed as async-signal-safe. There is a comment in glibc sources which claims it isn't safe in the presence of fork()
, so if you feel paranoid you could use tgkill(getpid(), <thread-id>, <signal-id>)
.
So, yeah -- both pthread_kill
and tgkill
should be ok.
On my CentOS 7 man
doesn't list any of them as safe, but it is likely due to the fact of it being too old.
Async signal safety of fork()
This is now listed as a bug by RedHat:
Bug 1422161 - glibc: fork is not async-signal-safe
...
+++ This bug was initially created as a clone of Bug #1422159 +++
POSIX requires that fork is async-signal-safe. Our current
implementation is not.
Print int from signal handler using write or async-safe functions
If you really insist on doing the printing from a signal handler, you basically have 2 options:
Block the signal except in a dedicated thread you create for handling the signal. This special thread can simply perform
for (;;) pause();
and sincepause
is async-signal-safe, the signal handler is allowed to use any functions it wants; it's not restricted to only async-signal-safe functions. On the other hand, it does have to access shared resources in a thread-safe way, since you're now dealing with threads.Write your own code for converting integers to decimal strings. It's just a simple loop of using
%10
and/10
to peel off the last digit and storing them to a short array.
However, I would highly recommend getting this operation out of the signal handler, using the self-pipe trick or similar.
Is gettimeofday async signal safe ? and can it cause deadlock if used in signal handler?
gettimeofday
is not defined as async-signal-safe, but if you pass 0 for the second (timezone) argument, it doesn't have to do anything that time
and clock_gettime
(both of which are officially async-signal-safe) don't also do, so as a matter of QoI it should be async-signal-safe in that case.
Your deadlock is inside the internal libc function __tz_convert
.
#2 0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
#3 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
It appears to have been called directly from Logger::getCurrentTimestamp
, but that's because it was "tail called" from a documented API function. There are only four functions in GNU libc that call __tz_convert
(I grepped the source code): localtime
, localtime_r
, gmtime
, and gmtime_r
. Therefore, your problem is not that you are calling gettimeofday
, but that you are calling one of those functions.
localtime
and gmtime
are obviously not async-signal-safe since they write to a global variable. localtime_r
and gmtime_r
are not async-signal-safe either, because they have to look at the global database of timezone information (yes, even gmtime_r
does this — it might be possible to change it not to need to do that, but it still wouldn't be a thing you could rely on cross-platform).
I don't think there's a good workaround. Formatted output from an async signal handler is going to trip over all kinds of other problems; my advice is to restructure your code so that you never need to call logging functions from async signal handlers.
Related Topics
How to Get the Difference (Only Additions) Between Two Files in Linux
Sed with Literal String--Not Input File
Why Child Process Still Alive After Parent Process Was Killed in Linux
How to Have a Tcp Connection Back to the Same Port
How to Grep for the Dollar Symbol ($)
Cannot Connect to X Server :0.0 with a Qt Application
How to Install Nuget from Command Line on Linux
Splitting a File in Linux Based on Content
How to Use Ioctl() to Manipulate My Kernel Module
/Usr/Bin/Ld: Cannot Find -Llapack
Gcloud Compute Copy-Files': Permission Denied When Copying Files
Replace the First Line in a Text File by a String
Parallel Download Using Curl Command Line Utility
Bash Script: Using "Script" Command from a Bash Script for Logging a Session