melonDS-emu / melonDS

DS emulator, sorta
https://melonds.kuribo64.net
GNU General Public License v3.0
3.18k stars 527 forks source link

Exception in NDS constructor from SigsegvHandler #1964

Closed benhall-7 closed 7 months ago

benhall-7 commented 8 months ago

Hi! I wrote a frontend for the melonDS core as a project of mine, and now that the codebase has gone through a revamp to become more object-oriented, I wanted to update my project to be compatible with those changes. However, I'm running into an exception when calling the constructor of the NDS itself. I'm using Mac, and JIT_ENABLED is OFF. I have a very basic wrapper to return an NDS (I've tried these two versions of the code):

std::unique_ptr<NDS> New_NDS()
{
    return std::make_unique<NDS>();
}

and then I tried:

std::unique_ptr<NDS> New_NDS()
{
    NDS::Current = nullptr;
    auto nds = std::make_unique<NDS>();
    nds->Reset();
    NDS::Current = nds.get();
    return nds;
}

But when running this, there's always some kind of silent exception, which I've isolated to this line of code (melonDS/src/ARMJIT_Memory.cpp, line ~197):

u8* curArea = (u8*)(NDS::Current->CurCPU == 0 ? NDS::Current->JIT.Memory.FastMem9Start : NDS::Current->JIT.Memory.FastMem7Start);

The issue is happening for me because the NDS constructor has an ARMJIT member regardless of the JIT_ENABLED env variable, and that contains an ARMJIT_MEMORY field. Then, the Memory field constructor has this block of code:

    struct sigaction sa;
    sa.sa_handler = nullptr;
    sa.sa_sigaction = &SigsegvHandler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, &OldSaSegv);
#ifdef __APPLE__
    sigaction(SIGBUS, &sa, &OldSaBus);

which calls the SigsegvHandler. The issue is a null dereference error, the SigsegvHandler is running NDS::Current->CurCPU before the NDS has even finished initializing. Maybe if I keep looking I'll find the thing I'm missing, but for now I'm a little stumped. Any help is appreciated! My project is here if it matters: https://github.com/benhall-7/melon-rs

RSDuck commented 7 months ago

that is weird. The code you are refering to shouldn't be even compiled when the JIT is disabled as it's guarded by the #ifdef: https://github.com/melonDS-emu/melonDS/blob/a8429af13150dcdb81fbb9aeb1b66b7c5ece582d/src/ARMJIT_Memory.h#L182-L227

benhall-7 commented 7 months ago

@RSDuck Thanks! That helped actually. I realized I was trying to disable the JIT_ENABLED flag in the compilation process, whereas it looks like I was actually supposed to disable the ENABLE_JIT flag shown in src/CMakeLists.txt. I'm still not sure how it was supposed to succeed in the first place given what looks to be cyclical logic between the constructor of NDS and the NDS::Current variable, but I was able to get past this problem