--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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