Merge branch 'unstable' of github.com:/antirez/redis into unstable

This commit is contained in:
antirez 2018-11-28 17:12:32 +01:00
commit fc022031d3
6 changed files with 198 additions and 13 deletions

View File

@ -102,14 +102,20 @@ else
ifeq ($(uname_S),OpenBSD) ifeq ($(uname_S),OpenBSD)
# OpenBSD # OpenBSD
FINAL_LIBS+= -lpthread FINAL_LIBS+= -lpthread
ifeq ($(USE_BACKTRACE),yes)
FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/local/include
FINAL_LDFLAGS+= -L/usr/local/lib
FINAL_LIBS+= -lexecinfo
endif
else else
ifeq ($(uname_S),FreeBSD) ifeq ($(uname_S),FreeBSD)
# FreeBSD # FreeBSD
FINAL_LIBS+= -lpthread FINAL_LIBS+= -lpthread -lexecinfo
else else
ifeq ($(uname_S),DragonFly) ifeq ($(uname_S),DragonFly)
# FreeBSD # FreeBSD
FINAL_LIBS+= -lpthread FINAL_LIBS+= -lpthread -lexecinfo
else else
# All the other OSes (notably Linux) # All the other OSes (notably Linux)
FINAL_LDFLAGS+= -rdynamic FINAL_LDFLAGS+= -rdynamic

View File

@ -62,7 +62,9 @@
#endif #endif
/* Test for backtrace() */ /* Test for backtrace() */
#if defined(__APPLE__) || (defined(__linux__) && defined(__GLIBC__)) #if defined(__APPLE__) || (defined(__linux__) && defined(__GLIBC__)) || \
defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(USE_BACKTRACE))\
|| defined(__DragonFly__)
#define HAVE_BACKTRACE 1 #define HAVE_BACKTRACE 1
#endif #endif

View File

@ -37,7 +37,11 @@
#ifdef HAVE_BACKTRACE #ifdef HAVE_BACKTRACE
#include <execinfo.h> #include <execinfo.h>
#ifndef __OpenBSD__
#include <ucontext.h> #include <ucontext.h>
#else
typedef ucontext_t sigcontext_t;
#endif
#include <fcntl.h> #include <fcntl.h>
#include "bio.h" #include "bio.h"
#include <unistd.h> #include <unistd.h>
@ -729,6 +733,22 @@ static void *getMcontextEip(ucontext_t *uc) {
#elif defined(__aarch64__) /* Linux AArch64 */ #elif defined(__aarch64__) /* Linux AArch64 */
return (void*) uc->uc_mcontext.pc; return (void*) uc->uc_mcontext.pc;
#endif #endif
#elif defined(__FreeBSD__)
/* FreeBSD */
#if defined(__i386__)
return (void*) uc->uc_mcontext.mc_eip;
#elif defined(__x86_64__)
return (void*) uc->uc_mcontext.mc_rip;
#endif
#elif defined(__OpenBSD__)
/* OpenBSD */
#if defined(__i386__)
return (void*) uc->sc_eip;
#elif defined(__x86_64__)
return (void*) uc->sc_rip;
#endif
#elif defined(__DragonFly__)
return (void*) uc->uc_mcontext.mc_rip;
#else #else
return NULL; return NULL;
#endif #endif
@ -870,6 +890,145 @@ void logRegisters(ucontext_t *uc) {
); );
logStackContent((void**)uc->uc_mcontext.gregs[15]); logStackContent((void**)uc->uc_mcontext.gregs[15]);
#endif #endif
#elif defined(__FreeBSD__)
#if defined(__x86_64__)
serverLog(LL_WARNING,
"\n"
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
"R8 :%016lx R9 :%016lx\nR10:%016lx R11:%016lx\n"
"R12:%016lx R13:%016lx\nR14:%016lx R15:%016lx\n"
"RIP:%016lx EFL:%016lx\nCSGSFS:%016lx",
(unsigned long) uc->uc_mcontext.mc_rax,
(unsigned long) uc->uc_mcontext.mc_rbx,
(unsigned long) uc->uc_mcontext.mc_rcx,
(unsigned long) uc->uc_mcontext.mc_rdx,
(unsigned long) uc->uc_mcontext.mc_rdi,
(unsigned long) uc->uc_mcontext.mc_rsi,
(unsigned long) uc->uc_mcontext.mc_rbp,
(unsigned long) uc->uc_mcontext.mc_rsp,
(unsigned long) uc->uc_mcontext.mc_r8,
(unsigned long) uc->uc_mcontext.mc_r9,
(unsigned long) uc->uc_mcontext.mc_r10,
(unsigned long) uc->uc_mcontext.mc_r11,
(unsigned long) uc->uc_mcontext.mc_r12,
(unsigned long) uc->uc_mcontext.mc_r13,
(unsigned long) uc->uc_mcontext.mc_r14,
(unsigned long) uc->uc_mcontext.mc_r15,
(unsigned long) uc->uc_mcontext.mc_rip,
(unsigned long) uc->uc_mcontext.mc_rflags,
(unsigned long) uc->uc_mcontext.mc_cs
);
logStackContent((void**)uc->uc_mcontext.mc_rsp);
#elif defined(__i386__)
serverLog(LL_WARNING,
"\n"
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
"SS :%08lx EFL:%08lx EIP:%08lx CS:%08lx\n"
"DS :%08lx ES :%08lx FS :%08lx GS:%08lx",
(unsigned long) uc->uc_mcontext.mc_eax,
(unsigned long) uc->uc_mcontext.mc_ebx,
(unsigned long) uc->uc_mcontext.mc_ebx,
(unsigned long) uc->uc_mcontext.mc_edx,
(unsigned long) uc->uc_mcontext.mc_edi,
(unsigned long) uc->uc_mcontext.mc_esi,
(unsigned long) uc->uc_mcontext.mc_ebp,
(unsigned long) uc->uc_mcontext.mc_esp,
(unsigned long) uc->uc_mcontext.mc_ss,
(unsigned long) uc->uc_mcontext.mc_eflags,
(unsigned long) uc->uc_mcontext.mc_eip,
(unsigned long) uc->uc_mcontext.mc_cs,
(unsigned long) uc->uc_mcontext.mc_es,
(unsigned long) uc->uc_mcontext.mc_fs,
(unsigned long) uc->uc_mcontext.mc_gs
);
logStackContent((void**)uc->uc_mcontext.mc_esp);
#endif
#elif defined(__OpenBSD__)
#if defined(__x86_64__)
serverLog(LL_WARNING,
"\n"
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
"R8 :%016lx R9 :%016lx\nR10:%016lx R11:%016lx\n"
"R12:%016lx R13:%016lx\nR14:%016lx R15:%016lx\n"
"RIP:%016lx EFL:%016lx\nCSGSFS:%016lx",
(unsigned long) uc->sc_rax,
(unsigned long) uc->sc_rbx,
(unsigned long) uc->sc_rcx,
(unsigned long) uc->sc_rdx,
(unsigned long) uc->sc_rdi,
(unsigned long) uc->sc_rsi,
(unsigned long) uc->sc_rbp,
(unsigned long) uc->sc_rsp,
(unsigned long) uc->sc_r8,
(unsigned long) uc->sc_r9,
(unsigned long) uc->sc_r10,
(unsigned long) uc->sc_r11,
(unsigned long) uc->sc_r12,
(unsigned long) uc->sc_r13,
(unsigned long) uc->sc_r14,
(unsigned long) uc->sc_r15,
(unsigned long) uc->sc_rip,
(unsigned long) uc->sc_rflags,
(unsigned long) uc->sc_cs
);
logStackContent((void**)uc->sc_rsp);
#elif defined(__i386__)
serverLog(LL_WARNING,
"\n"
"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n"
"EDI:%08lx ESI:%08lx EBP:%08lx ESP:%08lx\n"
"SS :%08lx EFL:%08lx EIP:%08lx CS:%08lx\n"
"DS :%08lx ES :%08lx FS :%08lx GS:%08lx",
(unsigned long) uc->sc_eax,
(unsigned long) uc->sc_ebx,
(unsigned long) uc->sc_ebx,
(unsigned long) uc->sc_edx,
(unsigned long) uc->sc_edi,
(unsigned long) uc->sc_esi,
(unsigned long) uc->sc_ebp,
(unsigned long) uc->sc_esp,
(unsigned long) uc->sc_ss,
(unsigned long) uc->sc_eflags,
(unsigned long) uc->sc_eip,
(unsigned long) uc->sc_cs,
(unsigned long) uc->sc_es,
(unsigned long) uc->sc_fs,
(unsigned long) uc->sc_gs
);
logStackContent((void**)uc->sc_esp);
#endif
#elif defined(__DragonFly__)
serverLog(LL_WARNING,
"\n"
"RAX:%016lx RBX:%016lx\nRCX:%016lx RDX:%016lx\n"
"RDI:%016lx RSI:%016lx\nRBP:%016lx RSP:%016lx\n"
"R8 :%016lx R9 :%016lx\nR10:%016lx R11:%016lx\n"
"R12:%016lx R13:%016lx\nR14:%016lx R15:%016lx\n"
"RIP:%016lx EFL:%016lx\nCSGSFS:%016lx",
(unsigned long) uc->uc_mcontext.mc_rax,
(unsigned long) uc->uc_mcontext.mc_rbx,
(unsigned long) uc->uc_mcontext.mc_rcx,
(unsigned long) uc->uc_mcontext.mc_rdx,
(unsigned long) uc->uc_mcontext.mc_rdi,
(unsigned long) uc->uc_mcontext.mc_rsi,
(unsigned long) uc->uc_mcontext.mc_rbp,
(unsigned long) uc->uc_mcontext.mc_rsp,
(unsigned long) uc->uc_mcontext.mc_r8,
(unsigned long) uc->uc_mcontext.mc_r9,
(unsigned long) uc->uc_mcontext.mc_r10,
(unsigned long) uc->uc_mcontext.mc_r11,
(unsigned long) uc->uc_mcontext.mc_r12,
(unsigned long) uc->uc_mcontext.mc_r13,
(unsigned long) uc->uc_mcontext.mc_r14,
(unsigned long) uc->uc_mcontext.mc_r15,
(unsigned long) uc->uc_mcontext.mc_rip,
(unsigned long) uc->uc_mcontext.mc_rflags,
(unsigned long) uc->uc_mcontext.mc_cs
);
logStackContent((void**)uc->uc_mcontext.mc_rsp);
#else #else
serverLog(LL_WARNING, serverLog(LL_WARNING,
" Dumping of registers not supported for this OS/arch"); " Dumping of registers not supported for this OS/arch");

View File

@ -1958,9 +1958,13 @@ int listenToPort(int port, int *fds, int *count) {
} }
if (fds[*count] == ANET_ERR) { if (fds[*count] == ANET_ERR) {
serverLog(LL_WARNING, serverLog(LL_WARNING,
"Creating Server TCP listening socket %s:%d: %s", "Could not create server TCP listening socket %s:%d: %s",
server.bindaddr[j] ? server.bindaddr[j] : "*", server.bindaddr[j] ? server.bindaddr[j] : "*",
port, server.neterr); port, server.neterr);
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
errno == EAFNOSUPPORT || errno == EADDRNOTAVAIL)
continue;
return C_ERR; return C_ERR;
} }
anetNonBlock(NULL,fds[*count]); anetNonBlock(NULL,fds[*count]);

View File

@ -574,12 +574,12 @@ int zslParseLexRangeItem(robj *item, sds *dest, int *ex) {
switch(c[0]) { switch(c[0]) {
case '+': case '+':
if (c[1] != '\0') return C_ERR; if (c[1] != '\0') return C_ERR;
*ex = 0; *ex = 1;
*dest = shared.maxstring; *dest = shared.maxstring;
return C_OK; return C_OK;
case '-': case '-':
if (c[1] != '\0') return C_ERR; if (c[1] != '\0') return C_ERR;
*ex = 0; *ex = 1;
*dest = shared.minstring; *dest = shared.minstring;
return C_OK; return C_OK;
case '(': case '(':
@ -652,9 +652,8 @@ int zslIsInLexRange(zskiplist *zsl, zlexrangespec *range) {
zskiplistNode *x; zskiplistNode *x;
/* Test for ranges that will always be empty. */ /* Test for ranges that will always be empty. */
if (sdscmplex(range->min,range->max) > 1 || int cmp = sdscmplex(range->min,range->max);
(sdscmp(range->min,range->max) == 0 && if (cmp > 0 || (cmp == 0 && (range->minex || range->maxex)))
(range->minex || range->maxex)))
return 0; return 0;
x = zsl->tail; x = zsl->tail;
if (x == NULL || !zslLexValueGteMin(x->ele,range)) if (x == NULL || !zslLexValueGteMin(x->ele,range))
@ -927,9 +926,8 @@ int zzlIsInLexRange(unsigned char *zl, zlexrangespec *range) {
unsigned char *p; unsigned char *p;
/* Test for ranges that will always be empty. */ /* Test for ranges that will always be empty. */
if (sdscmplex(range->min,range->max) > 1 || int cmp = sdscmplex(range->min,range->max);
(sdscmp(range->min,range->max) == 0 && if (cmp > 0 || (cmp == 0 && (range->minex || range->maxex)))
(range->minex || range->maxex)))
return 0; return 0;
p = ziplistIndex(zl,-2); /* Last element. */ p = ziplistIndex(zl,-2); /* Last element. */

View File

@ -388,7 +388,7 @@ start_server {tags {"zset"}} {
0 omega} 0 omega}
} }
test "ZRANGEBYLEX/ZREVRANGEBYLEX/ZCOUNT basics" { test "ZRANGEBYLEX/ZREVRANGEBYLEX/ZLEXCOUNT basics" {
create_default_lex_zset create_default_lex_zset
# inclusive range # inclusive range
@ -417,6 +417,22 @@ start_server {tags {"zset"}} {
assert_equal {} [r zrevrangebylex zset (hill (omega] assert_equal {} [r zrevrangebylex zset (hill (omega]
} }
test "ZLEXCOUNT advanced" {
create_default_lex_zset
assert_equal 9 [r zlexcount zset - +]
assert_equal 0 [r zlexcount zset + -]
assert_equal 0 [r zlexcount zset + \[c]
assert_equal 0 [r zlexcount zset \[c -]
assert_equal 8 [r zlexcount zset \[bar +]
assert_equal 5 [r zlexcount zset \[bar \[foo]
assert_equal 4 [r zlexcount zset \[bar (foo]
assert_equal 4 [r zlexcount zset (bar \[foo]
assert_equal 3 [r zlexcount zset (bar (foo]
assert_equal 5 [r zlexcount zset - (foo]
assert_equal 1 [r zlexcount zset (maxstring +]
}
test "ZRANGEBYSLEX with LIMIT" { test "ZRANGEBYSLEX with LIMIT" {
create_default_lex_zset create_default_lex_zset
assert_equal {alpha bar} [r zrangebylex zset - \[cool LIMIT 0 2] assert_equal {alpha bar} [r zrangebylex zset - \[cool LIMIT 0 2]