没有为 dlopen 或 dlclose 调用信号处理程序
signal handler not called for dlopen or dlclose
我在随机时间收到分段错误。
我注册了信号,但发生分段错误时未调用信号处理程序
#include <unistd.h>
#include <dlfcn.h>
#include <iostream>
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
using namespace std;
void Handler(int sig)
{
cout << "handler called " << strsignal(sig) << endl;
exit(1);
}
int main()
{
cout << "Testing crash !" << endl;
signal(SIGSEGV, Handler);
signal(SIGINT, Handler);
signal(SIGABRT, Handler);
for (int i = 0; i < 10; i++)
{
cout << i << " Before open" << endl;
void *handler = dlopen("/home/user/Test.so", RTLD_LAZY);
if (handler)
{
cout << i << " Before close" << endl;
dlclose(handler);
cout << i << " After close" << endl;
}
else
{
cout << "Error " << dlerror() << endl;
}
}
return 0;
}
输出:
运行 1
Testing crash !
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
Segmentation fault (core dumped)
第 2 轮
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
1 After close
Segmentation fault (core dumped)
问题是没有调用信号处理程序来分析问题
Problem is signal handler is not called to analyze the problem
您的信号处理程序可能 被 调用。但它可能会死锁,因为它不是异步信号安全的。 Per POSIX:
the behavior is undefined ... if the signal handler calls any function
defined in this standard other than one of the functions listed in the
following table.
此代码调用异步信号 unsafe 函数,and therefore invokes undefined behavior:
void Handler(int sig)
{
cout << "handler called " << strsignal(sig) << endl;
exit(1);
}
只能从信号处理程序中调用 异步信号安全函数。
exit()
和任何使用任何类型的 C++ 流都不是异步信号安全的。
Per POSIX, the list of async-signal-safe functions are:
_Exit()
_exit()
abort()
accept()
access()
aio_error()
aio_return()
aio_suspend()
alarm()
bind()
cfgetispeed()
cfgetospeed()
cfsetispeed()
cfsetospeed()
chdir()
chmod()
chown()
clock_gettime()
close()
connect()
creat()
dup()
dup2()
execl()
execle()
execv()
execve()
faccessat()
fchdir()
fchmod()
fchmodat()
fchown()
fchownat()
fcntl()
fdatasync()
fexecve()
ffs()
fork()
fstat()
fstatat()
fsync()
ftruncate()
futimens()
getegid()
geteuid()
getgid()
getgroups()
getpeername()
getpgrp()
getpid()
getppid()
getsockname()
getsockopt()
getuid()
htonl()
htons()
kill()
link()
linkat()
listen()
longjmp()
lseek()
lstat()
memccpy()
memchr()
memcmp()
memcpy()
memmove()
memset()
mkdir()
mkdirat()
mkfifo()
mkfifoat()
mknod()
mknodat()
ntohl()
ntohs()
open()
openat()
pause()
pipe()
poll()
posix_trace_event()
pselect()
pthread_kill()
pthread_self()
pthread_sigmask()
raise()
read()
readlink()
readlinkat()
recv()
recvfrom()
recvmsg()
rename()
renameat()
rmdir()
select()
sem_post()
send()
sendmsg()
sendto()
setgid()
setpgid()
setsid()
setsockopt()
setuid()
shutdown()
sigaction()
sigaddset()
sigdelset()
sigemptyset()
sigfillset()
sigismember()
siglongjmp()
signal()
sigpause()
sigpending()
sigprocmask()
sigqueue()
sigset()
sigsuspend()
sleep()
sockatmark()
socket()
socketpair()
stat()
stpcpy()
stpncpy()
strcat()
strchr()
strcmp()
strcpy()
strcspn()
strlen()
strncat()
strncmp()
strncpy()
strnlen()
strpbrk()
strrchr()
strspn()
strstr()
strtok_r()
symlink()
symlinkat()
tcdrain()
tcflow()
tcflush()
tcgetattr()
tcgetpgrp()
tcsendbreak()
tcsetattr()
tcsetpgrp()
time()
timer_getoverrun()
timer_gettime()
timer_settime()
times()
umask()
uname()
unlink()
unlinkat()
utime()
utimensat()
utimes()
wait()
waitpid()
wcpcpy()
wcpncpy()
wcscat()
wcschr()
wcscmp()
wcscpy()
wcscspn()
wcslen()
wcsncat()
wcsncmp()
wcsncpy()
wcsnlen()
wcspbrk()
wcsrchr()
wcsspn()
wcsstr()
wcstok()
wmemchr()
wmemcmp()
wmemcpy()
wmemmove()
wmemset()
write()
请注意 Linux 不符合此处的 POSIX。 On Linux, fork()
is broken and is not async-signal-safe.
我在随机时间收到分段错误。
我注册了信号,但发生分段错误时未调用信号处理程序
#include <unistd.h>
#include <dlfcn.h>
#include <iostream>
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
using namespace std;
void Handler(int sig)
{
cout << "handler called " << strsignal(sig) << endl;
exit(1);
}
int main()
{
cout << "Testing crash !" << endl;
signal(SIGSEGV, Handler);
signal(SIGINT, Handler);
signal(SIGABRT, Handler);
for (int i = 0; i < 10; i++)
{
cout << i << " Before open" << endl;
void *handler = dlopen("/home/user/Test.so", RTLD_LAZY);
if (handler)
{
cout << i << " Before close" << endl;
dlclose(handler);
cout << i << " After close" << endl;
}
else
{
cout << "Error " << dlerror() << endl;
}
}
return 0;
}
输出:
运行 1
Testing crash !
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
Segmentation fault (core dumped)
第 2 轮
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
1 After close
Segmentation fault (core dumped)
问题是没有调用信号处理程序来分析问题
Problem is signal handler is not called to analyze the problem
您的信号处理程序可能 被 调用。但它可能会死锁,因为它不是异步信号安全的。 Per POSIX:
the behavior is undefined ... if the signal handler calls any function defined in this standard other than one of the functions listed in the following table.
此代码调用异步信号 unsafe 函数,and therefore invokes undefined behavior:
void Handler(int sig)
{
cout << "handler called " << strsignal(sig) << endl;
exit(1);
}
只能从信号处理程序中调用 异步信号安全函数。
exit()
和任何使用任何类型的 C++ 流都不是异步信号安全的。
Per POSIX, the list of async-signal-safe functions are:
_Exit()
_exit()
abort()
accept()
access()
aio_error()
aio_return()
aio_suspend()
alarm()
bind()
cfgetispeed()
cfgetospeed()
cfsetispeed()
cfsetospeed()
chdir()
chmod()
chown()
clock_gettime()
close()
connect()
creat()
dup()
dup2()
execl()
execle()
execv()
execve()
faccessat()
fchdir()
fchmod()
fchmodat()
fchown()
fchownat()
fcntl()
fdatasync()
fexecve()
ffs()
fork()
fstat()
fstatat()
fsync()
ftruncate()
futimens()
getegid()
geteuid()
getgid()
getgroups()
getpeername()
getpgrp()
getpid()
getppid()
getsockname()
getsockopt()
getuid()
htonl()
htons()
kill()
link()
linkat()
listen()
longjmp()
lseek()
lstat()
memccpy()
memchr()
memcmp()
memcpy()
memmove()
memset()
mkdir()
mkdirat()
mkfifo()
mkfifoat()
mknod()
mknodat()
ntohl()
ntohs()
open()
openat()
pause()
pipe()
poll()
posix_trace_event()
pselect()
pthread_kill()
pthread_self()
pthread_sigmask()
raise()
read()
readlink()
readlinkat()
recv()
recvfrom()
recvmsg()
rename()
renameat()
rmdir()
select()
sem_post()
send()
sendmsg()
sendto()
setgid()
setpgid()
setsid()
setsockopt()
setuid()
shutdown()
sigaction()
sigaddset()
sigdelset()
sigemptyset()
sigfillset()
sigismember()
siglongjmp()
signal()
sigpause()
sigpending()
sigprocmask()
sigqueue()
sigset()
sigsuspend()
sleep()
sockatmark()
socket()
socketpair()
stat()
stpcpy()
stpncpy()
strcat()
strchr()
strcmp()
strcpy()
strcspn()
strlen()
strncat()
strncmp()
strncpy()
strnlen()
strpbrk()
strrchr()
strspn()
strstr()
strtok_r()
symlink()
symlinkat()
tcdrain()
tcflow()
tcflush()
tcgetattr()
tcgetpgrp()
tcsendbreak()
tcsetattr()
tcsetpgrp()
time()
timer_getoverrun()
timer_gettime()
timer_settime()
times()
umask()
uname()
unlink()
unlinkat()
utime()
utimensat()
utimes()
wait()
waitpid()
wcpcpy()
wcpncpy()
wcscat()
wcschr()
wcscmp()
wcscpy()
wcscspn()
wcslen()
wcsncat()
wcsncmp()
wcsncpy()
wcsnlen()
wcspbrk()
wcsrchr()
wcsspn()
wcsstr()
wcstok()
wmemchr()
wmemcmp()
wmemcpy()
wmemmove()
wmemset()
write()
请注意 Linux 不符合此处的 POSIX。 On Linux, fork()
is broken and is not async-signal-safe.