Strange memory allocation bug

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
torii
Posts: 16
Joined: Sun Feb 02, 2025 5:59 pm
GitHub: https://github.com/Toriiiiiiiiii
Contact:

Strange memory allocation bug

Post by torii »

Hello all!
I am experiencing a strange bug when using the liballoc implementation of malloc.
When first accessing allocated memory, the next write to memory seems to be ignored completely, leaving the memory uninitialised. I have added some example screenshots below:

Code: Select all

    int *n = malloc(sizeof(int));

    *n = 10;
    char buf[10] = {0};
    utos(*n, 10, buf);
    fputs(1, buf);
    fputs(1, "\n");

    *n = 12;
    utos(*n, 10, buf);
    fputs(1, buf);
malloc bug 2.png
malloc bug 2.png (452 Bytes) Viewed 407 times
By moving the declaration of `buf` before assigning to *n:

Code: Select all

    int *n = malloc(sizeof(int));
    char buf[10] = {0};

    *n = 10;
    utos(*n, 10, buf);
    fputs(1, buf);
    fputs(1, "\n");

    *n = 12;
    utos(*n, 10, buf);
    fputs(1, buf);
malloc bug 3.png
malloc bug 3.png (351 Bytes) Viewed 407 times
Edit: forgot to upload the github link https://github.com/Toriiiiiiiiii/Solkern
Writing bad code since 2019
Image Image
Octocontrabass
Member
Member
Posts: 5876
Joined: Mon Mar 25, 2013 7:01 pm

Re: Strange memory allocation bug

Post by Octocontrabass »

Have you tried disassembling this function? I suspect your code isn't doing what you think it's doing. I'm especially interested in the parameters being passed to utos().
torii
Posts: 16
Joined: Sun Feb 02, 2025 5:59 pm
GitHub: https://github.com/Toriiiiiiiiii
Contact:

Re: Strange memory allocation bug

Post by torii »

Octocontrabass wrote: Thu Jul 03, 2025 7:48 pm I'm especially interested in the parameters being passed to utos().
My implementation of utos() takes the value, number base and output buffer, and the code itself is as follows:

Code: Select all

void utos(uint32_t val, uint8_t base, char *buf) {
    uint32_t n = 0;
    uint32_t temp = val;

    if(val == 0) {
        return "0";
    }
    else {
        while(temp > 0) {
            n++;
            temp /= base;
        }
    }

    buf[n] = '\0';

    char charmap[32] = "0123456789abcdefghijklmnopqrstu";

    unsigned int strptr = n-1;
    while(val > 0) {
        char digit = charmap[val % base];
        val /= base;

        buf[strptr] = digit;
        strptr--;
    }
}
I do not believe the behaviour of this function is relevant to the issue, as the issue still occurs in other scenarios, such as dynamically allocated strings.

Interestingly, moving the testing code to before reading the multiboot information structure makes the numbers appear properly in the serial terminal, however it causes a page fault.
Is it possible that my page allocation code may be faulty? I have the source for that below:

Code: Select all

uint8_t get_frame_status(int frameid) {
    uint32_t index = frameid / 8;
    uint32_t shift = frameid % 8;
    uint8_t  byte  = framemap[index];

    return (byte & (1 << shift)) >> shift;
}

void set_frame_status(int frameid, uint8_t s) {
    uint32_t index = frameid / 8;
    uint32_t shift = frameid % 8;

    framemap[index] |= (s & 1) << shift;
}

void* kalloc_alloc(int n) {
    uint32_t first_frame = (end_kernel) / 4096 + 1;
    uint32_t index = 0;
    while(index < NPAGES) {
        
        uint8_t success = 1;
        for(int i = 0; i < n; ++i) {
            if(get_frame_status(index + i)) { 
                success = 0;
                break;
            }
        }

        if(success) {
            for(int i = 0; i < n; ++i) {
                set_frame_status(index + i, 1);
            }

            return (void*)(first_frame + (index * 4096));
        }

        index++;
    }

    return (void*)0;
}

void kalloc_free(void* ptr, int n) {
    uint32_t first_frame = (end_kernel + 4096) / 4096;
    uint32_t index = ((uint32_t)ptr - first_frame) / 4096;

    for(int i = 0; i < n/8; ++i) {
        for(int j = 0; j < 8; ++j) {
            set_frame_status(index+8*i+j, 0);
        }
    }
}
Writing bad code since 2019
Image Image
Post Reply