c-lldb 和信号的艰难时期,SIGSTOP 问题
发布时间:2022-05-17 15:37:38 259
相关标签:
我习惯了gdb
.现在,当我换成FreeBSD
,我试着用lldb
.
该程序使用kqueue
伺候SIGINT
SIGTERM
,SIGQUIT
信号。现在如果lldb
附加到进程,或使用调试器发送的命令行arg运行目标SIGSTOP
信号一件事是SIGSTOP
不能忽视和等待。
问题是kevent
返回-1
在流程中继续并继续退出。我看不到任何输出stderr
,这是另一个在不同帖子中被问到的问题。
什么是处理信号的实践lldb
是调试器吗?
使现代化
#include
#include
#include <netinet/in.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/time.h>
#include
#include
#include
#include
#include
#include
#include
#include <yma/yerror.h>
#include <yma/ybsd_sock.h>
#define TERMINATE_SET(s, v, l) { EXPAND(s) = v; PRINT_ERROR() goto EXPAND(l); }
#define NSIGNALS (5)
#define NSOCKETS (2)
#define SIGNALS {SIGINT, SIGQUIT, SIGTERM, SIGCONT, SIGPIPE}
#define NKEVBACKLOG (NSIGNALS + (NSOCKETS * 4)) /* signals + socket reads/writes + socket error + eof */
#define BUFSIZE (1024)
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
/* program status */
int status = 0;
/* restore signals at program exit ? */
bool b_restore_procmask = false;
/* signal masks */
sigset_t mask_block_sigs, mask_save_sigs, mask_kqueue_sigs;
struct kevent chlist[10]; /* events to monitor */
struct kevent evlist[NKEVBACKLOG]; /* events that were triggered */
int kq = -1, i, n;
/* signals being monitored by kqueue */
int signals[] = SIGNALS;
/* create kqueue descriptor */
if((kq = kqueue()) < 0){
TERMINATE_SET(status, -1, l_end)
}
/* set up signals */
sigemptyset(&mask_block_sigs);
/* these signals will be blocked. the signals will arrive */
/* to kqueue and not to a default signal handler. */
for(i = 0; i < NSIGNALS; ++i){
sigaddset(&mask_block_sigs, signals[i]);
}
/* save old sigmask, replace it with new sigmask */
status = sigprocmask(SIG_BLOCK, &mask_block_sigs, &mask_save_sigs);
TERMINATE_IF(status < 0, l_end)
b_restore_procmask = true;
/* set signal event */
for(i = 0; i < NSIGNALS; i++){
EV_SET(&chlist[i], signals[i], EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
}
/* end of signal setup */
/* add signals change list to kqueue */
n = kevent(kq, chlist, NSIGNALS, NULL, 0, NULL);
if(n < 0){
TERMINATE_SET(status, -1, l_end)
}
/* event loop */
while( 1 ) {
/* see event list */
n = kevent(kq, NULL, 0, evlist, NKEVBACKLOG, NULL);
switch(n) { /* switch on kevent return */
/* timeout */
case 0:
break;
/* error */
case -1:
TERMINATE_SET(status, -1, l_end);
/* some events */
default: {
int ev_id;
/* process events */
for(i = 0; i < n; ++i){
ev_id = evlist[i].ident;
/* check if signal has arrived */
switch(ev_id){
case SIGINT:
printf(" ! got SIGINT\n");
goto l_end;
case SIGQUIT:
printf(" ! got SIGQUIT\n");
goto l_end;
case SIGTERM:
printf(" ! got SIGTERM\n");
goto l_end;
case SIGPIPE:
printf(" ! got SIGPIPE\n");
break;
default: break;
}
} break; /* end process events */
} /* end kevent return switch */
} /* end event loop */
l_end:
/* restore procmask */
if(b_restore_procmask && (sigprocmask(SIG_SETMASK, &mask_save_sigs, NULL) < 0)){
PRINT_ERROR()
}
/* close kqueue */
CLOSE(kq);
return status;
}
以上是等待POSIX信号的程序的完整源代码。
我不想包含我的 makefile,因为它在这里无关紧要。clang -std=c2x -Wall -Wpedantic -Wextra -Wfatal-errors -O0 -g3 -glldb -fpic -c kevent.c -o outp应该去的东西。
更新
该程序确实以“中断的系统调用”退出
更新
当我再次阅读代码时,我发现了一个错误。错误在于错误的ev_id初始化。初始化是在for事件循环之前。所以上面的代码会SIGINT按预期做出反应。
更新
但是,当我附加到进程而不是作为参数运行它时lldb,我再次感到困惑。如果我发送SIGINT到进程,lldb则忽略这一事实process handle SIGINT -s false -p true并以“中断的系统调用”退出。
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报