Skip to content

Commit bcfc686

Browse files
committed
Tcl script, make target, and redis.c changes to build the static symbol table automagically
1 parent f232429 commit bcfc686

File tree

5 files changed

+322
-215
lines changed

5 files changed

+322
-215
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ clean:
6060
dep:
6161
$(CC) -MM *.c
6262

63+
staticsymbols:
64+
tclsh utils/build-static-symbols.tcl > staticsymbols.h
65+
6366
test:
6467
tclsh test-redis.tcl
6568

TODO

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ VERSION 1.1 TODO
1010
* Write docs for the "STORE" operaiton of SORT, and GET "#" option.
1111
* Append only mode: testing and a command to rebuild the log from scratch.
1212
* Profiling and optimizations. For instance the commands lookup is probably starting to eat too CPU being a simple list. To implement binary search or an hash table lookup can be a win probably.
13-
* Expiring algorithm should be adaptive. Use the following algorithm. Start testing REDIS_EXPIRELOOKUPS_PER_CRON in the first iteration, and continue with the same amount of keys until the percentage of expired keys > 25%.
1413

1514
VERSION 1.2 TODO
1615

redis.c

+108-214
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ static struct redisCommand cmdTable[] = {
544544
{"debug",debugCommand,-2,REDIS_CMD_INLINE},
545545
{NULL,NULL,0,0}
546546
};
547+
547548
/*============================ Utility functions ============================ */
548549

549550
/* Glob-style pattern matching. */
@@ -1025,7 +1026,7 @@ static void appendServerSaveParams(time_t seconds, int changes) {
10251026
server.saveparamslen++;
10261027
}
10271028

