Files

124 KiB
Raw Permalink Blame History

Symptom index

One line per symptom in the subsystem references: what you see (an assertion, a [RED] line, an abort or crash site, a visible result) and the entry that explains it. Search this page for the text in your log first (grep -i the function name, the [RED] text or the address form), then read the entry and the game notes it names. Generated by dm/tools/docs_symptoms.py from the entries' Symptom bullets: change the entry, then run it.

Packing

Rewriter

Memory and address space

  • large resources silently skipped, later a null deref where the resource is used; also visible as SetHeapSize asking for much less than the pool. → Partitioning the guest block between alias region, stacks and heap
  • SetHeapSize OOM: req 0x600000 > cap 0, followed by an SDK abort in nninitStartup on the first provisional boot. → Provisional Unreal layout leaves no heap
  • nnMain returns right after nv::InitializeGraphics, with no error (Hyrule Warriors: Age of Calamity); [mem] SetHeapSize … + modules … > app pool (Monster Hunter Rise), [mem] SetHeapSize … + modules 0x5c00000 > app pool (Catherine: Full Body); SetHeapSize asks for almost the whole application pool and fails at boot (Metroid Dread: 0xc9400000, larger than the heap region); the memory pool for the game's 96 MB GPU heap has no storage (MemoryPoolInitialize red line), then a null read at main+0x2eb954 (Catherine: Full Body); heap allocations fail late in a busy scene. → Heap sized from the application pool less used memory
  • SetHeapSize OOM: req 0x120000000 > cap 0xd0000000, then Break#1 reason=0 in nninitStartup, with a backtrace through nn::os::SetMemoryHeapSize (sdk+0x967a4). → A heap request beyond the heap region returns ResultOutOfMemory
  • StandardAllocator::Initialize aborts in nninitStartup (Fire Emblem Engage); nn::diag abort in StandardAllocator::Initialize(void *, size_t, bool) from nninitStartup (sdk+0x2f98e4 ← main+0x5b69e0, Big Brain Academy: Brain vs. Brain). → Virtual address memory follows the NPDM's system resource
  • the first AllocateAddressRegion fails with 0x1803; StandardAllocator::Initialize aborts in nninitStartup (an nn::diag abort; the NSP script's heap check reports "the host stopped before nnMain"); the alias region fills in minutes; regions a game reserves later fail (Size-aligned regions exhaust the alias address space, The movie player's own StandardAllocator). → The SDK's address-region node area
  • a null-based write minutes into play, at the pool size minus 0x20 (Engage: a write to NULL + 0x1fffe0, addr=0x1fffe0 at main+0x9a4664); NULL index pointers written on several job threads at once (main+0xdb0ad4, 0xdaea58, 0xdadb5c), with 32-bit mesh indices turning up inside texture objects. → Size-aligned regions exhaust the alias address space
  • a cut engine region still does not fit; two large regions lose up to 1 GB each to alignment, depending on where mmap put the guest block (Absolum); the region comes 0.69 GB past the 1 GB node area, at the next 1 GB boundary (Paper Mario: The Thousand-Year Door). → 1 GB alignment of regions of 1 GB and more
  • a write at NULL + 0x3fffe0 (a 4 MB pool − 0x20) at main+0x48b770, about six minutes into the prologue, with Unity's ALLOC_CACHEOBJECTS_THREAD allocator in x19; the [mem] high-water mark at +4.26 GB of the 4.375 GB alias region while 1.26 GB is mapped (Sea of Stars). → Size-class alignment doubles Unity's regions
  • nothing aborts at startup as with Unity 2022.3, but the provisional profile gave a 1 GB block and a 256 MB alias region while Unity maps 1.5 GB in the first room. → Unity 6 takes its memory with no StandardAllocator and no heap
  • nn::diag abort from StandardAllocator::Initialize long after nninitStartup, right after the first Vulkan query pool (sdk+0x12dad0 ← main+0x62c52c). → The movie player's own StandardAllocator
  • StandardAllocator::Initialize aborts in nninitStartup (Pokémon Legends: Z-A: main+0x1b2e690); nn::diag abort at sdk+0x11ff34 (StandardAllocator::Initialize) in nninitStartup, SDK 15.3.2, called from main+0x31370c (Paper Mario: The Thousand-Year Door). → StandardAllocators over 12 to 62 GB of address space
  • a write to 0x20000ffff in static initialization (main+0x164990), after AllocateAddressRegion returns 0x1803; reducing the request to 3 GB still returns 0x1803 with the SDK's original large-region alignment. With only the outer ranges reduced, a later free crashes at main+0x1668dc after reading compressed file data as a slab-owner pointer. → Separate virtual ranges in Snowdrop's page allocator
  • nn::diag abort at sdk+0x12dad0 in nninitStartup, called from main+0x756310. → .NET NativeAOT malloc and the GC region range
  • the game aborts in its static initialisers, before nnMain, when its own 62 GB address region fails (main+0x37c9bd0, AllocateAddressRegion(&p, 0xf80000000) at main+0x37c9a5c). → A 62 GB page allocator behind nu::VirtualAllocHook
  • the game calls exit(1) in nninitStartup (Octopath Traveler 0: main+0x12e74); nn::diag::Abort from main+0x352fbec (Unreal's fatal error) after the first commit, AllocateMemoryPages(0, 2 MB) while the RHI starts (main+0x353ff8c, result 0xe03) (Pikmin 4); a crash in NumberLineAllocator::Compaction at boot (DRAGON QUEST XI S, region option 4224). → Unreal's engine address region and its options
  • a null read in the out-of-memory report at main+0x1005824 when the engine region is smaller than the allocator's pools (Octopath Traveler 0). → Unreal's FMallocBinned3 replaced by the host allocator
  • an abort right at nnMain, under nn::os::CreateThread → ThreadManagerImplByHorizon::MapAliasStack → StackGuardManager::MapAtRandomAddress; with the log line, [RED] MapMemory refused (0xd401): <stack region> <- <address outside the guest block>. → Thread stacks from the host's Unreal heap
  • nn::diag abort from main+0x11bc, no message, in the first battle, with about 1 GB mapped (FINAL FANTASY RESONANCE with DRAGON QUEST VII Reimagined's 2 GB region). → Unreal 5.6's page allocator never gives address space back
  • write to 0x268 right after the title screen (main+0x5d6708, a constructor whose this is 0x200). → Ring heaps cut from a pool at 64 KB alignment
  • C++ exception aborts in nn::ro::detail::GetExceptionInfo. → svcQueryMemory must report each module's real layout
  • MapPhysicalMemory faults on part of a page. → MapPhysicalMemory in 16 KB host pages
  • the alias region's mapped total runs past the application pool in the first minute. → Maps past the application pool fail as on Horizon
  • a write through a null pointer at +0x1c0 during startup. → GetInfo(UserExceptionContextAddress) returns a real buffer
  • a null-pool buffer even with virtual pools working (Virtual memory pools mapped onto one physical pool). → A null-pool buffer from a game heap that ran out
  • a model load exhausts its resource heap: a null operator new at the world load, or BufferInitialize: pool has no storage followed by a null-pool crash. → Model heaps sized by the host's command record sizes
  • the frames stop at the first loading screen, a graphics worker at 100% CPU (17 s in, UnityGfxDeviceWorker running, the main thread waiting on a condition variable, no red line). → Unity's GPU pool block allocation spins at size 0
  • SIGBUS inside a host hook (snprintf under mount_ex / h_fs_MountSave), then the process hangs (Super Mario 3D World + Bowser's Fury); SIGBUS inside Metal (AGCDeserializedReply, an AGX compiler block) at an address in the guest stack region (Breath of the Wild). → Host calls on small guest stacks
  • the iPhone app is killed for memory; resident memory grows steadily (about 0.2 MB a frame) while the residency set and the texture counts stay flat. → Deferred-release drain without an autorelease pool
  • travelling produces a brief multi-GB footprint spike, then memory returns to its earlier level; periodic memory lines can miss the peak. Upload diagnostics show many swapped-out blocks still alive in one batch. → Upload staging grows within one rendering submission
  • GPU memory grows with repeated nvnTextureReadTexels calls on a long-lived game thread, even after each readback completes. → GPU readback without an autorelease pool

Threads

  • a parent returns from StartThread before a newly runnable higher-priority child pinned to its core finishes its work (deterministic regression, not attributed to a game failure). → Starting a higher-priority thread on the caller's core
  • per-core job queues never drained. → Core mask changes move the ideal core into the new mask
  • crash indexing a per-core table with a huge offset (index −2). → Ideal core −2 resolves to the process default core
  • the main thread waits forever on an event right after nnMain starts, with only three or four threads created; DM_THR=1 shows no CreateThread for the thread it waits on. → Free thread count (svcGetInfo type 24)
  • in garbage-collected titles (Unity / IL2CPP), live objects freed, with their finalizers releasing native resources. → Pausing threads and reading their context for garbage collectors
  • crashes around movie changes in the game's own player threads, about one run in two: SignalEvent → MultiWaitImpl::NotifyAndWakeupThread on a null MultiWait at address 0x20; WaitAny walking freed holders; a worker reading a freed object at main+0x225338. The other way round, a handoff that waits too widely: a black screen at boot that never loads a texture (packaged textures: first uploads 0), or a load that never ends behind an animated loading screen, with the thread dump's same-core handoffs N, total T ms larger than the run itself. → Same-core wake handoffs
  • the game freezes when a movie starts playing beside the game (a guide movie in a corner of the screen): the last frame stays, the process idles at a few percent of a core, and the thread dump shows a lower-priority job thread running/not waiting with its backtrace in the movie player (ReleaseOutputBufferIndex), the main thread waiting for it, and the movie's input thread running/not waiting too. A sample of the process shows the job thread in md_pump → md_event → dm_yield_to_core_peers, and the input thread in h_movie_SendIn → md_pump waiting for a pthread mutex. → A host lock held across a same-core handoff
  • several threads crash at once and the dumps interleave, then the process hangs instead of exiting. → Simultaneous crashes of several threads
  • none seen; found while investigating Fire Emblem Engage's demo crash, which it did not change (that was the address-space shortage, Size-aligned regions exhaust the alias address space). → SignalToAddress type 2 with count ≤ 0
  • a 64-bit wait could return at once or block when it should not (not met in a game). → WaitForAddress type 3: 64-bit wait if equal
  • a PhysX worker crashes in a task's removeReference with a null task manager, right as the game switches to 30 fps (pc=main+0x10ccf28, lr=main+0x13c236c); on the iPhone and in 2 of 5 Mac runs, in every Mac run with 12 busy loops loading the CPU. → Late PhysX task destructor after the unlock
  • a 30 Hz game thread runs at 27 Hz, and whatever it paces comes out slow (cutscenes at 36 ms per frame instead of 33.3; gameplay was fine at 60). → Timer slack in guest sleeps (sleep_precise)
  • a guest thread keeps a core at 100% with billions of SleepThread calls. → Sleeps under 20 µs take the yield path
  • a loading screen sits for a minute with the CPU nearly idle; one thread yields thousands of times a second, every yield a back-off sleep (the power line's top yielder, with as many back-off sleeps). → Yields that make progress return at once (thr_yield)
  • a host helper thread aborts when signalling a destroyed SystemEvent; repeated vi::GetDisplayVsyncEvent calls double the event's tick rate. Rapid replacement can abort with too many vsync events, or a retired vsync worker can signal another service's event at reused storage. → Service-event producers follow the binding lifetime
  • the main thread waits forever on a job's done event at boot while every worker sleeps, two of them on one event (main+0x1426c waiting on Job::m_doneEvent); 4 of 6 Mac runs. → One auto-clear event shared by a pool's workers
  • abort in os::WaitSystemEvent under oe::PopNotificationMessage (The Legend of Zelda: Link's Awakening); one guest thread at about 1000 ms/s on the iPhone only, the phone hot, CPU energy 5–7 W (Monster Hunter Rise's MessageSuperviseThread, priority 32, in the [nvn] threads lines). → The oe notification event and its queue
  • Paper Mario: The Thousand-Year Door 1.0.1 stays black before its first frame. The main thread stops at main+0x32796c, after starting SYS_Notification; the priority-28 notifier is in oe::PopNotificationMessage, while the priority-44 main thread waits for its same-core wake handoff. → Native HLE waits release the guest core

Services and SDK calls

Movies

Audio

Frame rate

NVN objects

Rendering

Shaders

Game state