Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
7be91705
Commit
7be91705
authored
Nov 13, 2015
by
antirez
Browse files
Lua debugger: handle forked sessions children during shutdown.
parent
3ab0b4d6
Changes
3
Show whitespace changes
Inline
Side-by-side
src/scripting.c
View file @
7be91705
...
@@ -63,6 +63,7 @@ struct ldbState {
...
@@ -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) {
...
@@ -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) {
...
@@ -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) {
...
@@ -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
)
{
...
...
src/server.c
View file @
7be91705
...
@@ -1201,11 +1201,12 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
@@ -1201,11 +1201,12 @@ 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
{
if
(
!
ldbRemoveChild
(
pid
))
{
serverLog
(
LL_WARNING
,
serverLog
(
LL_WARNING
,
"Warning, detected child with unmatched pid: %ld"
"Warning, detected child with unmatched pid: %ld"
,
" (EVAL forked debugging session?)"
,
(
long
)
pid
);
(
long
)
pid
);
}
}
}
updateDictResizePolicy
();
updateDictResizePolicy
();
}
}
}
else
{
}
else
{
...
@@ -2528,6 +2529,9 @@ int prepareForShutdown(int flags) {
...
@@ -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. */
...
...
src/server.h
View file @
7be91705
...
@@ -1471,6 +1471,8 @@ int redis_check_rdb_main(char **argv, int argc);
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment