cygwin的安装参考前文: https://my.oschina.net/abensky/blog/5386053
cygwin (64位) 3.3, redis 6.2
编译后的文件放在 https://gitee.com/aben_skys/redis-windows
cygwin下编译redis
cd ~
wget -O redis-6.2.6.tar.gz https://download.redis.io/releases/redis-6.2.6.tar.gz
tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6
make
编译时出现错误:
debug.c:1753:5: error: unknown type name ‘Dl_info’
1753 | Dl_info info;
| ^~~~~~~
debug.c:1763:13: warning: implicit declaration of function ‘dladdr’; did you mean ‘s_addr’? [-Wimplicit-function-declaration]
1763 | if (dladdr((void*)target, &info) != 0 && info.dli_sname != NULL) {
| ^~~~~~
| s_addr
debug.c:1763:54: error: request for member ‘dli_sname’ in something not a structure or union
1763 | if (dladdr((void*)target, &info) != 0 && info.dli_sname != NULL) {
| ^
debug.c:1765:63: error: request for member ‘dli_sname’ in something not a structure or union
1765 | printf("Function at 0x%lx is %s\n",target,info.dli_sname);
| ^
debug.c: In function ‘dumpCodeAroundEIP’:
debug.c:1774:5: error: unknown type name ‘Dl_info’
1774 | Dl_info info;
| ^~~~~~~
In file included from debug.c:31:
debug.c:1783:17: error: request for member ‘dli_sname’ in something not a structure or union
1783 | info.dli_sname, info.dli_saddr, info.dli_fname, info.dli_fbase,
| ^
server.h:2744:27: note: in definition of macro ‘serverLog’
2744 | _serverLog(level, __VA_ARGS__);\
| ^~~~~~~~~~~
debug.c:1783:33: error: request for member ‘dli_saddr’ in something not a structure or union
1783 | info.dli_sname, info.dli_saddr, info.dli_fname, info.dli_fbase,
| ^
server.h:2744:27: note: in definition of macro ‘serverLog’
2744 | _serverLog(level, __VA_ARGS__);\
| ^~~~~~~~~~~
debug.c:1783:49: error: request for member ‘dli_fname’ in something not a structure or union
1783 | info.dli_sname, info.dli_saddr, info.dli_fname, info.dli_fbase,
| ^
server.h:2744:27: note: in definition of macro ‘serverLog’
2744 | _serverLog(level, __VA_ARGS__);\
| ^~~~~~~~~~~
debug.c:1783:65: error: request for member ‘dli_fbase’ in something not a structure or union
1783 | info.dli_sname, info.dli_saddr, info.dli_fname, info.dli_fbase,
| ^
server.h:2744:27: note: in definition of macro ‘serverLog’
2744 | _serverLog(level, __VA_ARGS__);\
| ^~~~~~~~~~~
debug.c:1784:17: error: request for member ‘dli_saddr’ in something not a structure or union
1784 | info.dli_saddr);
| ^
server.h:2744:27: note: in definition of macro ‘serverLog’
2744 | _serverLog(level, __VA_ARGS__);\
| ^~~~~~~~~~~
debug.c:1785:44: error: request for member ‘dli_saddr’ in something not a structure or union
1785 | size_t len = (long)eip - (long)info.dli_saddr;
| ^
debug.c:1791:38: error: request for member ‘dli_saddr’ in something not a structure or union
1791 | void *base = (void *)info.dli_saddr;
| ^
make[1]: *** [Makefile:374: debug.o] Error 1
make[1]: Leaving directory '/home/aben/redis-6.2.6/src'
make: *** [Makefile:6: all] Error 2
针对 error: unknown type name ‘Dl_info’
错误, 参考: https://github.com/redis/redis/issues/8694 需要修改 src/debug.c
的 void dumpX86Calls
前后的内容(三处, 注意 cygwin修正
注释的地方):
/*cygwin修正: 新增*/
typedef struct Dl_info{
unsigned char *dli_sname;
unsigned char *dli_saddr;
unsigned char *dli_fname;
unsigned char *dli_fbase;
}info;
/* Scans the (assumed) x86 code starting at addr, for a max of `len`
* bytes, searching for E8 (callq) opcodes, and dumping the symbols
* and the call offset if they appear to be valid. */
void dumpX86Calls(void *addr, size_t len) {
size_t j;
unsigned char *p = addr;
/*cygwin修正: Dl_info info 前面要加 struct*/
struct Dl_info info;
/* Hash table to best-effort avoid printing the same symbol
* multiple times. */
unsigned long ht[256] = {0};
if (len < 5) return;
for (j = 0; j < len-4; j++) {
if (p[j] != 0xE8) continue; /* Not an E8 CALL opcode. */
unsigned long target = (unsigned long)addr+j+5;
target += *((int32_t*)(p+j+1));
if (dladdr((void*)target, &info) != 0 && info.dli_sname != NULL) {
if (ht[target&0xff] != target) {
printf("Function at 0x%lx is %s\n",target,info.dli_sname);
ht[target&0xff] = target;
}
j += 4; /* Skip the 32 bit immediate. */
}
}
}
void dumpCodeAroundEIP(void *eip) {
/*cygwin修正: Dl_info info 前面要加 struct*/
struct Dl_info info;
看图:
测试: make test
(此步可以略过)
需要安装 tcl 85.+:
apt-cyg install tcl
. 虽然有几个错误, 但是不影响使用
启动:
src/redis-server
客户端(新开一个cygwin命令行):
cd ~
cd redis-6.2.6
src/redis-cli
windows下执行
我们把编译好的文件放到 c:\lnmp\redis
目录下
1. 从目录 redis-6.2.6
及其下 src
处复制文件
#使用cp+大括号一次性复制多个文件
cp {README.md,redis.conf,sentinel.conf,TLS.md} /cygdrive/c/lnmp/redis/
cp src/{redis-benchmark.exe,redis-check-aof.exe,redis-check-rdb.exe,redis-cli.exe,redis-sentinel.exe,redis-server.exe} /cygdrive/c/lnmp/redis/
2.复制cygwin必须的dll文件
cp /cygdrive/c/cygwin64/bin/cygwin1.dll /cygdrive/c/lnmp/redis/
3. 启动命令
此时启动 redis-server
会显示没有找到配置文件, 所以我们要在启动时指定配置文件:
#命令行的第一个参数是配置文件
redis-server.exe redis.conf
redis的rdb持久化是默认开启的, 但是save策略建议手动修改为:
save 900 1
save 300 10
save 60 10000