anhero / JsonBox

This is a JSON C++ library. It can write and read JSON files with ease and speed.
MIT License
115 stars 60 forks source link

Value::operator<< overload is not thread-safe #43

Open camerongivler opened 7 years ago

camerongivler commented 7 years ago

Running the following code produces a segfault:

#include "JsonBox.h"
#include <ctime>
#include <sstream>
#include <chrono>
#include <thread>
#include <future>

int main()
{
    std::srand(std::time(0));
    int numThings = 50;

    std::promise<void> p;
    std::shared_future<void> f = p.get_future().share();

    for(int i = 0; i < numThings; i++) {
        std::thread t([f](){
                JsonBox::Value val;
                val[std::to_string(std::rand())] = std::rand();
                f.get();

                // This code segfaults
                std::cout << val << std::endl;

                // This code is fine
                /*
                std::ostringstream os;
                val.writeToStream(os);
                std::string print = os.str();
                std::cout << print << std::endl;
                */
            });
        t.detach();
    }
    std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
    p.set_value();
    std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
}

The Values that are printed out are all created in different threads/scopes. It seems as though the overload itself is what is causing the segfault. My guess is it has to do with Value.cpp lines https://github.com/anhero/JsonBox/blob/a6d8255e1ee33281e6ca317b122d9ac5af135a65/src/Value.cpp#L1247 and https://github.com/anhero/JsonBox/blob/a6d8255e1ee33281e6ca317b122d9ac5af135a65/src/Value.cpp#L1259 This turns out to be very annoying when debugging code from multiple threads.