akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.05k stars 808 forks source link

Segmentation fault on a call to json_loads inside a function during the 2nd call to the function #619

Closed french7181 closed 2 years ago

french7181 commented 2 years ago

Hello,

I am cross-compiling jansson to a ARM cortex-M3 processor and have managed to implement it successfully up now. The configuration command used looks as follows:

$ ./configure --host=arm-linux --disable-shared --enable-static --prefix=/home/Dev/jansson/ CC=arm-uclinuxeabi-gcc CXX=arm-uclinuxeabi-c++ CPP=arm-uclinuxeabi-cpp LDFLAGS=-L/home/Dev/jansson/../..//A2F/root/usr/lib -mthumb -mcpu=cortex-m3 -pthread CFLAGS=-I/home/Dev/jansson/../..//A2F/root/usr/include -Os -mthumb -mcpu=cortex-m3 LIBS=-lm

For historical reasons, I was using jansson 2.7 that I had successfully used for another project. I have turned to 2.14 for this new project, though both version of the library produce the same behavior.

For my project, I am parsing a JSON string (received from a socket) inside a dedicated function in order to fill a struct used later in my code. The structure is processed and a result JSON is generated back and sent over the socket. Then the code is ready to receive a new socket. Everything works fine during the reception of the first JSON string which gets parsed ok. However, when I receive the second JSON string from my socket, I call the parsing function which fails with a segmentation fault during the first call to json_loads. Sending back twice the same JSON string produces the same behavior.

Here is a snippet to the begining of my parsing function :

int parseRTNetJSONConf(char *buffer,RTNetCommand_t *Command,int verbose)
{
        json_t *root;
        json_error_t error;
    json_t *CMD, *Params, *ID, *Mode,*Len, *Data,*Reference, *Time;
        ...
    CMD = NULL;
    Params = NULL;
    ID = NULL;
    Mode = NULL;
    Len = NULL;
    Data = NULL;
    Reference = NULL;
    Time = NULL;

    Command->ref = 0;
    if (verbose >= VERBOSE_DEBUG_LEVEL)
        fprintf(stdout, "debug: parseRTNetJSONConf - calling json_loads\n");
    root = json_loads(buffer, 0, &error);
        Reference = json_object_get(root,"Ref");
        ....
        json_decref(Reference);
        json_decref(root);
    return result;
}

Function parseRTNetJSONConf gets called in my main in the socket processing loop.

if((result = parseRTNetJSONConf(buf,Command,verboseLevel)) == 0){ processCommand(Command,returnVal,verboseLevel); ....

After a bunch of verification, the segmentation fault is confirmed to happen during the second call to the parseRTNetJSONConf while calling the json_loads function creating the root json_t.

Any idea of what might be causing this issue ?

Mephistophiles commented 2 years ago
root = json_loads(buffer, 0, &error);
    Reference = json_object_get(root,"Ref");
    ....
    json_decref(Reference);
    json_decref(root);

you should not decref the variable Reference (https://jansson.readthedocs.io/en/latest/apiref.html#c.json_object_get) - it borrowed reference

P.S. please, use code block for code snippets

french7181 commented 2 years ago

Thanks for the quick answer, it solved it, I did not get the subtility of the borrowed reference at first and my previous implementations of the library did only make a single pass usage of the json_loads.

PS: I corrected the extent of the code block (it only create a single quoted block the first time I created, but now it generated a triple quoted one).

Thanks again.