Start a debugging session before calling EVAL implementation. * The technique we use is to capture the client socket file descriptor, * in order to perform direct I/O with it from within Lua hooks. This * way we don't have to re-enter Redis in order to handle I/O. * * The function returns 1 if the caller should proceed to call EVAL, * and 0 if instead the caller should abort the operation (t
| 1962 | * The caller should call ldbEndSession() only if ldbStartSession() |
| 1963 | * returned 1. */ |
| 1964 | int ldbStartSession(client *c) { |
| 1965 | ldb.forked = (c->flags & CLIENT_LUA_DEBUG_SYNC) == 0; |
| 1966 | if (ldb.forked) { |
| 1967 | pid_t cp = redisFork(CHILD_TYPE_LDB); |
| 1968 | if (cp == -1) { |
| 1969 | addReplyError(c,"Fork() failed: can't run EVAL in debugging mode."); |
| 1970 | return 0; |
| 1971 | } else if (cp == 0) { |
| 1972 | /* Child. Let's ignore important signals handled by the parent. */ |
| 1973 | struct sigaction act; |
| 1974 | sigemptyset(&act.sa_mask); |
| 1975 | act.sa_flags = 0; |
| 1976 | act.sa_handler = SIG_IGN; |
| 1977 | sigaction(SIGTERM, &act, NULL); |
| 1978 | sigaction(SIGINT, &act, NULL); |
| 1979 | |
| 1980 | /* Log the creation of the child and close the listening |
| 1981 | * socket to make sure if the parent crashes a reset is sent |
| 1982 | * to the clients. */ |
| 1983 | serverLog(LL_WARNING,"Redis forked for debugging eval"); |
| 1984 | } else { |
| 1985 | /* Parent */ |
| 1986 | listAddNodeTail(ldb.children,(void*)(unsigned long)cp); |
| 1987 | freeClientAsync(c); /* Close the client in the parent side. */ |
| 1988 | return 0; |
| 1989 | } |
| 1990 | } else { |
| 1991 | serverLog(LL_WARNING, |
| 1992 | "Redis synchronous debugging eval session started"); |
| 1993 | } |
| 1994 | |
| 1995 | /* Setup our debugging session. */ |
| 1996 | connBlock(ldb.conn); |
| 1997 | connSendTimeout(ldb.conn,5000); |
| 1998 | ldb.active = 1; |
| 1999 | |
| 2000 | /* First argument of EVAL is the script itself. We split it into different |
| 2001 | * lines since this is the way the debugger accesses the source code. */ |
| 2002 | sds srcstring = sdsdup((sds)ptrFromObj(c->argv[1])); |
| 2003 | size_t srclen = sdslen(srcstring); |
| 2004 | while(srclen && (srcstring[srclen-1] == '\n' || |
| 2005 | srcstring[srclen-1] == '\r')) |
| 2006 | { |
| 2007 | srcstring[--srclen] = '\0'; |
| 2008 | } |
| 2009 | sdssetlen(srcstring,srclen); |
| 2010 | ldb.src = sdssplitlen(srcstring,sdslen(srcstring),"\n",1,&ldb.lines); |
| 2011 | sdsfree(srcstring); |
| 2012 | return 1; |
| 2013 | } |
| 2014 | |
| 2015 | /* End a debugging session after the EVAL call with debugging enabled |
| 2016 | * returned. */ |
no test coverage detected