Home Modular Debugger (MDB)
Post
Cancel

Modular Debugger (MDB)

适用于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);
}
This post is licensed under CC BY 4.0 by the author.