2

I've made a simple TCP Server using Boost Asio (1.53.0). The Server accepts JSON-Requests, parse them with boost::property_tree::read_json.

To test the reliability, I created a simple Application which creates 128 Threads and they send continually Requests.

After a few seconds, the server crashes with an Access Violation:

Unhandled exception at 0x000007FEFD829E5D (KernelBase.dll) in RPC_Server.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

msvcr110d.dll!__RethrowException(EHExceptionRecord * pThisException) Line 1217
msvcr110d.dll!__CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept) Line 1279
ntdll.dll!0000000077360c21()
RPC_Server.exe!json::json::Parse(std::basic_string<char,std::char_traits<char>,std::allocator<char> > & sJson) Line 28

Here get's read_json called:

rpc::request json::Parse(std::string sJson)
{
  try {
    std::stringstream ss;
    ss << sJson;
    boost::property_tree::ptree pt;
    boost::property_tree::read_json(ss, pt);
...
}
  • If I comment the read_json line out, the server handles everything correctly.
  • If I reduce the Test Application to e.g. just 1 Thread, the server handles and parses everything correctly.
RaphaelH
  • 2,144
  • 2
  • 30
  • 43
  • I notice you're taking `sJson` by reference. Where is the string itself stored? Might it be shared with (and modified by) other threads? – Mike Seymour Aug 19 '13 at 12:48
  • Also tried By-Value, it doesn't matter. – RaphaelH Aug 19 '13 at 12:55
  • As an experiment, reduce the number of threads to just one. If that happens to eliminate the access violation, then it means the problem is most likely due to a multi-threading issue. If that works, then increase the threads again, but put some critical sections or mutexes around the read_json code. – Bob Bryan Aug 19 '13 at 16:08
  • The example code shows the string param being passed as a copy, and all the other variables have been added on the stack. Threading is irrelevant. I have this crash too when read_json completes, if I pummel it alot. – G Huxley Nov 12 '14 at 23:03

1 Answers1

2

Seems like boost::property_tree::read_json isn't thread-safe by default.

You have to define:

#define BOOST_SPIRIT_THREADSAFE
RaphaelH
  • 2,144
  • 2
  • 30
  • 43
  • If this fixes the questioner's problem then it's only luck. The example code shows the string param being passed as a copy, and all the other variables have been added on the stack. Threading is irrelevant. I have this crash too when read_json completes, if I pummel it alot. Another example is http://stackoverflow.com/questions/18837401/c-boost-read-json-crash-and-i-had-define-boost-spirit-threadsafe – G Huxley Nov 12 '14 at 23:05
  • Ok, here's the answer to my problem: If you don't define this globally but have Spirit/json_parser used in multiple independent cpps, it'll still crash because annoyingly Sprit has a static variable that'll be shared amongst them all. That's a bit rubbish... BOOST_SPIRIT_THREADSAFE should be on by default. – G Huxley Nov 14 '14 at 04:41
  • Nice to hear you solved it. Yes it definitely should be on by default! – RaphaelH Nov 14 '14 at 10:43