Skip to content
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

JSON Parsing Freeze Issue on Nintendo Switch #4066

Closed
octokling opened this issue Jun 29, 2023 · 7 comments
Closed

JSON Parsing Freeze Issue on Nintendo Switch #4066

octokling opened this issue Jun 29, 2023 · 7 comments

Comments

@octokling
Copy link

octokling commented Jun 29, 2023

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
Copy link
Owner

Can you check in the debugger where the code freezes?

@octokling
Copy link
Author

octokling commented Jun 29, 2023

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
Copy link
Author

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
Copy link
Owner

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

@octokling
Copy link
Author

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
Copy link
Author

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
Copy link
Author

octokling commented Jun 30, 2023

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

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

No branches or pull requests

2 participants