Skip to content

Commit

Permalink
Correct cleanup when aborting AOF loading.
Browse files Browse the repository at this point in the history
Because of the new ability to start with a truncated AOF, we need
to correctly release all the memory on EOF error. Otherwise there is a
small leak, that is not really a problem, but causes a false positive in
the tests that detect memory leaks.
  • Loading branch information
antirez committed Sep 8, 2014
1 parent ea1de5c commit 24b3f78
Showing 1 changed file with 29 additions and 8 deletions.
37 changes: 29 additions & 8 deletions src/aof.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,14 @@ struct redisClient *createFakeClient(void) {
return c;
}

void freeFakeClientArgv(struct redisClient *c) {
int j;

for (j = 0; j < c->argc; j++)
decrRefCount(c->argv[j]);
zfree(c->argv);
}

void freeFakeClient(struct redisClient *c) {
sdsfree(c->querybuf);
listRelease(c->reply);
Expand Down Expand Up @@ -639,14 +647,30 @@ int loadAppendOnlyFile(char *filename) {
if (argc < 1) goto fmterr;

argv = zmalloc(sizeof(robj*)*argc);
fakeClient->argc = argc;
fakeClient->argv = argv;

for (j = 0; j < argc; j++) {
if (fgets(buf,sizeof(buf),fp) == NULL) goto readerr;
if (fgets(buf,sizeof(buf),fp) == NULL) {
fakeClient->argc = j; /* Free up to j-1. */
freeFakeClientArgv(fakeClient);
goto readerr;
}
if (buf[0] != '$') goto fmterr;
len = strtol(buf+1,NULL,10);
argsds = sdsnewlen(NULL,len);
if (len && fread(argsds,len,1,fp) == 0) goto readerr;
if (len && fread(argsds,len,1,fp) == 0) {
sdsfree(argsds);
fakeClient->argc = j; /* Free up to j-1. */
freeFakeClientArgv(fakeClient);
goto readerr;
}
argv[j] = createObject(REDIS_STRING,argsds);
if (fread(buf,2,1,fp) == 0) goto readerr; /* discard CRLF */
if (fread(buf,2,1,fp) == 0) {
fakeClient->argc = j+1; /* Free up to j. */
freeFakeClientArgv(fakeClient);
goto readerr; /* discard CRLF */
}
}

/* Command lookup */
Expand All @@ -655,9 +679,8 @@ int loadAppendOnlyFile(char *filename) {
redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr);
exit(1);
}

/* Run the command in the context of a fake client */
fakeClient->argc = argc;
fakeClient->argv = argv;
cmd->proc(fakeClient);

/* The fake client should not have a reply */
Expand All @@ -667,9 +690,7 @@ int loadAppendOnlyFile(char *filename) {

/* Clean up. Command code may have changed argv/argc so we use the
* argv/argc of the client instead of the local variables. */
for (j = 0; j < fakeClient->argc; j++)
decrRefCount(fakeClient->argv[j]);
zfree(fakeClient->argv);
freeFakeClientArgv(fakeClient);
}

/* This point can only be reached when EOF is reached without errors.
Expand Down

0 comments on commit 24b3f78

Please sign in to comment.