Compare commits

..
Author SHA1 Message Date
John Sully b806999eb0 Solo tests should work with loopn 2021-08-11 19:17:54 +00:00
Christian Legge d7f6bc1614 Add REPLPING command for use during replication (#329)
* added replping command for initiating replication

* backwards compatibility for replping (retry if not recognized)

* don't allow ping during loading (load balancer fix)

* changed replping warning to notice
2021-07-29 15:50:30 -04:00
MalavanEQAlpha 83d878f111 Merge pull request #328 from EQ-Alpha/backtrace_for_alpine
Backtrace for alpine using libunwind
2021-07-28 17:17:06 -04:00
malavan 0fc6441c96 add some comments 2021-07-28 20:32:18 +00:00
malavan 5be1620629 add stacktrace message 2021-07-19 23:17:18 +00:00
malavan 685b87e2ef dd comment and set eip unused 2021-07-19 17:32:38 +00:00
malavan 72429c2106 dd comment and set eip unused 2021-07-19 17:31:24 +00:00
malavan 7707fe15a9 dd comment and set eip unused 2021-07-19 17:29:43 +00:00
malavan c583ffff41 add backtrace for alpine using libunwind 2021-07-19 17:20:52 +00:00
Christian Legge 7c1ab8b8e2 Merge pull request #321 from EQ-Alpha/ci-flags-fix
Requested changes from 6.2.2 merge
2021-07-15 16:42:02 -04:00
6 changed files with 102 additions and 13 deletions

No files matched your search

+11 -3
View File
@@ -127,7 +127,7 @@ ifneq ($(uname_S),Darwin)
endif
# Linux ARM32 needs -latomic at linking time
ifneq (,$(findstring armv,$(uname_M)))
FINAL_LIBS+=-latomic
FINAL_LIBS+=-latomic
endif
@@ -177,7 +177,7 @@ ifeq ($(uname_S),OpenBSD)
FINAL_CXXFLAGS+= -DUSE_BACKTRACE -I/usr/local/include
FINAL_LDFLAGS+= -L/usr/local/lib
FINAL_LIBS+= -lexecinfo
endif
endif
else
ifeq ($(uname_S),NetBSD)
@@ -187,7 +187,7 @@ ifeq ($(uname_S),NetBSD)
FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/pkg/include
FINAL_LDFLAGS+= -L/usr/pkg/lib
FINAL_LIBS+= -lexecinfo
endif
endif
else
ifeq ($(uname_S),FreeBSD)
# FreeBSD
@@ -316,6 +316,14 @@ else
endef
endif
# Alpine OS doesn't have support for the execinfo backtrace library we use for debug, so we provide an alternate implementation using libwunwind.
OS := $(shell cat /etc/os-release | grep ID= | head -n 1 | cut -d'=' -f2)
ifeq ($(OS),alpine)
FINAL_CXXFLAGS+=-DUNW_LOCAL_ONLY
FINAL_LIBS += -lunwind
endif
REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS)
REDIS_CXX=$(QUIET_CC)$(CXX) $(FINAL_CXXFLAGS)
KEYDB_AS=$(QUIET_CC) as --64 -g
+72 -4
View File
@@ -51,6 +51,12 @@ typedef ucontext_t sigcontext_t;
#include <cxxabi.h>
#endif /* HAVE_BACKTRACE */
//UNW_LOCAL_ONLY being set means we use libunwind for backtraces instead of execinfo
#ifdef UNW_LOCAL_ONLY
#include <libunwind.h>
#include <cxxabi.h>
#endif
#ifdef __CYGWIN__
#ifndef SA_ONSTACK
#define SA_ONSTACK 0x08000000
@@ -947,7 +953,7 @@ void _serverAssert(const char *estr, const char *file, int line) {
serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
if (g_pserver->crashlog_enabled) {
#ifdef HAVE_BACKTRACE
#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY
logStackTrace(NULL, 1);
#endif
printCrashReport();
@@ -1044,7 +1050,7 @@ void _serverPanic(const char *file, int line, const char *msg, ...) {
serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",fmtmsg,file,line);
if (g_pserver->crashlog_enabled) {
#ifdef HAVE_BACKTRACE
#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY
logStackTrace(NULL, 1);
#endif
printCrashReport();
@@ -1599,6 +1605,65 @@ void safe_write(int fd, const void *pv, ssize_t cb)
} while (offset < cb);
}
#ifdef UNW_LOCAL_ONLY
/* Logs the stack trace using the libunwind call.
* The eip argument is unused as libunwind only gets local context.
* The uplevel argument indicates how many of the calling functions to skip.
*/
void logStackTrace(void * eip, int uplevel) {
(void)eip;//UNUSED
const char *msg;
int fd = openDirectLogFiledes();
if (fd == -1) return; /* If we can't log there is anything to do. */
msg = "\n------ STACK TRACE ------\n";
if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */};
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
/* Write symbols to log file */
msg = "\nBacktrace:\n";
if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */};
for (int i = 0; i < uplevel; i++) {
unw_step(&cursor);
}
while ( unw_step(&cursor) ) {
unw_word_t ip, sp, off;
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
char symbol[256] = {"<unknown>"};
char *name = symbol;
if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) ) {
int status;
if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
name = symbol;
}
dprintf(fd, "%s(+0x%" PRIxPTR ") [0x%016" PRIxPTR "] sp=0x%016" PRIxPTR "\n",
name,
static_cast<uintptr_t>(off),
static_cast<uintptr_t>(ip),
static_cast<uintptr_t>(sp));
if ( name != symbol )
free(name);
}
}
#endif /* UNW_LOCAL_ONLY */
#ifdef HAVE_BACKTRACE
void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd)
{
char **syms = backtrace_symbols(trace, csym);
@@ -1642,8 +1707,6 @@ void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd)
free(syms);
}
#ifdef HAVE_BACKTRACE
/* Logs the stack trace using the backtrace() call. This function is designed
* to be called from signal handlers safely.
* The eip argument is optional (can take NULL).
@@ -1934,6 +1997,9 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
logRegisters(uc);
#endif
#ifdef UNW_LOCAL_ONLY
logStackTrace(NULL, 1);
#endif
printCrashReport();
@@ -2028,6 +2094,8 @@ void watchdogSignalHandler(int sig, siginfo_t *info, void *secret) {
serverLogFromHandler(LL_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---");
#ifdef HAVE_BACKTRACE
logStackTrace(getMcontextEip(uc), 1);
#elif defined UNW_LOCAL_ONLY
logStackTrace(NULL, 1);
#else
serverLogFromHandler(LL_WARNING,"Sorry: no support for backtrace().");
#endif
+11 -4
View File
@@ -2759,18 +2759,19 @@ void syncWithMaster(connection *conn) {
goto error;
}
retry_connect:
/* Send a PING to check the master is able to reply without errors. */
if (mi->repl_state == REPL_STATE_CONNECTING) {
if (mi->repl_state == REPL_STATE_CONNECTING || mi->repl_state == REPL_STATE_RETRY_NOREPLPING) {
serverLog(LL_NOTICE,"Non blocking connect for SYNC fired the event.");
/* Delete the writable event so that the readable event remains
* registered and we can wait for the PONG reply. */
connSetReadHandler(conn, syncWithMaster);
connSetWriteHandler(conn, NULL);
mi->repl_state = REPL_STATE_RECEIVE_PING_REPLY;
/* Send the PING, don't check for errors at all, we have the timeout
* that will take care about this. */
err = sendCommand(conn,"PING",NULL);
err = sendCommand(conn,mi->repl_state == REPL_STATE_RETRY_NOREPLPING ? "PING" : "REPLPING",NULL);
if (err) goto write_error;
mi->repl_state = REPL_STATE_RECEIVE_PING_REPLY;
return;
}
@@ -2783,7 +2784,13 @@ void syncWithMaster(connection *conn) {
* Note that older versions of Redis replied with "operation not
* permitted" instead of using a proper error code, so we test
* both. */
if (err[0] != '+' &&
if (strncmp(err,"-ERR unknown command",20) == 0) {
serverLog(LL_NOTICE,"Master does not support REPLPING, sending PING instead...");
mi->repl_state = REPL_STATE_RETRY_NOREPLPING;
sdsfree(err);
err = NULL;
goto retry_connect;
} else if (err[0] != '+' &&
strncmp(err,"-NOAUTH",7) != 0 &&
strncmp(err,"-NOPERM",7) != 0 &&
strncmp(err,"-ERR operation not permitted",28) != 0)
+5
View File
@@ -753,6 +753,10 @@ struct redisCommand redisCommandTable[] = {
"ok-stale ok-loading fast @connection @replication",
0,NULL,0,0,0,0,0,0},
{"replping",pingCommand,-1,
"ok-stale fast @connection @replication",
0,NULL,0,0,0,0,0,0},
{"echo",echoCommand,2,
"fast @connection",
0,NULL,0,0,0,0,0,0},
@@ -2768,6 +2772,7 @@ void createSharedObjects(void) {
shared.lastid = makeObjectShared("LASTID",6);
shared.default_username = makeObjectShared("default",7);
shared.ping = makeObjectShared("ping",4);
shared.replping = makeObjectShared("replping", 8);
shared.setid = makeObjectShared("SETID",5);
shared.keepttl = makeObjectShared("KEEPTTL",7);
shared.load = makeObjectShared("LOAD",4);
+2 -1
View File
@@ -505,6 +505,7 @@ typedef enum {
REPL_STATE_NONE = 0, /* No active replication */
REPL_STATE_CONNECT, /* Must connect to master */
REPL_STATE_CONNECTING, /* Connecting to master */
REPL_STATE_RETRY_NOREPLPING, /* Master does not support REPLPING, retry with PING */
/* --- Handshake states, must be ordered --- */
REPL_STATE_RECEIVE_PING_REPLY, /* Wait for PING reply */
REPL_STATE_SEND_HANDSHAKE, /* Send handshake sequance to master */
@@ -1283,7 +1284,7 @@ struct sharedObjectsStruct {
*emptyscan, *multi, *exec, *left, *right, *hset, *srem, *xgroup, *xclaim,
*script, *replconf, *eval, *persist, *set, *pexpireat, *pexpire,
*time, *pxat, *px, *retrycount, *force, *justid,
*lastid, *ping, *setid, *keepttl, *load, *createconsumer,
*lastid, *ping, *replping, *setid, *keepttl, *load, *createconsumer,
*getack, *special_asterick, *special_equals, *default_username,
*hdel, *zrem, *mvccrestore, *pexpirememberat,
*select[PROTO_SHARED_SELECT_CMDS],
+1 -1
View File
@@ -253,7 +253,7 @@ proc s {args} {
# test server, so that the test server will send them again to
# clients once the clients are idle.
proc run_solo {name code} {
if {$::numclients == 1 || $::loop || $::external || $::endurance} {
if {$::numclients == 1 || $::loop < 0 || $::external || $::endurance} {
# run_solo is not supported in these scenarios, just run the code.
if {$::endurance} {
puts "Skipping solo tests because endurance mode is enabled"