Question: I'm studying the heap of glibc.

There's no main\_arena symbol in libc.so, even if I try to dump it with pwntool. However, when I debug a test program, I can print the main\_arena structure. 

```
gdb-peda$ p main_arena
$1 = {
    mutex = 0x0, 
    flags = 0x0, 
    fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
    top = 0x0, 
    last_remainder = 0x0, 
    bins = {0x0 <repeats 254 times>}, 
    binmap = {0x0, 0x0, 0x0, 0x0}, 
    next = 0x7ffff7dd1b20 <main_arena>, 
    next_free = 0x0, 
    attached_threads = 0x1, 
    system_mem = 0x0, 
    max_system_mem = 0x0
}

```

And besides, when I compile test program with -m32, main\_arena can't be found, too.

Answer: 
`main_arena` is a local symbol and is specifically **not exported**. the list of exported symbols is controlled via the `Version` files in the glibc source tree. this is, by design, to keep people from being able to link against random symbols that glibc uses internally (so as to not pollute the namespace as is required by POSIX and other standards).

gdb can find it because you have debug symbols available ... either the C lib is not stripped, or you have the split debug symbols in `/usr/lib/debug/` and gdb is finding those. when you launch gdb, it will tell you things like `Reading symbols from /usr/lib/debug/xxxxx`.

the only way to be able to link against the symbol is to rebuild glibc from source and modify the export list.

alternatively, you could write some code in your app to behave like gdb. namely, open the debug file, process the ELF/DWARF information in it, apply relocations using the active loaded library info (see `dl_iterate_phdr`), and then just start poking memory directly.

if that's too much work, a hackery solution might be to `fork()`+`popen()` gdb against your own process and run it in batch mode to dump symbol info. 

```
char *cmd;
FILE *fp;

asprintf(&cmd, "gdb -q -p %i -batch -ex 'p &main_arena'", getpid());
fp = popen(cmd, "r");
// parse the output of |fp| here looking for the address.

free(cmd);
fclose(fp);

```
The libc.so.6 is stripped.
And the debug version of it is not.
That's why readelf doesn't show main\_arena.

I still wonder how does gdb know the symbol name, even when the library is stripped.