natinusala / borealis

Hardware accelerated, controller and TV oriented UI library for PC and Nintendo Switch (libnx)
Apache License 2.0
260 stars 83 forks source link

Pushing view more than once results in undefined behavior #60

Closed masagrator closed 3 years ago

masagrator commented 3 years ago

As in title. I will provide info on two examples resulting in different behavior.

Example 1:

#include <stdio.h>
#include <stdlib.h>

#include <borealis.hpp>
#include <string>

int main(int argc, char* argv[])
{
    // Init the app
    brls::Logger::setLogLevel(brls::LogLevel::DEBUG);

    if (!brls::Application::init("Borealis example"))
    {
        brls::Logger::error("Unable to init Borealis application");
        return EXIT_FAILURE;
    }

        // Create a sample view
        brls::TabFrame* rootFrame = new brls::TabFrame();
    brls::AppletFrame* _appletFrame = new brls::AppletFrame(true, true);

    //Set title
        rootFrame->setTitle("Borealis Example App");
    _appletFrame->setTitle("Borealis Example App");

    //Create lists
        brls::List* testList = new brls::List();
    brls::List* testList2 = new brls::List();

    //Create listItem pushing view to AppletFrame
        brls::ListItem* HideTabItem = new brls::ListItem("Hide tab");
    HideTabItem->getClickEvent()->subscribe([_appletFrame](brls::View* view) {
            brls::Application::pushView(_appletFrame);
        });

    testList->addView(HideTabItem);

    rootFrame->addTab("Main", testList);

    //Create listItem pushing view to rootFrame

    brls::ListItem* ShowTabItem = new brls::ListItem("Show tab");
    ShowTabItem->getClickEvent()->subscribe([rootFrame](brls::View* view) {
            brls::Application::pushView(rootFrame);
        });

    testList2->addView(ShowTabItem);

    _appletFrame->setContentView(testList2);

        // Add the root view to the stack
        brls::Application::pushView(rootFrame);

        // Run the app
        while (brls::Application::mainLoop())
        ;

        // Exit
        return EXIT_SUCCESS;
}

By using clickEvent to push AppletFrame view then go back by pushing TabFrame view results in crash when trying to exit by using home menu and dedicated button. Provided example is returning 0x2A8 error. Crash report: 01601141633_010000000000100d.log

Example 2:

#include <stdio.h>
#include <stdlib.h>

#include <borealis.hpp>
#include <string>

int main(int argc, char* argv[])
{
    // Init the app
    brls::Logger::setLogLevel(brls::LogLevel::DEBUG);

    if (!brls::Application::init("Borealis example"))
    {
        brls::Logger::error("Unable to init Borealis application");
        return EXIT_FAILURE;
    }

        // Create a sample view
        brls::TabFrame* rootFrame = new brls::TabFrame();
    brls::AppletFrame* _appletFrame = new brls::AppletFrame(true, true);

    //Set title
        rootFrame->setTitle("Borealis Example App");
    _appletFrame->setTitle("Borealis Example App");

    //Create lists
        brls::List* testList = new brls::List();
    brls::List* testList2 = new brls::List();

    //Create listItem pushing view to AppletFrame
        brls::ListItem* HideTabItem = new brls::ListItem("Hide tab");
    HideTabItem->getClickEvent()->subscribe([_appletFrame](brls::View* view) {
            brls::Application::pushView(_appletFrame);
        });

    testList->addView(HideTabItem);

    rootFrame->addTab("Main", testList);

    //Create listItem pushing view to rootFrame

    brls::ListItem* ShowTabItem = new brls::ListItem("Show tab");
    ShowTabItem->getClickEvent()->subscribe([rootFrame](brls::View* view) {
            brls::Application::popView();
         });

    testList2->addView(ShowTabItem);

    _appletFrame->setContentView(testList2);

        // Add the root view to the stack
        brls::Application::pushView(rootFrame);

        // Run the app
        while (brls::Application::mainLoop())
        ;

         // Exit
         return EXIT_SUCCESS;
}

By using clickEvent to push AppletFrame view, go back by using popview and again push AppletFrame it will stuck and crash in few seconds. Provided example is returning 0x2A8 error. Crash report: 01601142026_010000000000100d.log

Earlier few times I also got 0x6A8 error with different code using similar methods, but I cannot replicate it now. Only what I have is crash report:

01600894264_010000000000100d.log

FW 10.1.0 Atmosphere 0.13.0 Using album and title replacement mode (in second case it just crash app, not whole system)

masagrator commented 3 years ago

So in Discord we have discussed that: Example 1: This is not allowed to do, never push the same view twice if it's not freed and made again before pushing.

Example 2: popview frees view that we were currently in, view was not created again and that's why it crashed.

Issues solved. Closing.