How to get the double free error on run time in my c++ code

374 Views Asked by At

I am using the Jansson library in my c++ code. In the library when any Jansson variable is created, the variable should be freed to release the reference and I am using the 'json_decref(json_t *json)' method to release. But sometimes it causes the double free problem and I didn't get the problem in runtime. Maybe it is not normal but I want to get a runtime error when I try to release some references. For example, I am running the following test code,

json_t *root = json_loads(any_json_message, 0, &error);
json_decref(root);
json_decref(root);

As you see there is a problem and I don't get any runtime error like double free.

Also, I am using CMake to compile my source code. Maybe any cmake flag fixes my question.

Any idea ?

2

There are 2 best solutions below

0
On

The behaviour of accessing the pointed object is undefined once it has been freed. The documentation doesn't spell it out, but calling json_decref more than once (plus the times you've called json_incref on the pointer) also has undefined behaviour.

Maybe it is not normal but I want to get a runtime error when I try to release some references.

Well, Jansson doesn't give that for you.

Your compiler might provide a run time analyser that might be able to detect some undefined behaviour and terminate the program with a message. See the manual of your compiler for how to use the analyser.

1
On

The documentation says that json_t contains a reference count. I guess that the first call to json_decref decreases the reference count from 1 to 0 and frees the memory. The second call to json_decref sees that the reference count is 0, and does nothing.

To generate the double-free error, you should copy the old contents of the json_t object. Something like this (but not literally; see below):

json_t *root = json_loads(any_json_message, 0, &error);
json_t copy = *root;
json_decref(root);
json_decref(&copy);

However, json_t is (I guess) an opaque type, that is, users can only create pointers to it, and not objects. To force creating a copy of an object, you can guess the size of the json_t object, and use memcpy:

json_t *root = json_loads(any_json_message, 0, &error);
char copy[42];
memcpy(copy, root, sizeof copy);
json_decref(root);
json_decref((json_t *)copy);

Try with various sizes (instead of 42) until it works. However, I am not sure you can make it work - it's just a guess on how the internals of this library work.