适用于linux系统的mdb:
https://github.com/luochenglcs/mdb
If the code is useful to you - great !. Spread it around and get people to use, debug and enhance it.
一、libumem_ready赋值
1
2
| umem_update_variables
->|umem_set_standalone == -1 ? libumem_ready : UMEM_READVAR(umem_ready);
|
1
2
3
| umem_set_standalone
->|mdb_lookup_by_obj
->|lookup_minimal_symbol("umem_alloc",NULL, NULL)
|
1
2
3
4
| UMEM_READVAR(umem_ready)
->|umem_lookup_by_name
->mdb_lookup_by_obj
->lookup_minimal_symbol("umem_ready", NULL, NULL)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| //http://agentzh.org/misc/code/gdb/minsyms.c.html#L163
/* Look through all the current minimal symbol tables and find the
first minimal symbol that matches NAME. If OBJF is non-NULL, limit
the search to that objfile. If SFILE is non-NULL, the only file-scope
symbols considered will be from that source file (global symbols are
still preferred). Returns a pointer to the minimal symbol that
matches, or NULL if no match is found.
Note: One instance where there may be duplicate minimal symbols with
the same name is when the symbol tables for a shared library and the
symbol tables for an executable contain global symbols with the same
names (the dynamic linker deals with the duplication).
It's also possible to have minimal symbols with different mangled
names, but identical demangled names. For example, the GNU C++ v3
ABI requires the generation of two (or perhaps three) copies of
constructor functions --- "in-charge", "not-in-charge", and
"allocate" copies; destructors may be duplicated as well.
Obviously, there must be distinct mangled names for each of these,
but the demangled names are all the same: S::S or S::~S. */
struct bound_minimal_symbol
lookup_minimal_symbol (const char *name, const char *sfile,
struct objfile *objf)
{
...
}
|
二、重点函数
1 leaky_subr_estimate
1
2
3
4
5
6
7
| leaky_subr_estimate(*estp) //est是个数
->|mdb_walk("umem_cache", (mdb_walk_cb_t)leaky_estimate, estp)
->|mdb_pwalk("umem_cache", (mdb_walk_cb_t)leaky_estimate, estp, NULL)
->|mdb_walker_lookup("umem_cache") -> mdb_iwalker_t *iwp
->|walk_common(mdb_wcb_create(iwp, func, data, addr))
->|mdb_walk("vmem", (mdb_walk_cb_t)leaky_estimate_vmem, estp)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| mdb_wcb_t *
mdb_wcb_create(mdb_iwalker_t *iwp, mdb_walk_cb_t cb, void *data, uintptr_t addr)
{
mdb_wcb_t *wcb = mdb_zalloc(sizeof (mdb_wcb_t), UM_SLEEP);
wcb->w_buftag = WCB_TAG_INITIAL;
wcb->w_walker = iwp;
wcb->w_state.walk_callback = cb;
wcb->w_state.walk_cbdata = data;
wcb->w_state.walk_addr = addr;
wcb->w_state.walk_arg = iwp->iwlk_init_arg;
return (wcb);
}
|