Discussion:
calling glibc mallinfo() from GDB after attaching to a process?
Chris Markle
2004-08-31 02:09:06 UTC
Permalink
Hi,

I would like to attach to a running program, issue a call to the glibc
mallinfo() function, display the returned mallinfo structure, and the
continue execution of the program. The idea here is to grab some malloc
statistics from a running program... Is this kind of thing possible? If
so, can someone offer up some clues as to the GDB commands to issue to
do this?

Chris
Eli Zaretskii
2004-08-31 03:57:21 UTC
Permalink
Date: Mon, 30 Aug 2004 19:09:06 -0700
I would like to attach to a running program, issue a call to the glibc
mallinfo() function, display the returned mallinfo structure, and the
continue execution of the program. The idea here is to grab some malloc
statistics from a running program... Is this kind of thing possible?
Yes.
If so, can someone offer up some clues as to the GDB commands to
issue to do this?
After attaching to the program, use the command

call mallinfo

to call the function. This will work if mallinfo is linked into the
program.
Chris Markle
2004-08-31 05:24:51 UTC
Permalink
Ed,
Post by Eli Zaretskii
call mallinfo
(warning - gdb rookie here - although I have the manual open on my lap...)

I get in response to this:

[...]
(gdb) break main
Breakpoint 1 at 0x80484d8: file malloc.c, line 12.
(gdb) run
Starting program: /home/cmarkle/src/x
Breakpoint 1, main (argc=1, argv=0xbffebf54) at malloc.c:12
12 malloc(10000);
(gdb) n
13 malloc(100000);
(gdb) n
14 malloc(1000000);
(gdb) call mallinfo
$1 = {<text variable, no debug info>} 0x400a4b30 <__libc_mallinfo>

Supposedly mallinfo() returns a 40-byte mallinfo structure. How do I get
that structure returned and how do I display it?

Thx in advance...

Chris
Michael Chastain
2004-08-31 15:21:01 UTC
Permalink
The gdb command you want is:

(gdb) print mallinfo()

That is, you just say "print EXPRESSION", and EXPRESSION includes
subroutine calls. gdb then does a bunch of behind-the-scenes work
to make a function call into the inferior.

Some people write little stub functions expressly to be called from gdb.
If you are having trouble calling mallinfo() directly, try this:

int my_mallinfo ()
{
struct mallinfo info = mallinfo();
printf ("arena: %d\n", info.arena);
...
return 0;
}

(gdb) print my_mallinfo()
...

That way, you're calling a function in your program instead of
a shared library, and the function returns an int rather than
a struct. Both of these things make gdb work better, and avoid
errors like this:

(gdb) print mallinfo()

Program received signal SIGSEGV, Segmentation fault.
0x4207512d in mallinfo () from /lib/i686/libc.so.6
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (mallinfo) will be abandoned.

Sample code attached.

===

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

int main ()
{
malloc (10);
malloc (10);
}

int my_mallinfo ()
{
struct mallinfo info = mallinfo ();
printf ("arena: %d\n", info.arena);
return 0;
}
Chris Markle
2004-08-31 16:07:56 UTC
Permalink
Michael,

Thanks mucho for your excellent reply...
Post by Michael Chastain
That way, you're calling a function in your program instead of
a shared library, and the function returns an int rather than
a struct. Both of these things make gdb work better, and avoid
(gdb) print mallinfo()
Program received signal SIGSEGV, Segmentation fault.
0x4207512d in mallinfo () from /lib/i686/libc.so.6
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (mallinfo) will be abandoned.
I am getting exactly this seg fault when calling mallinfo(). Do later
versions of gdb deal better with this?

Chris
Michael Chastain
2004-08-31 17:14:13 UTC
Permalink
Post by Chris Markle
I am getting exactly this seg fault when calling mallinfo(). Do later
versions of gdb deal better with this?
No, they don't. I'm getting this seg fault with both gdb 6.2 and
gdb HEAD 2004-08-30.

This happens even when I use the debug version of glibc
with LD_LIBRARY_PATH=/usr/lib/debug.

However, this works:

(gdb) print __libc_mallinfo()

Looking at "readelf -w /usr/lib/libc.so.6", there is a subprogram
named "__libc_mallinfo", but no subprogram named mallinfo. "mallinfo"
is actually just a weak alias for "__libc_mallinfo".

It looks like gdb doesn't pick up the type information for "mallinfo".
That causes gdb to believe that "mallinfo" is a function that takes no
arguments and returns an integer. So when gdb makes the call, it
neglects to use the struct return-value convention and mallinfo dies in
the assembly code that copies the struct return-value back to the
caller-specified area.

I have an old glibc: red hat linux 8, glibc 2.2.93-5-rh.
I don't know if this is better with newer glibc's.

Michael

Andreas Schwab
2004-08-31 09:26:17 UTC
Permalink
Post by Eli Zaretskii
After attaching to the program, use the command
call mallinfo
call mallinfo()

(call is the same as print, except when the expression does not return a
value.)

Andreas.
--
Andreas Schwab, SuSE Labs, ***@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Loading...