1

Can someone explain me the working of a malloc wrapper for below code??

RTLD_NEXT should find the next syblo in search order, which means it should hit my malloc, where i haven't put any allocation scheme like original malloc.

Then how come the allocation is taking place?

I have done something like this in my code:

enter code here: tracer.cc
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
static void* (*lt_malloc)(size_t size);
#define LT_MALLOC (*lt_malloc)

void *malloc(size_t sz)
{
    printf("My malloc called");
    return LT_MALLOC(sz);
}

int main()
{
    if (!lt_malloc)
    {
           lt_malloc = (void*(*)(size_t))dlsym(RTLD_NEXT, "malloc");
        if (!lt_malloc)
        {
            fprintf(stderr, "LeakTracer: could not resolve 'malloc' in 'libc.so': %s\n", dlerror());
            exit(1);
        }
    }

    int *p=(int*)malloc(10);
    *p=34;
    printf("Address of p: %u, value: %d\n",p,*p);

    p=(int*)malloc(10);
    *p=45;
    printf("Address of p: %u, value: %d\n",p,*p); */

}

Check the GDB output, nowhere it goes to libc malloc. Then from where is the memory allocation taking place?

enter code here
Breakpoint 1 at 0x804855d: file malloc1.c, line 25.

(gdb) s
The program is not being run.

(gdb) r
Starting program: /home/raj/timer_test/malloc_wrapper/a.out 

Breakpoint 1, main () at malloc1.c:25
25       int *p=(int*)malloc(20);

(gdb) s
malloc (sz=20) at malloc1.c:10
10       printf("My malloc called");

(gdb) s
11       return LT_MALLOC(sz);

(gdb) s
12      }

(gdb) s
main () at malloc1.c:26
26       *p=45;

(gdb) s
27       printf("Address of p: %u, value: %d\n",p,*p); 

(gdb) s
My malloc calledAddress of p: 146501640, value: 45
29       p=(int*)malloc(20);

(gdb) s
malloc (sz=20) at malloc1.c:10
10       printf("My malloc called");

(gdb) s
11       return LT_MALLOC(sz);

(gdb) s
12      }

(gdb) s
main () at malloc1.c:30
30       *p=56;

(gdb) s
31       printf("Address of p: %u, value: %d\n",p,*p); 

(gdb) s
My malloc calledAddress of p: 146501664, value: 56
32      }

(gdb) s
0x006a8e9c in __libc_start_main () from /lib/libc.so.6

(gdb) s
Single stepping until exit from function __libc_start_main, 
which has no line number information.

Program exited with code 043.
(gdb) 

My confusion, is in which step and how the libc original malloc is called? And why can't the GDB trace it?

One more question, suppose after certain time (may be timer expiry) i want to call original malloc and not mine. How to do that?

RajSanpui
  • 11,556
  • 32
  • 79
  • 146
  • Why do you cast the return value of `malloc`? Especially when you're casting it to the wrong type? – Chris Lutz Mar 31 '11 at 08:02
  • 1
    Are you sure you have debug symbols for your libc installed? gdb usually won't step into a function if it doesn't have the source code for it installed. Have you tried stepping by assembly instruction from line 11? – pmdj Mar 31 '11 at 08:07
  • @Chris: Where do you see i am casting to the wrong type? Everything is correct. – RajSanpui Mar 31 '11 at 08:24
  • @kingsmasher1 - `char *p = (int *)malloc(10);` should be yielding a few compiler complaints, if not flat out errors. – Chris Lutz Mar 31 '11 at 08:39
  • @kingsmasher1 instead of "s", step using "si" – pmdj Mar 31 '11 at 08:49
  • @Chris: Ohhh you can ignore that, that was a typo. Will correct it :) – RajSanpui Mar 31 '11 at 08:54
  • @kingsmasher1 - It's a totally unnecessary problem. `int *p = malloc(10)` is just as valid. (Also, `int *p = malloc(10)` is wrong unless `10 % sizeof(int) == 0`. You should use `int *p = malloc(sizeof(int))` or `int *p = malloc(sizeof *p)`, and if you need 10 of them, multiply by the size. – Chris Lutz Mar 31 '11 at 08:57
  • @Chris: Thanks, i know all these. But it is always better to typecast, because malloc returns pointer of void* type. – RajSanpui Mar 31 '11 at 10:57
  • @kingsmasher1 - There is no gained safety in explicitly casting a `void *` pointer compared to the implicit cast. The explicit cast just takes more work and can cause problems in the future. – Chris Lutz Mar 31 '11 at 15:30
  • @Chris Lutz: Yes, that applies when one is a college level programmer, if you are in a software industry, there are some coding guidelines and rules that every engineer should follow. – RajSanpui Mar 31 '11 at 15:49

1 Answers1

1

I might be wrong, but I think that what is going on is that with the dlsym() call you are getting the address to the malloc in the libc, so your malloc function is acting as a wrapper around the libc malloc [but with the same name] You say:

"which means it should hit my malloc"

but are you sure the symbol for your malloc is the second one? ;) It might be it is the first one, as your malloc is in the same compilation unit.

sergico
  • 2,595
  • 2
  • 29
  • 40
  • @sergico: '''Probably''', you are correct. If i do thia: `p=(int*)LT_MALLOC(10);` the statement "My malloc called is not getting printed" But LT_MALLOC is return value from dlsym right? And specifying RTLD_NEXT in dlsym should point to our malloc. So how come it is hitting the default malloc using LT_MALLOC instead of lt_malloc? – RajSanpui Mar 31 '11 at 08:53
  • @kingsmasher: The string `LT_MALLOC`is simply replaced with the string `lt_malloc`; and yes, the `lt_malloc` function pointer seems to receive from the dlsym() call the pointer to the libc malloc. If you are on a Unix-like system, try nm on the executable and grep for malloc, you might be able to see which one is first in the symbol table. Also, try replacing RTLD_NEXT with RTLD_DEFAULT, this might select the "other" malloc implementation [hopefully yours :)] – sergico Mar 31 '11 at 09:18
  • @sergico: `[root@raj malloc_wrapper]# nm a.out | grep malloc ``Output:080498b0 b lt_malloc 0804852c T malloc` T = defined in my code, what is this b? – RajSanpui Mar 31 '11 at 09:49
  • @sergico: This after replacing, both mallocs with LT_MALLOC, with both as malloc( ) instead of LT_MALLOC the output is again the same as above – RajSanpui Mar 31 '11 at 09:51
  • @kingsmaster: b mean: `The symbol is in the uninitialized data section (known as BSS)` If you replace RTLD_NEXT with RTLD_DEFAULT does your malloc get selected? – sergico Mar 31 '11 at 10:03
  • @sergico: Yes, it does, and that is why it falls into an infinite loop. malloc, in return value again invokes malloc. But output of nm is same !!! One more doubt, i thought RTLD_NEXT should select tnhe "next" malloc after the default one(libc). Right? Please tell me, why this RTLD_NEXT and RTLD_DEFAULT are in confusion? Also why nm value everytime shows same? – RajSanpui Mar 31 '11 at 10:14