switchbrew / libnx

Library for Switch Homebrew
https://switchbrew.github.io/libnx/
ISC License
1.27k stars 174 forks source link

Graphics crashes on firmware 1.0 #77

Closed ghost closed 6 years ago

ghost commented 6 years ago

It seems libnx has some issues with graphics on firmware 1.0. Many programs such as nx-hbmenu and FTPd seem to crash with 2345-0021. If I've read the libnx error list correctly, this is "LibnxError_BadGfxDequeueBuffer".

To reproduce this, simply run nx-hbmenu as normal on firmware 1.0, then wait for it (or any applications you launch from it) to crash; this often occurs immediately on launch, but can take a few seconds to a few minutes on occasion.

Thank you.

plutooo commented 6 years ago

can you narrow down what error resulted in this panic?

ghost commented 6 years ago

I am not certain; for nx-hbmenu, the issue was introduced with the UI update; it seems that anything with "complex" graphics is more liable to cause this crash. Also potentially notable is, if you manage to launch an NRO from nx-hbmenu before it crashes, the application itself will eventually crash with the same 2345-0021 error that the hbmenu itself usually does, whereas it would not have crashed if loaded directly.

yellows8 commented 6 years ago

Are you able to modify libnx gfx.c to determine the error trigger? "loaded directly" ?

ghost commented 6 years ago

I've not been successful at pinpointing the exact problem, but upon further testing I noticed that the 1.0 version of nx-hbmenu is not subject to these crashes. As for "loaded directly", I meant loading an NSP directly with nspwn.

yellows8 commented 6 years ago

"Are you able to modify libnx gfx.c to determine the error trigger?"

(Just write to a file with stdio)

ghost commented 6 years ago

Sorry for the slow replies. It seems Swiftloke beat me to doing this; here's a log of the #switchdev conversation for posterity:


<Swiftloke> I've done a little bit of digging with my 1.0.0 Switch, and managed to backtrace to the BadGfxDequeueError and where it occurs.
<Swiftloke> The error is LibnxNvidiaError_InsufficientMemory.
<yellows8> what returns that?
<Swiftloke> The error originally sprouts up here:
<Swiftloke> https://github.com/switchbrew/libnx/blob/1e04b22bae5eb3fd89783b6bd5b3cbf1c08a9365/nx/source/gfx/nvgfx.c#L426
<Swiftloke> Then it's carried down here:
<Swiftloke> https://github.com/switchbrew/libnx/blob/3a8a9d7c2695294845464a1eea68800005425e7a/nx/source/gfx/gfx.c#L142
<Swiftloke> Then to here:
<Swiftloke> https://github.com/switchbrew/libnx/blob/3a8a9d7c2695294845464a1eea68800005425e7a/nx/source/gfx/gfx.c#L517
<yellows8> ok :/
yellows8 commented 6 years ago

Try with: 726f8adfe3f3b4970b9d384d85838d644e736676

Swiftloke commented 6 years ago

Several tests with this commit yield success- hbmenu 2.0 no longer crashes on startup. I'll be trying more various homebrew and reporting back.

ghost commented 6 years ago

Yeah, likewise here. As I mentioned in #switchdev, seems the issue is resolved, at least with nx-hbmenu.

Swiftloke commented 6 years ago

Posting this for historical reasons. As an update to my earlier debugging, it turns out that the error was due to improper handling of the LibnxNvidiaError_Timeout error, and not something running out of memory, see below:

Swiftloke 15:37:19
Well, it works on 1.0.0. It was a failure to handle the timeout error correctly, then?
@yellows8 15:38:23
yeah
Swiftloke 15:38:41
So why did it end up throwing InsufficientMemory then...?
Huh.
@yellows8 15:39:15
was it *really* InsufficientMemory?
Swiftloke 15:39:47
OK...
So... The error actually shown in fatal was off by one in the corresponding result.h error. I figured this out about halfway through debugging, after I had decided what the error was.
So it was Timeout.
jarulo commented 6 years ago

I am using the suggested commit fix at https://github.com/switchbrew/libnx/commit/726f8adfe3f3b4970b9d384d85838d644e736676 but I still get a libnx crash with the same error.

More specifically, nvgfxEventWait is returning 0xF5C, which is LibnxNvidiaError_InsufficientMemory if I am reading this correctly. Any ideas how this can happen?

(FWIW, also only seems to happen on 1.0.0)

yellows8 commented 6 years ago

Can you try with libnx 1.2.1?

jarulo commented 6 years ago

Still same error on libnx 1.2.1.

I fixed it by adding this:

Result nvgfxEventWait(u32 syncpt_id, u32 threshold, s32 timeout) {
    Result rc=0;
    Result timeout_rc = MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout);
    Result insufficientmemory_rc = MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_InsufficientMemory);

    if (R_SUCCEEDED(rc)) {
        do {
            rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, syncpt_id, threshold, timeout, 0, &g_nvgfx_nvhostctrl_eventres);
        } while(rc==timeout_rc || rc == insufficientmemory_rc);
    } 

The insufficient memory error does not seem to be fatal as just retrying seems to make it go away.

yellows8 commented 6 years ago

What code did you use to obtain that 0xF5C error, and are you sure it's correct?

jarulo commented 6 years ago

I used UART to print the errorcodes that are not timeout_rc and not 0. Only the 0xF5C error popped up once in a while. It happens very rarely and only very early on application start, but if it happened, it was fatal.

Cpasjuste commented 6 years ago

Hi,

My latest version of pfba does have the same error randomly (after loading multiple times a rom). I guess it could be a problem on my side. I'm using latest libnx sources, and i'm on 5.1 since a few days. Not sure what causing the problem (libnx, some pfba changes, the 5.1 update..). I'm going to take a closer look to see where it really crash.

Cpasjuste commented 6 years ago

Hi, For information, i fixed my crash with this commit : https://github.com/Cpasjuste/libcross2dui/commit/b34792198c574d8df30bfa9cde94dd3ec4d68736#diff-c9a7f53fde38976bb82d1b09304cc1b5