nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
42.4k stars 6.67k forks source link

JSON Parsing Freeze Issue on Nintendo Switch #4066

Closed octokling closed 1 year ago

octokling commented 1 year ago

Description

When i attempting to parse a const char* to JSON with this code "json jsonData = json::parse();", my code freezes and becomes unresponsive.

Reproduction steps

My code :

test.cpp

void Test::test()
{ 
    sead::ScopedCurrentHeapSetter heapSetter(mHeap);
    using json = nlohmann::json;

    json data;

    try {
        Logger::log("TEST 1\n");
        const char* charData = "JSON..."; // JSON in this link: https://willbosstwitchbot.glitch.me/devSMO
        Logger::log("TEST 2\n");
        json jsonData = json::parse(charData);
        Logger::log("TEST 3\n");
    } catch (const json::parse_error& e) {
        Logger::log("JSON parsing error: %s\n", e.what());
        return;
    }
    return;
}

main.cpp :


HOOK_DEFINE_TRAMPOLINE(GameSystemInit) {
    static void Callback(GameSystem *thisPtr) {
    [...]
    sead::Heap* testHeap = sead::ExpHeap::create(50000, "TestHeap", nullptr, 8,
            sead::Heap::HeapDirection::cHeapDirection_Forward, false);

        Test::createInstance(testHeap);
        Test::instance()->init(testHeap);
        Test::instance()->test();

        Orig(thisPtr);
    }
};

Expected vs. actual results

The JSON data I'm trying to parse is 4831 bytes in size.

However, when I use a much smaller JSON file, such as the one in this link: https://willbosstwitchbot.glitch.me/twitch?user=Will_Boss_Gamer, which is only 600 bytes in size, there is no problem and the parsing works correctly.

Error messages

No error is reported. However, I have concluded that this line "json jsonData = json::parse(charData);" freezes my code, because i noticed that "TEST 3" is not sent thanks to the TCP Logger (Logger::log)

My logs:

Waiting for Switch to Connect...
Switch Connected! IP: 192.168.1.44 Port: 37774
Connected!
TEST 1
TEST 2

Compiler and operating system

gcc version 10.2.1 20210110 (Debian 10.2.1-6)

Library version

json.h version 3.7.3

nlohmann commented 1 year ago

Can you check in the debugger where the code freezes?

octokling commented 1 year ago

Debugging on the Nintendo Switch is a bit complicated. Personally, I use Logger::log() statement manually to debug.

Can you tell me where in the json.h file I need to debug to help you know what my problem is?

octokling commented 1 year ago

By the way, I have two doubts. Either the json.h file is problematic, or my heap is not large enough for parse, which could also cause a freeze no?

nlohmann commented 1 year ago

From all tests and experiences I think it's not the library...

octokling commented 1 year ago

After reflection, I think I made a mistake in my code. 🤔🤔🤔

Because when I assign some bytes to my dataStream for example more than 20000 bytes it freezes

octokling commented 1 year ago

In the file json.h,

I added a lot of Logger::log() statements to see where it might be blocking.

It appears that the code is blocked at this void: parser(i, cb, allow_exceptions).parse(true, result);

which, in turn, is blocked by sax_parse_internal(&sdp);

And with sax_parse_internal(&sdp), i got this output :

Called sax_parse_internal
starting while
while if not skip_to_state_evaluation
case token_type::begin_object:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_unsigned:
while if not skip_to_state_evaluation
case token_type::begin_object:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_unsigned:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
while if not skip_to_state_evaluation
case token_type::value_string:
octokling commented 1 year ago

Ok i know why my switch freeze.

The CPU Usage of the Core #1 is at 100%

So maybe the while(true){} of the sax_parse_internal will never finish