diff --git a/dev/gdb/ebtree.gdb b/dev/gdb/ebtree.gdb new file mode 100644 index 000000000..c7a6b943d --- /dev/null +++ b/dev/gdb/ebtree.gdb @@ -0,0 +1,118 @@ +# sets $tag and $node from $arg0, for internal use only +define _ebtree_set_tag_node + set $tag = (unsigned long)$arg0 & 0x1 + set $node = (unsigned long)$arg0 & 0xfffffffffffffffe + set $node = (struct eb_node *)$node +end + +# get root from any node (leaf of node), returns in $node +define ebtree_root + set $node = (struct eb_root *)$arg0->node_p + if $node == 0 + # sole node + set $node = (struct eb_root *)$arg0->leaf_p + end + # walk up + while 1 + _ebtree_set_tag_node $node + if $node->branches.b[1] == 0 + break + end + set $node = $node->node_p + end + # root returned in $node +end + +# returns $node filled with the first node of ebroot $arg0 +define ebtree_first + # browse ebtree left until encoutering leaf + set $node = (struct eb_node *)$arg0->b[0] + while 1 + _ebtree_set_tag_node $node + if $tag == 0 + loop_break + end + set $node = (struct eb_root *)$node->branches.b[0] + end + # extract last node + _ebtree_set_tag_node $node +end + +# finds next ebtree node after $arg0, and returns it in $node +define ebtree_next + # get parent + set $node = (struct eb_root *)$arg0->leaf_p + # Walking up from right branch, so we cannot be below root + # while (eb_gettag(t) != EB_LEFT) // #define EB_LEFT 0 + while 1 + _ebtree_set_tag_node $node + if $tag == 0 + loop_break + end + set $node = (struct eb_root *)$node->node_p + end + set $node = (struct eb_root *)$node->branches.b[1] + # walk down (left side => 0) + # while (eb_gettag(start) == EB_NODE) // #define EB_NODE 1 + while 1 + _ebtree_set_tag_node $node + if $node == 0 + loop_break + end + if $tag != 1 + loop_break + end + set $node = (struct eb_root *)$node->branches.b[0] + end +end + + +# sets $tag and $node from $arg0, for internal use only +define _ebsctree_set_tag_node + set $tag = (unsigned long)$arg0 & 0x1 + set $node = (unsigned long)$arg0 & 0xfffffffffffffffe + set $node = (struct eb32sc_node *)$node +end + +# returns $node filled with the first node of ebroot $arg0 +define ebsctree_first + # browse ebsctree left until encoutering leaf + set $node = (struct eb32sc_node *)$arg0->b[0] + while 1 + _ebsctree_set_tag_node $node + if $tag == 0 + loop_break + end + set $node = (struct eb_root *)$node->branches.b[0] + end + # extract last node + _ebsctree_set_tag_node $node +end + +# finds next ebtree node after $arg0, and returns it in $node +define ebsctree_next + # get parent + set $node = (struct eb_root *)$arg0->node.leaf_p + # Walking up from right branch, so we cannot be below root + # while (eb_gettag(t) != EB_LEFT) // #define EB_LEFT 0 + while 1 + _ebsctree_set_tag_node $node + if $tag == 0 + loop_break + end + set $node = (struct eb_root *)$node->node.node_p + end + set $node = (struct eb_root *)$node->node.branches.b[1] + # walk down (left side => 0) + # while (eb_gettag(start) == EB_NODE) // #define EB_NODE 1 + while 1 + _ebsctree_set_tag_node $node + if $node == 0 + loop_break + end + if $tag != 1 + loop_break + end + set $node = (struct eb_root *)$node->node.branches.b[0] + end +end diff --git a/dev/gdb/list.gdb b/dev/gdb/list.gdb new file mode 100644 index 000000000..22d557c08 --- /dev/null +++ b/dev/gdb/list.gdb @@ -0,0 +1,26 @@ +# lists entries starting at list head $arg0 +define list_dump + set $h = $arg0 + set $p = *(void **)$h + while ($p != $h) + printf "%#lx\n", $p + if ($p == 0) + loop_break + end + set $p = *(void **)$p + end +end + +# list all entries starting at list head $arg0 until meeting $arg1 +define list_find + set $h = $arg0 + set $k = $arg1 + set $p = *(void **)$h + while ($p != $h) + printf "%#lx\n", $p + if ($p == 0 || $p == $k) + loop_break + end + set $p = *(void **)$p + end +end diff --git a/dev/gdb/pools.gdb b/dev/gdb/pools.gdb new file mode 100644 index 000000000..795432e41 --- /dev/null +++ b/dev/gdb/pools.gdb @@ -0,0 +1,21 @@ +# dump pool contents (2.9 and above, with buckets) +define pools_dump + set $h = $po + set $p = *(void **)$h + while ($p != $h) + set $e = (struct pool_head *)(((char *)$p) - (unsigned long)&((struct pool_head *)0)->list) + + set $total = 0 + set $used = 0 + set $idx = 0 + while $idx < sizeof($e->buckets) / sizeof($e->buckets[0]) + set $total=$total + $e->buckets[$idx].allocated + set $used=$used + $e->buckets[$idx].used + set $idx=$idx + 1 + end + + set $mem = $total * $e->size + printf "list=%#lx pool_head=%p name=%s size=%u alloc=%u used=%u mem=%u\n", $p, $e, $e->name, $e->size, $total, $used, $mem + set $p = *(void **)$p + end +end diff --git a/dev/gdb/post-mortem.gdb b/dev/gdb/post-mortem.gdb new file mode 100644 index 000000000..1e8abd5e4 --- /dev/null +++ b/dev/gdb/post-mortem.gdb @@ -0,0 +1,47 @@ +# This script will set the post_mortem struct pointer ($pm) from the one found +# in the "post_mortem" symbol. If not found or if not correct, it's the same +# address as the "_post_mortem" section, which can be found using "info files" +# or "objdump -h" on the executable. The guessed value is the by a first call +# to pm_init, but if not correct, you just need to call pm_init again with the +# correct pointer, e.g: +# pm_init 0xcfd400 + +define pm_init + set $pm = (struct post_mortem*)$arg0 + set $g = $pm.global + set $ti = $pm.thread_info + set $tc = $pm.thread_ctx + set $tgi = $pm.tgroup_info + set $tgc = $pm.tgroup_ctx + set $fd = $pm.fdtab + set $pxh = *$pm.proxies + set $po = $pm.pools + set $ac = $pm.activity +end + +# show basic info on the running process (OS, uid, etc) +define pm_show_info + print $pm->platform + print $pm->process +end + +# show thread IDs to easily map between gdb threads and tid +define pm_show_threads + set $t = 0 + while $t < $g.nbthread + printf "Tid %4d: pthread_id=%#lx stack_top=%#lx\n", $t, $ti[$t].pth_id, $ti[$t].stack_top + set $t = $t + 1 + end +end + +# dump all threads' dump buffers +define pm_show_thread_dump + set $t = 0 + while $t < $g.nbthread + printf "%s\n", $tc[$t].thread_dump_buffer->area + set $t = $t + 1 + end +end + +# initialize the various pointers +pm_init &post_mortem diff --git a/dev/gdb/proxies.gdb b/dev/gdb/proxies.gdb new file mode 100644 index 000000000..4b34fb097 --- /dev/null +++ b/dev/gdb/proxies.gdb @@ -0,0 +1,25 @@ +# list proxies starting with the one in argument (typically $pxh) +define px_list + set $p = (struct proxy *)$arg0 + while ($p != 0) + printf "%p (", $p + if $p->cap & 0x10 + printf "LB," + end + if $p->cap & 0x1 + printf "FE," + end + if $p->cap & 0x2 + printf "BE," + end + printf "%s)", $p->id + if $p->cap & 0x1 + printf " feconn=%u cmax=%u cum_conn=%llu cpsmax=%u", $p->feconn, $p->fe_counters.conn_max, $p->fe_counters.cum_conn, $p->fe_counters.cps_max + end + if $p->cap & 0x2 + printf " beconn=%u served=%u queued=%u qmax=%u cum_sess=%llu wact=%u", $p->beconn, $p->served, $p->queue.length, $p->be_counters.nbpend_max, $p->be_counters.cum_sess, $p->lbprm.tot_wact + end + printf "\n" + set $p = ($p)->next + end +end diff --git a/dev/gdb/servers.gdb b/dev/gdb/servers.gdb new file mode 100644 index 000000000..8aad06bd5 --- /dev/null +++ b/dev/gdb/servers.gdb @@ -0,0 +1,9 @@ +# list servers in a proxy whose pointer is passed in argument +define px_list_srv + set $h = (struct proxy *)$arg0 + set $p = ($h)->srv + while ($p != 0) + printf "%#lx %s maxconn=%u cur_sess=%u max_sess=%u served=%u queued=%u st=%u->%u ew=%u sps_max=%u\n", $p, $p->id, $p->maxconn, $p->cur_sess, $p->counters.cur_sess_max, $p->served, $p->queue.length, $p->cur_state, $p->next_state, $p->cur_eweight, $p->counters.sps_max + set $p = ($p)->next + end +end diff --git a/dev/gdb/stream.gdb b/dev/gdb/stream.gdb new file mode 100644 index 000000000..0baea0336 --- /dev/null +++ b/dev/gdb/stream.gdb @@ -0,0 +1,18 @@ +# list all streams for all threads +define stream_dump + set $t = 0 + while $t < $g.nbthread + set $h = &$tc[$t].streams + printf "Tid %4d: &streams=%p\n", $t, $h + set $p = *(void **)$h + while ($p != $h) + set $s = (struct stream *)(((char *)$p) - (unsigned long)&((struct stream *)0)->list) + printf " &list=%#lx strm=%p uid=%u strm.fe=%s strm.flg=%#x strm.list={n=%p,p=%p}\n", $p, $s, $s->uniq_id, $s->sess->fe->id, $s->flags, $s->list.n, $s->list.p + if ($p == 0) + loop_break + end + set $p = *(void **)$p + end + set $t = $t + 1 + end +end