wiiu-env / libgui

7 stars 3 forks source link

MEM1_alloc crashing #15

Open V10lator opened 4 years ago

V10lator commented 4 years ago

I'm using MEM1_alloc for a I/O queue and libWHBs crash handler catched this while running overnight:

0x01049438    0x90830000    stw        r4,0(r3)
0x0104943c    0x2c0c0000    cmpwi      cr0,r12,0x0
0x01049440    0x9184000c    stw        r12,12(r4)
0x01049444    0x4182ffe8    b          2,12,0x104942c
0x01049448    0x908c0008    stw        r4,8(r12)
0x0104944c    0x7c832378    or         r3,r4,r4
0x01049450    0x4e800020    bclr       20,0
0x01049454    0x81830000    lwz        r12,0(r3)
0x01049458    0x38000000    addi       r0,r0,0

Address:      Back Chain    LR Save
0x1097e7bc:   0x1097e7ec    0x1ad1b540 <unknown>+0x0
0x1097e7ec:   0x1097e7fc    0x0104975c coreinit.rpl|CoreInitDefaultHeap+0x91c
0x1097e7fc:   0x1097e81c    0x0104a0e0 coreinit.rpl|MEMAllocFromExpHeapEx+0xe0
0x1097e81c:   0x1097e834    0x0d017d18 homebrew_launcher|MEM1_alloc+0x4c
0x1097e834:   0x1097e85c    0x0d00e12c homebrew_launcher|getFastestEntry+0x30
0x1097e85c:   0x1097e88c    0x0d00e70c homebrew_launcher|addToIOQueue+0x40
0x1097e88c:   0x1097e8ac    0x0d137a08 nlibcurl|curl_getdate+0x2344
0x1097e8ac:   0x1097e8fc    0x0d13b9cc nlibcurl|curl_share_strerror+0x10b4
0x1097e8fc:   0x1097e964    0x0d13bf60 nlibcurl|curl_share_strerror+0x1648
0x1097e964:   0x1097e994    0x0d13c804 nlibcurl|curl_share_strerror+0x1eec
0x1097e994:   0x1097e9c4    0x0d13d6a0 nlibcurl|curl_share_strerror+0x2d88
0x1097e9c4:   0x1097e9dc    0x0d13d920 nlibcurl|curl_share_strerror+0x3008
0x1097e9dc:   0x1097e9ec    0x0d122f80 nlibcurl|curl_easy_perform+0xa8
0x1097e9ec:   0x1097f2ec    0x0d0125d4 homebrew_launcher|downloadFile+0x4e8
0x1097f2ec:   0x10980674    0x0d013b64 homebrew_launcher|downloadTitle+0x10c8
0x10980674:   0x10980af4    0x0d00cb14 homebrew_launcher|downloadMenu+0x640