1028-
static void ResetServerSaveParams() {
1029+
static void resetServerSaveParams() {
10291030
zfree(server.saveparams);
10301031
server.saveparams = NULL;
10311032
server.saveparamslen = 0;
@@ -1054,7 +1055,7 @@ static void initServerConfig() {
10541055
server.sharingpoolsize = 1024;
10551056
server.maxclients = 0;
10561057
server.maxmemory = 0;
1057-
ResetServerSaveParams();
1058+
resetServerSaveParams();
10581059

10591060
appendServerSaveParams(60*60,1); /* save after 1 hour and 1 change */
10601061
appendServerSaveParams(300,100); /* save after 5 minutes and 100 changes */
@@ -5534,150 +5535,91 @@ static void debugCommand(redisClient *c) {
55345535
}
55355536
}
55365537

5537-
#ifdef HAVE_BACKTRACE
5538-
static struct redisFunctionSym symsTable[] = {
5539-
{"compareStringObjects", (unsigned long)compareStringObjects},
5540-
{"isStringRepresentableAsLong", (unsigned long)isStringRepresentableAsLong},
5541-
{"dictEncObjKeyCompare", (unsigned long)dictEncObjKeyCompare},
5542-
{"dictEncObjHash", (unsigned long)dictEncObjHash},
5543-
{"incrDecrCommand", (unsigned long)incrDecrCommand},
5544-
{"freeStringObject", (unsigned long)freeStringObject},
5545-
{"freeListObject", (unsigned long)freeListObject},
5546-
{"freeSetObject", (unsigned long)freeSetObject},
5547-
{"decrRefCount", (unsigned long)decrRefCount},
5548-
{"createObject", (unsigned long)createObject},
5549-
{"freeClient", (unsigned long)freeClient},
5550-
{"rdbLoad", (unsigned long)rdbLoad},
5551-
{"rdbSaveStringObject", (unsigned long)rdbSaveStringObject},
5552-
{"rdbSaveStringObjectRaw", (unsigned long)rdbSaveStringObjectRaw},
5553-
{"addReply", (unsigned long)addReply},
5554-
{"addReplySds", (unsigned long)addReplySds},
5555-
{"incrRefCount", (unsigned long)incrRefCount},
5556-
{"rdbSaveBackground", (unsigned long)rdbSaveBackground},
5557-
{"createStringObject", (unsigned long)createStringObject},
5558-
{"replicationFeedSlaves", (unsigned long)replicationFeedSlaves},
5559-
{"syncWithMaster", (unsigned long)syncWithMaster},
5560-
{"tryObjectSharing", (unsigned long)tryObjectSharing},
5561-
{"tryObjectEncoding", (unsigned long)tryObjectEncoding},
5562-
{"getDecodedObject", (unsigned long)getDecodedObject},
5563-
{"removeExpire", (unsigned long)removeExpire},
5564-
{"expireIfNeeded", (unsigned long)expireIfNeeded},
5565-
{"deleteIfVolatile", (unsigned long)deleteIfVolatile},
5566-
{"deleteKey", (unsigned long)deleteKey},
5567-
{"getExpire", (unsigned long)getExpire},
5568-
{"setExpire", (unsigned long)setExpire},
5569-
{"updateSlavesWaitingBgsave", (unsigned long)updateSlavesWaitingBgsave},
5570-
{"freeMemoryIfNeeded", (unsigned long)freeMemoryIfNeeded},
5571-
{"authCommand", (unsigned long)authCommand},
5572-
{"pingCommand", (unsigned long)pingCommand},
5573-
{"echoCommand", (unsigned long)echoCommand},
5574-
{"setCommand", (unsigned long)setCommand},
5575-
{"setnxCommand", (unsigned long)setnxCommand},
5576-
{"getCommand", (unsigned long)getCommand},
5577-
{"delCommand", (unsigned long)delCommand},
5578-
{"existsCommand", (unsigned long)existsCommand},
5579-
{"incrCommand", (unsigned long)incrCommand},
5580-
{"decrCommand", (unsigned long)decrCommand},
5581-
{"incrbyCommand", (unsigned long)incrbyCommand},
5582-
{"decrbyCommand", (unsigned long)decrbyCommand},
5583-
{"selectCommand", (unsigned long)selectCommand},
5584-
{"randomkeyCommand", (unsigned long)randomkeyCommand},
5585-
{"keysCommand", (unsigned long)keysCommand},
5586-
{"dbsizeCommand", (unsigned long)dbsizeCommand},
5587-
{"lastsaveCommand", (unsigned long)lastsaveCommand},
5588-
{"saveCommand", (unsigned long)saveCommand},
5589-
{"bgsaveCommand", (unsigned long)bgsaveCommand},
5590-
{"shutdownCommand", (unsigned long)shutdownCommand},
5591-
{"moveCommand", (unsigned long)moveCommand},
5592-
{"renameCommand", (unsigned long)renameCommand},
5593-
{"renamenxCommand", (unsigned long)renamenxCommand},
5594-
{"lpushCommand", (unsigned long)lpushCommand},
5595-
{"rpushCommand", (unsigned long)rpushCommand},
5596-
{"lpopCommand", (unsigned long)lpopCommand},
5597-
{"rpopCommand", (unsigned long)rpopCommand},
5598-
{"llenCommand", (unsigned long)llenCommand},
5599-
{"lindexCommand", (unsigned long)lindexCommand},
5600-
{"lrangeCommand", (unsigned long)lrangeCommand},
5601-
{"ltrimCommand", (unsigned long)ltrimCommand},
5602-
{"typeCommand", (unsigned long)typeCommand},
5603-
{"lsetCommand", (unsigned long)lsetCommand},
5604-
{"saddCommand", (unsigned long)saddCommand},
5605-
{"sremCommand", (unsigned long)sremCommand},
5606-
{"smoveCommand", (unsigned long)smoveCommand},
5607-
{"sismemberCommand", (unsigned long)sismemberCommand},
5608-
{"scardCommand", (unsigned long)scardCommand},
5609-
{"spopCommand", (unsigned long)spopCommand},
5610-
{"srandmemberCommand", (unsigned long)srandmemberCommand},
5611-
{"sinterCommand", (unsigned long)sinterCommand},
5612-
{"sinterstoreCommand", (unsigned long)sinterstoreCommand},
5613-
{"sunionCommand", (unsigned long)sunionCommand},
5614-
{"sunionstoreCommand", (unsigned long)sunionstoreCommand},
5615-
{"sdiffCommand", (unsigned long)sdiffCommand},
5616-
{"sdiffstoreCommand", (unsigned long)sdiffstoreCommand},
5617-
{"syncCommand", (unsigned long)syncCommand},
5618-
{"flushdbCommand", (unsigned long)flushdbCommand},
5619-
{"flushallCommand", (unsigned long)flushallCommand},
5620-
{"sortCommand", (unsigned long)sortCommand},
5621-
{"lremCommand", (unsigned long)lremCommand},
5622-
{"infoCommand", (unsigned long)infoCommand},
5623-
{"mgetCommand", (unsigned long)mgetCommand},
5624-
{"monitorCommand", (unsigned long)monitorCommand},
5625-
{"expireCommand", (unsigned long)expireCommand},
5626-
{"expireatCommand", (unsigned long)expireatCommand},
5627-
{"getsetCommand", (unsigned long)getsetCommand},
5628-
{"ttlCommand", (unsigned long)ttlCommand},
5629-
{"slaveofCommand", (unsigned long)slaveofCommand},
5630-
{"debugCommand", (unsigned long)debugCommand},
5631-
{"processCommand", (unsigned long)processCommand},
5632-
{"setupSigSegvAction", (unsigned long)setupSigSegvAction},
5633-
{"readQueryFromClient", (unsigned long)readQueryFromClient},
5634-
{"rdbRemoveTempFile", (unsigned long)rdbRemoveTempFile},
5635-
{"msetGenericCommand", (unsigned long)msetGenericCommand},
5636-
{"msetCommand", (unsigned long)msetCommand},
5637-
{"msetnxCommand", (unsigned long)msetnxCommand},
5638-
{"zslCreateNode", (unsigned long)zslCreateNode},
5639-
{"zslCreate", (unsigned long)zslCreate},
5640-
{"zslFreeNode",(unsigned long)zslFreeNode},
5641-
{"zslFree",(unsigned long)zslFree},
5642-
{"zslRandomLevel",(unsigned long)zslRandomLevel},
5643-
{"zslInsert",(unsigned long)zslInsert},
5644-
{"zslDelete",(unsigned long)zslDelete},
5645-
{"createZsetObject",(unsigned long)createZsetObject},
5646-
{"zaddCommand",(unsigned long)zaddCommand},
5647-
{"zrangeGenericCommand",(unsigned long)zrangeGenericCommand},
5648-
{"zrangeCommand",(unsigned long)zrangeCommand},
5649-
{"zrevrangeCommand",(unsigned long)zrevrangeCommand},
5650-
{"zremCommand",(unsigned long)zremCommand},
5651-
{"rdbSaveDoubleValue",(unsigned long)rdbSaveDoubleValue},
5652-
{"rdbLoadDoubleValue",(unsigned long)rdbLoadDoubleValue},
5653-
{"feedAppendOnlyFile",(unsigned long)feedAppendOnlyFile},
5654-
{NULL,0}
5655-
};
5538+
/* =================================== Main! ================================ */
56565539

5657-
/* This function try to convert a pointer into a function name. It's used in
5658-
* oreder to provide a backtrace under segmentation fault that's able to
5659-
* display functions declared as static (otherwise the backtrace is useless). */
5660-
static char *findFuncName(void *pointer, unsigned long *offset){
5661-
int i, ret = -1;
5662-
unsigned long off, minoff = 0;
5540+
#ifdef __linux__
5541+
int linuxOvercommitMemoryValue(void) {
5542+
FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
5543+
char buf[64];
56635544

5664-
/* Try to match against the Symbol with the smallest offset */
5665-
for (i=0; symsTable[i].pointer; i++) {
5666-
unsigned long lp = (unsigned long) pointer;
5545+
if (!fp) return -1;
5546+
if (fgets(buf,64,fp) == NULL) {
5547+
fclose(fp);
5548+
return -1;
5549+
}
5550+
fclose(fp);
56675551

5668-
if (lp != (unsigned long)-1 && lp >= symsTable[i].pointer) {
5669-
off=lp-symsTable[i].pointer;
5670-
if (ret < 0 || off < minoff) {
5671-
minoff=off;
5672-
ret=i;
5673-
}
5674-
}
5552+
return atoi(buf);
5553+
}
5554+
5555+
void linuxOvercommitMemoryWarning(void) {
5556+
if (linuxOvercommitMemoryValue() == 0) {
5557+
redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low condition memory. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.");
5558+
}
5559+
}
5560+
#endif /* __linux__ */
5561+
5562+
static void daemonize(void) {
5563+
int fd;
5564+
FILE *fp;
5565+
5566+
if (fork() != 0) exit(0); /* parent exits */
5567+
setsid(); /* create a new session */
5568+
5569+
/* Every output goes to /dev/null. If Redis is daemonized but
5570+
* the 'logfile' is set to 'stdout' in the configuration file
5571+
* it will not log at all. */
5572+
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
5573+
dup2(fd, STDIN_FILENO);
5574+
dup2(fd, STDOUT_FILENO);
5575+
dup2(fd, STDERR_FILENO);
5576+
if (fd > STDERR_FILENO) close(fd);
5577+
}
5578+
/* Try to write the pid file */
5579+
fp = fopen(server.pidfile,"w");
5580+
if (fp) {
5581+
fprintf(fp,"%d\n",getpid());
5582+
fclose(fp);
56755583
}
5676-
if (ret == -1) return NULL;
5677-
*offset = minoff;
5678-
return symsTable[ret].name;
56795584
}
56805585

5586+
int main(int argc, char **argv) {
5587+
initServerConfig();
5588+
if (argc == 2) {
5589+
resetServerSaveParams();
5590+
loadServerConfig(argv[1]);
5591+
} else if (argc > 2) {
5592+
fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
5593+
exit(1);
5594+
} else {
5595+
redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
5596+
}
5597+
initServer();
5598+
if (server.daemonize) daemonize();
5599+
redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);
5600+
#ifdef __linux__
5601+
linuxOvercommitMemoryWarning();
5602+
#endif
5603+
if (server.appendonly) {
5604+
if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK)
5605+
redisLog(REDIS_NOTICE,"DB loaded from append only file");
5606+
} else {
5607+
if (rdbLoad(server.dbfilename) == REDIS_OK)
5608+
redisLog(REDIS_NOTICE,"DB loaded from disk");
5609+
}
5610+
if (aeCreateFileEvent(server.el, server.fd, AE_READABLE,
5611+
acceptHandler, NULL, NULL) == AE_ERR) oom("creating file event");
5612+
redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);
5613+
aeMain(server.el);
5614+
aeDeleteEventLoop(server.el);
5615+
return 0;
5616+
}
5617+
5618+
/* ============================= Backtrace support ========================= */
5619+
5620+
#ifdef HAVE_BACKTRACE
5621+
static char *findFuncName(void *pointer, unsigned long *offset);
5622+
56815623
static void *getMcontextEip(ucontext_t *uc) {
56825624
#if defined(__FreeBSD__)
56835625
return (void*) uc->uc_mcontext.mc_eip;
@@ -5772,87 +5714,39 @@ static void setupSigSegvAction(void) {
57725714
sigaction (SIGBUS, &act, NULL);
57735715
return;
57745716
}
5775-
#else /* HAVE_BACKTRACE */
5776-
static void setupSigSegvAction(void) {
5777-
}
5778-
#endif /* HAVE_BACKTRACE */
57795717

5780-
/* =================================== Main! ================================ */
5718+
#include "staticsymbols.h"
5719+
/* This function try to convert a pointer into a function name. It's used in
5720+
* oreder to provide a backtrace under segmentation fault that's able to
5721+
* display functions declared as static (otherwise the backtrace is useless). */
5722+
static char *findFuncName(void *pointer, unsigned long *offset){
5723+
int i, ret = -1;
5724+
unsigned long off, minoff = 0;
57815725

5782-
#ifdef __linux__
5783-
int linuxOvercommitMemoryValue(void) {
5784-
FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
5785-
char buf[64];
5726+
/* Try to match against the Symbol with the smallest offset */
5727+
for (i=0; symsTable[i].pointer; i++) {
5728+
unsigned long lp = (unsigned long) pointer;
57865729

5787-
if (!fp) return -1;
5788-
if (fgets(buf,64,fp) == NULL) {
5789-
fclose(fp);
5790-
return -1;
5730+
if (lp != (unsigned long)-1 && lp >= symsTable[i].pointer) {
5731+
off=lp-symsTable[i].pointer;
5732+
if (ret < 0 || off < minoff) {
5733+
minoff=off;
5734+
ret=i;
5735+
}
5736+
}
57915737
}
5792-
fclose(fp);
5793-
5794-
return atoi(buf);
5738+
if (ret == -1) return NULL;
5739+
*offset = minoff;
5740+
return symsTable[ret].name;
57955741
}
5796-
5797-
void linuxOvercommitMemoryWarning(void) {
5798-
if (linuxOvercommitMemoryValue() == 0) {
5799-
redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low condition memory. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.");
5800-
}
5742+
#else /* HAVE_BACKTRACE */
5743+
static void setupSigSegvAction(void) {
58015744
}
5802-
#endif /* __linux__ */
5745+
#endif /* HAVE_BACKTRACE */
58035746

5804-
static void daemonize(void) {
5805-
int fd;
5806-
FILE *fp;
58075747

5808-
if (fork() != 0) exit(0); /* parent exits */
5809-
setsid(); /* create a new session */
58105748

5811-
/* Every output goes to /dev/null. If Redis is daemonized but
5812-
* the 'logfile' is set to 'stdout' in the configuration file
5813-
* it will not log at all. */
5814-
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
5815-
dup2(fd, STDIN_FILENO);
5816-
dup2(fd, STDOUT_FILENO);
5817-
dup2(fd, STDERR_FILENO);
5818-
if (fd > STDERR_FILENO) close(fd);
5819-
}
5820-
/* Try to write the pid file */
5821-
fp = fopen(server.pidfile,"w");
5822-
if (fp) {
5823-
fprintf(fp,"%d\n",getpid());
5824-
fclose(fp);
5825-
}
5826-
}
5749+
/* The End */
5750+
5751+
58275752

5828-
int main(int argc, char **argv) {
5829-
initServerConfig();
5830-
if (argc == 2) {
5831-
ResetServerSaveParams();
5832-
loadServerConfig(argv[1]);
5833-
} else if (argc > 2) {
5834-
fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
5835-
exit(1);
5836-
} else {
5837-
redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
5838-
}
5839-
initServer();
5840-
if (server.daemonize) daemonize();
5841-
redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);
5842-
#ifdef __linux__
5843-
linuxOvercommitMemoryWarning();
5844-
#endif
5845-
if (server.appendonly) {
5846-
if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK)
5847-
redisLog(REDIS_NOTICE,"DB loaded from append only file");
5848-
} else {
5849-
if (rdbLoad(server.dbfilename) == REDIS_OK)
5850-
redisLog(REDIS_NOTICE,"DB loaded from disk");
5851-
}
5852-
if (aeCreateFileEvent(server.el, server.fd, AE_READABLE,
5853-
acceptHandler, NULL, NULL) == AE_ERR) oom("creating file event");
5854-
redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);
5855-
aeMain(server.el);
5856-
aeDeleteEventLoop(server.el);
5857-
return 0;
5858-
}

0 commit comments

Comments
 (0)