我正在为我的套接字服务器应用程序使用boost asio。每个连接都由一个boost线程处理。我每个核心使用io_service,每个io_service都在一个工作线程中运行。
在我的连接中,我使用mysql C apis来查询数据库。 当有高流量时,有时mysql_query / close api会执行SIGSEGV。
有没有办法处理每个线程的SIGSEGV,以便我调用执行SIGSEGV的mysql api的线程只处理其他线程不受影响的异常。
这是我得到的错误 线程[17] 2844 [core:0](暂停:信号:SIGSEGV:分段错误) 为0x0 net_real_write()位于0x7ffff78d1ae5 net_flush()位于0x7ffff78d201b net_write_command()位于0x7ffff78d21d0 cli_advanced_command()位于0x7ffff78cf1ca mysql_send_query()位于0x7ffff78cd58d mysql_real_query()位于0x7ffff78cd5a9
答案 0 :(得分:0)
SIGSEGV
是同步信号。因此,SIGSEGV
所源自的线程是将在其信号处理程序中处理SIGSEGV
的线程。记录此行为here:
由于执行特定机器语言指令而生成的某些信号(例如
SIGSEGV
和SIGFPE
)是线程定向的,使用pthread_kill
定向特定线程的信号也是如此
据我所知,在保持定义的行为的同时,无法退出信号处理程序中的特定线程。要维护定义的行为,只能在信号处理程序中进行以下调用:
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() fchmod() fchmodat() fchown() fchownat()
fcntl() fdatasync() fexecve() fork() fstat()
fstatat() fsync() ftruncate() futimens() getegid()
geteuid() getgid() getgroups() getpeername() getpgrp()
getpid() getppid() getsockname() getsockopt() getuid()
kill() link() linkat() listen() lseek()
lstat() mkdir() mkdirat() mkfifo() mkfifoat()
mknod() mknodat() open() openat() pause()
pipe() poll() posix_trace_event() pselect()
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() signal() sigpause() sigpending()
sigprocmask() sigqueue() sigset() sigsuspend() sleep()
sockatmark() socket() socketpair() stat() 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()
write() _exit() _Exit()
要获取已定义的行为,请考虑将导致SEGSEGV
的代码隔离到其自己的进程中。例如,每个连接分叉和使用一个进程将允许SIGSEGV
仅杀死发生错误的进程,而不会影响其他连接或引入未定义的行为。