Note that it seemed to run fine for hours before crashing and the I/O queue is allocating and freeing a lot (codes here: https://pastebin.com/4yzvA9gz ).

V10lator commented 4 years ago

And a new one. Weird that it always seems to be caused by libCURL:

0x01049438    0x90830000    stw        r4,0(r3)
0x0104943c    0x2c0c0000    cmpwi      cr0,r12,0x0
0x01049440    0x9184000c    stw        r12,12(r4)
0x01049444    0x4182ffe8    b          2,12,0x104942c
0x01049448    0x908c0008    stw        r4,8(r12)
0x0104944c    0x7c832378    or         r3,r4,r4
0x01049450    0x4e800020    bclr       20,0
0x01049454    0x81830000    lwz        r12,0(r3)
0x01049458    0x38000000    addi       r0,r0,0

Address:      Back Chain    LR Save
0x1077f4d4:   0x1077f504    0x00000000
0x1077f504:   0x1077f514    0x0104975c coreinit.rpl|CoreInitDefaultHeap+0x91c
0x1077f514:   0x1077f534    0x0104a0e0 coreinit.rpl|MEMAllocFromExpHeapEx+0xe0
0x1077f534:   0x1077f54c    0x0d013b90 homebrew_launcher|MEM1_alloc+0x4c
0x1077f54c:   0x1077f57c    0x0d00bab0 homebrew_launcher|addToIOQueue+0x4c
0x1077f57c:   0x1077f59c    0x0d127208 nlibcurl|curl_getdate+0x2344
0x1077f59c:   0x1077f5ec    0x0d12b1cc nlibcurl|curl_share_strerror+0x10b4
0x1077f5ec:   0x1077f654    0x0d12b760 nlibcurl|curl_share_strerror+0x1648
0x1077f654:   0x1077f684    0x0d12c004 nlibcurl|curl_share_strerror+0x1eec
0x1077f684:   0x1077f6b4    0x0d12cea0 nlibcurl|curl_share_strerror+0x2d88
0x1077f6b4:   0x1077f6cc    0x0d12d120 nlibcurl|curl_share_strerror+0x3008
0x1077f6cc:   0x1077f6dc    0x0d112780 nlibcurl|curl_easy_perform+0xa8
0x1077f6dc:   0x1077fc5c    0x0d00f918 homebrew_launcher|downloadFile+0x520
0x1077fc5c:   0x107810ac    0x0d011034 homebrew_launcher|downloadTitle+0x11c8
0x107810ac:   0x10781534    0x0d00a344 homebrew_launcher|downloadMenu+0x61c
0x10781534:   0x10781554    0x0d00af88 homebrew_launcher|mainMenu+0x80
V10lator commented 4 years ago

In case it's needed here's the addToIOQueue function:

size_t addToIOQueue(const void *buf, size_t size, size_t n, FILE *file)
{
    WriteQueueEntry *toAdd;
    void *newBuf;
    bool fast;

    if(buf != NULL)
    {
        size *= n;
        newBuf = MEM1_alloc(size, 4);
        fast = newBuf != NULL;
        if(fast)
        {
            toAdd = MEM1_alloc(sizeof(WriteQueueEntry), 4);
            if(toAdd == NULL)
            {
                MEM1_free(newBuf);
                fast = false;
            }
        }
        if(!fast)
        {
            newBuf = MEMAllocFromDefaultHeap(size);
            if(newBuf == NULL)
                return 0;

            toAdd = MEMAllocFromDefaultHeap(sizeof(WriteQueueEntry));
            if(toAdd == NULL)
            {
                MEMFreeToDefaultHeap(newBuf);
                return 0;
            }
#ifdef NUSSPLI_DEBUG
            if((writeQueueSize + size) >> 20 > maxWriteQueueSize)
            {
                maxWriteQueueSize = (writeQueueSize + size) >> 20;
                debugPrintf("I/O queue size: %d MB", maxWriteQueueSize);
            }
#endif
        }

        OSBlockMove(newBuf, buf, size, false);
    }
    else
    {
        toAdd = MEM1_alloc(sizeof(WriteQueueEntry), 4);
        fast = toAdd != NULL;
        if(!fast)
        {
            toAdd = MEMAllocFromDefaultHeap(sizeof(WriteQueueEntry));
            if(toAdd == NULL)
                return 0;
        }

        newBuf = NULL;
    }

    toAdd->buf = newBuf;
    toAdd->file = file;
    toAdd->size = size;
    toAdd->fast = fast;
    toAdd->next = NULL;

    lockIOQueueAgressive();
    if(newBuf != NULL)
    {
        while(writeQueueSize > MAX_IO_QUEUE_SIZE)
        {
            OSFastMutex_Unlock(writeQueueMutex);
            debugPrintf("Waiting for free slot...");
            OSSleepTicks(256);
            lockIOQueueAgressive();
        }

        writeQueueSize += size;
    }

    if(writeQueue == NULL)
        writeQueue = lastWriteQueueEntry = toAdd;
    else
        lastWriteQueueEntry = lastWriteQueueEntry->next = toAdd;

    OSFastMutex_Unlock(writeQueueMutex);
    return size;
}

It's wired to libCURL like this:

ret |= curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, toRam ? fwrite : addToIOQueue);
ret |= curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);