New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refcount doesn't work between threads #212

Closed
EmielBruijntjes opened this Issue Dec 1, 2015 · 1 comment

Comments

Projects
None yet
2 participants
@EmielBruijntjes
Contributor

EmielBruijntjes commented Dec 1, 2015

As posing a pull request to solve it doesn't seem to work, i'll stick with a bug report instead:

/**
 *  JsonBug.cpp
 * 
 *  Example program that makes the JSON-C library crash because it does
 *  not do atomic refcounts.
 * 
 *  Compile with "g++ -std=c++11 jsonbug.cpp -ljson-c -lpthread"
 * 
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  @copyright 2015 Copernica BV
 */

/**
 *  Dependencies
 */
#include <json-c/json.h>
#include <thread>

/**
 *  Function that runs in a thread
 *  @param  object
 */
void threadfunction(json_object *object)
{
    // we are going to make a lot of copies of the object
    for (size_t i = 0; i < 1000; ++i)
    {
        // make a new reference to the original object
        auto *copy = json_object_get(object);

        // and get rid of the reference again
        json_object_put(copy);
    }

    // we no longer need the original object either
    json_object_put(object);
}

/**
 *  Main procedure
 *  @return int
 */
int main()
{
    // Just run the test a crazy amount of times - until one fails
    for (size_t i = 0; true; ++i)
    {
        // create a json object
        auto *obj = json_object_new_object();

        // start a thread with a new reference to the original json object
        std::thread t(std::bind(&threadfunction, json_object_get(obj)));

        // we no longer need the original object, the thread uses its own copy
        json_object_put(obj);

        // wait for the thread to be ready
        t.join();
    }

    // done
    return 0;
}

After a while it crashes with this error:

*** Error in `./a.out': double free or corruption (top): 0x00000000016f1aa0 ***
Aborted (core dumped)
@hawicz

This comment has been minimized.

Show comment
Hide comment
@hawicz

hawicz Sep 5, 2017

Member

I pulled over your changes from PR#211, adjusted how they get compiled in, and conditionalized them on a --enable-threading configure option (since switching from a simple increment/decrement to the _sync* functions will have a performance impact).
I've confirmed that your test crashes without the changes, but continues to run with them, so I'm calling this issue done.

Member

hawicz commented Sep 5, 2017

I pulled over your changes from PR#211, adjusted how they get compiled in, and conditionalized them on a --enable-threading configure option (since switching from a simple increment/decrement to the _sync* functions will have a performance impact).
I've confirmed that your test crashes without the changes, but continues to run with them, so I'm calling this issue done.

@hawicz hawicz closed this Sep 5, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment