0

I'm trying to code my own malloc. I generate a .so file and do some tests with my library. The basic allocation tests work and so does LD_PRELOAD=./libmy_malloc.so ls -laRH /. But when I run LD_PRELOAD=./libmy_malloc.so emacs, I get an error: emacs: Wrong type argument: characterp, -1.

Do you know what would be the cause of this one? I don't see where the mistake could be..

Here is the code I use for malloc / calloc / realloc / reallocarray and free :

Here is my struct :

typedef struct block_s
{
    bool isFree;
    void *_ptr;
    size_t _size;
    struct block_s *next;
} block_t;

extern block_t *_head;
#define _BLOCKSIZE_(size) (sizeof(block_t)+size)

malloc :

static size_t space_left = 0;

void *action(size_t size)
{
    void *new = sbrk(size);
    return (new == (void*)-1 ? NULL : new);
}

size_t getpage(size_t size)
{
    size_t page = getpagesize() * 2;

    while (page < _BLOCKSIZE_(size))
        page += getpagesize() * 2;
    return (page);
}

void *init_memblock(size_t size)
{
    size_t tmp = getpage(size);
    _head = action(tmp);

    if (_head == NULL)
        return (NULL);
    space_left = tmp - _BLOCKSIZE_(size);
    _head->isFree = false;
    _head->_ptr = (char*)_head + sizeof(block_t);
    _head->_size = size;
    _head->next = NULL;
    return (_head->_ptr);
}

void *alloc(size_t size, void *pos)
{
    block_t *new = pos;
    size_t page = getpage(size);

    if (space_left < _BLOCKSIZE_(size)) {
        if (action(page) == NULL)
            return (NULL);
        space_left += page;
    }
    space_left -= _BLOCKSIZE_(size);
    new->isFree = false;
    new->_ptr = (char*)new + sizeof(block_t);
    new->_size = size;
    new->next = NULL;
    return (new);
}

block_t *search_memblock(block_t *_block, size_t size)
{
    block_t *prev = NULL;

    while (_block != NULL) {
        prev = _block;
        if (_block->isFree == true && _block->_size >= size) {
            _block->isFree = false;
            return (_block);
        }
        _block = _block->next;
    }
    prev->next = alloc(size, (void*)prev+_BLOCKSIZE_(prev->_size));
    return (prev->next);
}

void *malloc(size_t size)
{
    block_t *memblock = NULL;

    if (!size)
        return (NULL);
    if (_head == NULL)
        return (init_memblock(size));
    memblock = search_memblock(_head, size);
    if (memblock != NULL)
        return (memblock->_ptr);
    return (NULL);
}

free :

void free(void *ptr)
{
    block_t *block = ptr - sizeof(block_t);

    if (!ptr)
        return;
    block->isFree = true;
}

calloc :

void *calloc(size_t nmemb, size_t size)
{
    void *ptr = malloc(nmemb * size);

    if (ptr == NULL)
        return (NULL);
    memset(ptr, 0, nmemb * size);
    return (ptr);
}

realloc :

void *realloc(void *ptr, size_t size)
{
    void *tmp = NULL;

    if (size == 0) {
        free(ptr);
        return (NULL);
    }
    if (ptr == NULL)
        return (malloc(size));
    tmp = malloc(size);
    if (tmp)
        memcpy(tmp, ptr, size);
    if (ptr)
        free(ptr);
    return (tmp);
}

and reallocarray :

void *reallocarray(void *ptr, size_t nmemb, size_t size)
{
    return (realloc(ptr, nmemb * size));
}

Thank you in advance

  • Shot in the dark, but I can easily imagine that GNU emacs is making use of special, nonstandard, undocumented features of glibc malloc, features that your straightforward reimplementation is obviously ignorant of... – Steve Summit Feb 18 '22 at 18:11
  • Mmh.. How can I resolve this type of situation? – Team もののけ姫 Feb 18 '22 at 18:15
  • Grab the source code for the version of emacs you're using and start digging. – Retired Ninja Feb 18 '22 at 18:20
  • Maybe the problem would come from the code but I even ran other commands and the ls one with all the recusive type flags and it worked fine. But is this the right way? – Team もののけ姫 Feb 18 '22 at 18:27
  • Is it "the right way"? Not sure what you mean by that. Writing your own version of malloc is an excellent exercise. Using LD_PRELOAD tricks to sneak your version in so that real programs get it instead of the standard one — that's such a phenomenally bad idea, and impossible on so many levels, that I don't know where to start! I'm astonished and impressed that you've gotten it to work at all. – Steve Summit Feb 18 '22 at 18:56
  • Now, don't get me wrong: when I say "a phenomenally bad idea, and impossible on so many levels", I don't mean that pejoratively. I did the same sort of thing myself, once, to replace `open` and `read` and `write`, in order to slip in my own virtual filesystem underneath standard apps. Worked great, too, for a while, but it was terrifically hacky and unsustainable. But good luck with your similar effort! Unfortunately I don't think I have any tips on how to "resolve" the problem with emacs, though. – Steve Summit Feb 18 '22 at 18:57
  • Thank you for the time you took to study my situation. I will try to look further into the problem. Like I said, don't worry be happy =) – Team もののけ姫 Feb 18 '22 at 19:06
  • @SteveSummit Note that using the LD_PRELOAD trick in such a way is actually fairly common and is (as far as I recall) used by tools such as valgrind etc. Far from trivial though -- that I'll accept :-) – G.M. Feb 18 '22 at 19:14
  • Is the `emacs` found in your path a binary executable or a shell/python/??? script that sets up an environment before launching the binary? – G.M. Feb 18 '22 at 19:17
  • @G.M. ISWYM. Thanks. (For those curious: see [What is the LD_PRELOAD trick?](https://stackoverflow.com/questions/426230/what-is-the-ld-preload-trick)) – Steve Summit Feb 18 '22 at 19:18
  • @Teamもののけ姫 Having read G.M.'s comment, I must soften my flamboyant language about "phenomenally bad idea, and impossible on so many levels". Evidently people use LD_PRELOAD to "slip in" debugging versions of malloc all the time, so you're actually in good company. But GNU EMACS is of course a crazy sophisticated program, with voracious and specialized memory allocation requirements, so it's not surprising it had problems with anything other than the malloc in glibc, even though `ls` was fine with your version. – Steve Summit Feb 18 '22 at 19:22
  • @G.M. I'm not sure but I think it's a shell/python – Team もののけ姫 Feb 18 '22 at 19:29
  • @SteveSummit I see.. So the problem would be that my allocation functions do not handle a specific case(s) if I understood correctly – Team もののけ姫 Feb 18 '22 at 19:30

0 Answers0