Redis Modules: Ctx becomes inaccessible upon exiting Callback Function

42 views
Skip to first unread message

Dhruv Umesh

unread,
Aug 6, 2022, 10:42:34 AM8/6/22
to Redis DB
Hello all,

I am currently writing a module that will first set 10 keys in the database, and then iterate through the keys using RedisModule_Scan, printing the key value pairs where the value is greater than 10. However, during testing, I keep getting a segmentation fault in line 3672 in moduleInitKey(): kp->db = ctx->client->db; . Using gdb, I've determined that this happens because the ctx object becomes inaccessible after exiting the callback function. I have attached my code below. Any help/advice on this matter is appreciated.

Thanks in advance,
Dhruv.

#include "../../redis/src/redismodule.h"
#include <stdlib.h>

void redisModuleScanCallback(RedisModuleCtx *ctx, RedisModuleString *keyname,
                   RedisModuleKey *key, void *privdata) {

        size_t len = 0;
        //double *threshold = (double *) privdata;
        RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Pre key read");
        const char *val = RedisModule_StringDMA(key, &len, REDISMODULE_READ);
        //RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Val: %s", val);
        double *d;

        sscanf(val, "%lf", d);
        if(*d >= 10.0){ //I'm not using the threshold variable for now
                RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Hit -> %s", val);
        } else {
                RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Miss");
        }
        return;
}

void populateDB(RedisModuleCtx *ctx){

        for(int i = 0; i < 10; i++){
                const char k = 65 + i;
                size_t len;
                int v = i+5;
                RedisModuleString *val = RedisModule_CreateStringPrintf(ctx, "%d", v);
                RedisModuleString *keyname = RedisModule_CreateStringPrintf(ctx, "%c", k);
                RedisModuleKey *key = RedisModule_OpenKey(ctx, keyname, REDISMODULE_WRITE);
                int status = RedisModule_StringSet(key, val);
                if (status == REDISMODULE_ERR)
                        RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Error setting");
        }
        return;
}

int getKeyValuePairs(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
        if(argc != 2)
                return RedisModule_WrongArity(ctx);
        RedisModule_AutoMemory(ctx);
        populateDB(ctx);

        double threshold = 0;
        if(RedisModule_StringToDouble(argv[1], &threshold) == REDISMODULE_ERR)
                return REDISMODULE_ERR;

        int num_keys = (int) RedisModule_DbSize(ctx), key_count = 0;
        RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "Num keys: %d", num_keys);
        RedisModuleScanCursor *cursor = RedisModule_ScanCursorCreate();
        while(RedisModule_Scan(ctx, cursor, redisModuleScanCallback, NULL));
        RedisModule_ScanCursorDestroy(cursor);

        return REDISMODULE_OK;
}



int RedisModule_OnLoad(RedisModuleCtx *ctx) {
        if (RedisModule_Init(ctx, "keyQueries", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) {
                return REDISMODULE_ERR;
        }
        if (RedisModule_CreateCommand(ctx, "GETVALUESGEQ", getKeyValuePairs,
                "write", 1,1,1) == REDISMODULE_ERR) {
                return REDISMODULE_ERR;
        }
}


Dhruv Umesh

unread,
Aug 7, 2022, 9:35:06 AM8/7/22
to Redis DB
Update: I've solved my problem. I'm not sure why but sscanf was the issue. 
Reply all
Reply to author
Forward
0 new messages