mirror of
https://github.com/fluencelabs/redis
synced 2025-03-26 12:21:04 +00:00
Lua debugger: handle forked sessions children during shutdown.
This commit is contained in:
parent
3ab0b4d6d0
commit
7be9170585
@ -63,6 +63,7 @@ struct ldbState {
|
|||||||
int forked; /* Is this a fork()ed debugging session? */
|
int forked; /* Is this a fork()ed debugging session? */
|
||||||
list *logs; /* List of messages to send to the client. */
|
list *logs; /* List of messages to send to the client. */
|
||||||
list *traces; /* Messages about Redis commands executed since last stop.*/
|
list *traces; /* Messages about Redis commands executed since last stop.*/
|
||||||
|
list *children; /* All forked debugging sessions pids. */
|
||||||
int bp[LDB_BREAKPOINTS_MAX]; /* An array of breakpoints line numbers. */
|
int bp[LDB_BREAKPOINTS_MAX]; /* An array of breakpoints line numbers. */
|
||||||
int bpcount; /* Number of valid entries inside bp. */
|
int bpcount; /* Number of valid entries inside bp. */
|
||||||
int step; /* Stop at next line ragardless of breakpoints. */
|
int step; /* Stop at next line ragardless of breakpoints. */
|
||||||
@ -1489,6 +1490,7 @@ void ldbInit(void) {
|
|||||||
ldb.active = 0;
|
ldb.active = 0;
|
||||||
ldb.logs = listCreate();
|
ldb.logs = listCreate();
|
||||||
listSetFreeMethod(ldb.logs,(void (*)(void*))sdsfree);
|
listSetFreeMethod(ldb.logs,(void (*)(void*))sdsfree);
|
||||||
|
ldb.children = listCreate();
|
||||||
ldb.src = NULL;
|
ldb.src = NULL;
|
||||||
ldb.lines = 0;
|
ldb.lines = 0;
|
||||||
ldb.cbuf = sdsempty();
|
ldb.cbuf = sdsempty();
|
||||||
@ -1560,11 +1562,22 @@ int ldbStartSession(client *c) {
|
|||||||
addReplyError(c,"Fork() failed: can't run EVAL in debugging mode.");
|
addReplyError(c,"Fork() failed: can't run EVAL in debugging mode.");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (cp == 0) {
|
} else if (cp == 0) {
|
||||||
/* Child */
|
/* Child. Let's ignore important signals handled by the parent. */
|
||||||
|
struct sigaction act;
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = 0;
|
||||||
|
act.sa_handler = SIG_IGN;
|
||||||
|
sigaction(SIGTERM, &act, NULL);
|
||||||
|
sigaction(SIGINT, &act, NULL);
|
||||||
|
|
||||||
|
/* Log the creation of the child and close the listening
|
||||||
|
* socket to make sure if the parent crashes a reset is sent
|
||||||
|
* to the clients. */
|
||||||
serverLog(LL_WARNING,"Redis forked for debugging eval");
|
serverLog(LL_WARNING,"Redis forked for debugging eval");
|
||||||
closeListeningSockets(0);
|
closeListeningSockets(0);
|
||||||
} else {
|
} else {
|
||||||
/* Parent */
|
/* Parent */
|
||||||
|
listAddNodeTail(ldb.children,(void*)(unsigned long)cp);
|
||||||
freeClientAsync(c); /* Close the client in the parent side. */
|
freeClientAsync(c); /* Close the client in the parent side. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1618,6 +1631,33 @@ void ldbEndSession(client *c) {
|
|||||||
ldb.active = 0;
|
ldb.active = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the specified pid is among the list of children spawned for
|
||||||
|
* forked debugging sessions, it is removed from the children list.
|
||||||
|
* If the pid was found non-zero is returned. */
|
||||||
|
int ldbRemoveChild(pid_t pid) {
|
||||||
|
listNode *ln = listSearchKey(ldb.children,(void*)(unsigned long)pid);
|
||||||
|
if (ln) {
|
||||||
|
listDelNode(ldb.children,ln);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Kill all the forked sessions. */
|
||||||
|
void ldbKillForkedSessions(void) {
|
||||||
|
listIter li;
|
||||||
|
listNode *ln;
|
||||||
|
|
||||||
|
listRewind(ldb.children,&li);
|
||||||
|
while((ln = listNext(&li))) {
|
||||||
|
pid_t pid = (unsigned long) ln->value;
|
||||||
|
serverLog(LL_WARNING,"Killing debugging session %ld",(long)pid);
|
||||||
|
kill(pid,SIGKILL);
|
||||||
|
}
|
||||||
|
listRelease(ldb.children);
|
||||||
|
ldb.children = listCreate();
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrapper for EVAL / EVALSHA that enables debugging, and makes sure
|
/* Wrapper for EVAL / EVALSHA that enables debugging, and makes sure
|
||||||
* that when EVAL returns, whatever happened, the session is ended. */
|
* that when EVAL returns, whatever happened, the session is ended. */
|
||||||
void evalGenericCommandWithDebugging(client *c, int evalsha) {
|
void evalGenericCommandWithDebugging(client *c, int evalsha) {
|
||||||
|
12
src/server.c
12
src/server.c
@ -1201,10 +1201,11 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
|||||||
} else if (pid == server.aof_child_pid) {
|
} else if (pid == server.aof_child_pid) {
|
||||||
backgroundRewriteDoneHandler(exitcode,bysignal);
|
backgroundRewriteDoneHandler(exitcode,bysignal);
|
||||||
} else {
|
} else {
|
||||||
serverLog(LL_WARNING,
|
if (!ldbRemoveChild(pid)) {
|
||||||
"Warning, detected child with unmatched pid: %ld"
|
serverLog(LL_WARNING,
|
||||||
" (EVAL forked debugging session?)",
|
"Warning, detected child with unmatched pid: %ld",
|
||||||
(long)pid);
|
(long)pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateDictResizePolicy();
|
updateDictResizePolicy();
|
||||||
}
|
}
|
||||||
@ -2528,6 +2529,9 @@ int prepareForShutdown(int flags) {
|
|||||||
|
|
||||||
serverLog(LL_WARNING,"User requested shutdown...");
|
serverLog(LL_WARNING,"User requested shutdown...");
|
||||||
|
|
||||||
|
/* Kill all the Lua debugger forked sessions. */
|
||||||
|
ldbKillForkedSessions();
|
||||||
|
|
||||||
/* Kill the saving child if there is a background saving in progress.
|
/* Kill the saving child if there is a background saving in progress.
|
||||||
We want to avoid race conditions, for instance our saving child may
|
We want to avoid race conditions, for instance our saving child may
|
||||||
overwrite the synchronous saving did by SHUTDOWN. */
|
overwrite the synchronous saving did by SHUTDOWN. */
|
||||||
|
@ -1471,6 +1471,8 @@ int redis_check_rdb_main(char **argv, int argc);
|
|||||||
|
|
||||||
/* Scripting */
|
/* Scripting */
|
||||||
void scriptingInit(int setup);
|
void scriptingInit(int setup);
|
||||||
|
int ldbRemoveChild(pid_t pid);
|
||||||
|
void ldbKillForkedSessions(void);
|
||||||
|
|
||||||
/* Blocked clients */
|
/* Blocked clients */
|
||||||
void processUnblockedClients(void);
|
void processUnblockedClients(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user