X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=.gdbinit;h=7b3b9a79675865c8df10a08cb243c6f6af357427;hb=cd5ab3c6f211fb90799d3c4730d5218e0e0707b2;hp=5b483e6616093f7f11c8ebc827d16ecac7c8c174;hpb=e1119473f3d515fbe53425c056a7b8d07e70fdd8;p=apache diff --git a/.gdbinit b/.gdbinit index 5b483e6616..7b3b9a7967 100644 --- a/.gdbinit +++ b/.gdbinit @@ -18,6 +18,25 @@ document dump_table Print the key/value pairs in a table. end +define dump_skiplist + set $sl = (apr_skiplist *)$arg0 + set $m = $sl->bottom + printf "skiplist@%p: size=%lu: height=%d\n", $sl, $sl->size, $sl->height + while ($m) + printf "(%p,%.12lx)", $m, $m->data + set $u = $m->up + while ($u) + printf " (%p,%.12lx)", $u, $u->data + set $u = $u->up + end + printf "\n" + set $m = $m->next + end +end +document dump_skiplist + Print the nodes/values in a skiplist +end + define dump_string_hash set $h = $arg0->array set $n = $arg0->max @@ -290,7 +309,9 @@ define dump_filter_chain printf " %s(0x%lx): type=%d, ctx=0x%lx, r=%s(0x%lx), c=0x%lx\n", \ $f->frec->name, (unsigned long)$f, $f->frec->ftype, (unsigned long)$f->ctx, \ $f->r == $r ? "r" : ($f->r == 0L ? "null" : \ - ($f->r == $r->main ? "r->main" : "????")), $f->r, $f->c + ($f->r == $r->main ? "r->main" : \ + ($r->main && $f->r == $r->main->main ? "r->main->main" : "????"))), \ + $f->r, $f->c set $f = $f->next end @@ -331,29 +352,162 @@ document dump_servers Print server_rec list info end +define dump_request_tree + set $r = $arg0 + set $i + while $r + printf "r=(0x%lx): uri=%s, handler=%s, r->main=0x%lx\n", \ + $r, $r->unparsed_uri, $r->handler ? $r->handler : "(none)", $r->main + set $r = $r->main + end +end + define dump_allocator printf "Allocator current_free_index = %d, max_free_index = %d\n", \ ($arg0)->current_free_index, ($arg0)->max_free_index printf "Allocator free list:\n" set $i = 0 set $max =(sizeof $arg0->free)/(sizeof $arg0->free[0]) + set $kb = 0 while $i < $max set $node = $arg0->free[$i] if $node != 0 printf " #%2d: ", $i while $node != 0 - printf "%d, ", $node->endp - $node->first_avail + printf "%d, ", ($node->index + 1) << 12 + set $kb = $kb + (($node->index + 1) << 2) set $node = $node->next end printf "ends.\n" end set $i = $i + 1 end + printf "Sum of free blocks: %dkiB\n", $kb end document dump_allocator Print status of an allocator and its freelists. end +define dump_one_pool + set $p = $arg0 + set $size = 0 + set $free = 0 + set $nodes = 0 + set $node = $arg0->active + set $done = 0 + while $done == 0 + set $size = $size + (($node->index + 1) << 12) + set $free = $free + ($node->endp - $node->first_avail) + set $nodes = $nodes + 1 + set $node = $node->next + if $node == $arg0->active + set $done = 1 + end + end + printf "Pool '" + if $p->tag + printf "%s", $p->tag + else + printf "no tag" + end + printf "' [%p]: %d/%d free (%d blocks)\n", $p, $free, $size, $nodes +end + +define dump_all_pools + set $root = $arg0 + while $root->parent + set $root = $root->parent + end + dump_pool_and_children $root +end +document dump_all_pools + Dump the whole pool hierarchy starting from apr_global_pool. Requires an arbitrary pool as starting parameter. +end + +python + +from __future__ import print_function + +class DumpPoolAndChilds (gdb.Command): + """Dump the whole pool hierarchy starting from the given pool.""" + + def __init__ (self): + super (DumpPoolAndChilds, self).__init__ ("dump_pool_and_children", gdb.COMMAND_USER) + + def _allocator_free_blocks(self, alloc): + salloc = "%s" % (alloc) + if self.total_free_blocks.get(salloc) != None: + return self.total_free_blocks[salloc] + i = 0 + dalloc = alloc.dereference() + max =(dalloc['free'].type.sizeof)/(dalloc['free'][0].type.sizeof) + kb = 0 + while i < max: + node = dalloc['free'][i] + if node != 0: + while node != 0: + noded = node.dereference() + kb = kb + ((int(noded['index']) + 1) << 2) + node = noded['next'] + i = i + 1 + self.total_free_blocks[salloc] = kb + return kb + + + def _dump_one_pool(self, arg): + size = 0 + free = 0 + nodes = 0 + darg = arg.dereference() + active = darg['active'] + node = active + done = 0 + while done == 0: + noded = node.dereference() + size = size + ((int(noded['index']) + 1) << 12) + free = free + (noded['endp'] - noded['first_avail']) + nodes = nodes + 1 + node = noded['next'] + if node == active: + done = 1 + if darg['tag'] != 0: + tag = darg['tag'].string() + else: + tag = "No tag" + print("Pool '%s' [%s]: %d/%d free (%d blocks) allocator: %s free blocks in allocator: %i kiB" % (tag, arg, free, size, nodes, darg['allocator'], self._allocator_free_blocks(darg['allocator']))) + self.free = self.free + free + self.size = self.size + size + self.nodes = self.nodes + nodes + + def _dump(self, arg, depth): + pool = arg + print("%*c" % (depth * 4 + 1, " "), end="") + self._dump_one_pool(pool) + if pool['child'] != 0: + self._dump(pool['child'], depth + 1) + s = pool['sibling'] + if s != 0: + self._dump(s, depth) + + def invoke (self, arg, from_tty): + pool = gdb.parse_and_eval(arg) + self.free = 0 + self.size = 0 + self.nodes = 0 + self.total_free_blocks = {} + self._dump(pool, 0) + print("Total %d/%d free (%d blocks)" % (self.free, self.size, self.nodes)) + sum = 0 + for key in self.total_free_blocks: + sum = sum + self.total_free_blocks[key] + print("Total free allocator blocks: %i kiB" % (sum)) + +DumpPoolAndChilds () +end +document dump_pool_and_children + Dump the whole pool hierarchy starting from the given pool. +end + # Set sane defaults for common signals: handle SIGPIPE noprint pass nostop handle SIGUSR1 print pass nostop