cfunction-interposition

Interposition at compile time does not work


I am learning about interposition. The code below is taken from a course (CMU 15-213), however, when I compile, this warning "mymalloc.c:6:29: warning: all paths through this function will call itself [-Winfinite-recursion]" occurs.

As I understand, a call to malloc in main() will instead be transferred to the call to mymalloc(). Inside mymalloc(), malloc is called again and hence, the loop occurs.

//int.c

#include <stdio.h>
#include "malloc.h"

int main() {
    int *p = malloc(32);
    free(p);
    return (0);
}
//malloc.h

#include <stdlib.h>
#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)

void *mymalloc(size_t size);
void myfree(void *ptr);
//mymalloc.c

#ifdef COMPILETIME
#include <stdio.h>
#include "malloc.h"

/* malloc wrapper function */
void *mymalloc(size_t size) {
    void *ptr = malloc(size);
    printf("malloc(%d)=%p\n",
           (int)size, ptr);
    return ptr;
}

/* free wrapper function */
void myfree(void *ptr)
{
    free(ptr);
    printf("free(%p)\n", ptr);
}
#endif
//Makefile

CC = gcc
CFLAGS = -Wall

intc: int.c mymalloc.c
    $(CC) $(CFLAGS) -DCOMPILETIME -c mymalloc.c
    $(CC) $(CFLAGS) -I. -o intc int.c mymalloc.o

runc:
    ./intc

clean:
    rm -f *~ intr intl intc *.so *.o

I tried searching but couldn't find any solution to this problem. Can anyone please help ? Thank you.


Solution

  • You wrote

    #include "malloc.h"
    ...
    void *mymalloc(size_t size) {
        void *ptr = malloc(size);
    

    which after preprocessing comes out as

    void *mymalloc(size_t size) {
        void *ptr = mymalloc(size);
    

    The diagnostic is accurate. Infinite recursion won't make you happy, as it will lead to stack overflow.

    The #define malloc(size) mymalloc(size) is good for user application code, but not for the library code you're writing here. Arrange for application and library source files to consume appropriate macro definitions. You might need one more header file, here.

    You wrote that both int.c and mymalloc.c should #include "malloc.h". No, that cannot be. The int.c application can consume a #define which changes what "malloc()" means. But the mymalloc.c library code cannot, as it must access the original libc malloc routine.