[quagga-dev 11675] GDB macros

Paul Jakma paul at jakma.org
Tue Oct 28 17:02:01 GMT 2014


Hi,

I've got a bunch of GDB macros to print out and help walk a couple of 
common data-structs. Primarily from when I was debugging some ospfd LSDB 
stuff it seems.

Don't know if it's useful to anyone, or if anyone else has similar stuff, 
and whether it might be useful to build up a little library of gdb macros 
somewhere?

It's not well-organised at the moment.

gdb.macros.txt:

define def_ntohs
  set $data = (char *)$arg0
  set $i = 0

  set $_  = $data[$i++] << 8
  set $_ += $data[$i++]
end
document def_ntohs
Read a 2-byte short at the given pointed to area as big-endian and 
return it in $_

Argument: Pointer to a 2-byte, big-endian short word.
Returns: Integer value of that word in $_
end

define def_ntohl
  set $data = (char *)$arg0
  set $i = 0

  set $_  = $data[$i++] << 24
  set $_ += $data[$i++] << 16
  set $_ += $data[$i++] << 8
  set $_ += $data[$i++]
end
document def_ntohl
Read a 4-byte integer at the given pointed to area as big-endian and 
return it in $_

Argument: Pointer to a big-endian 4-byte word.
Returns: Integer value of that word in $_
end

define walk_route_table_next
   # callee saves
   set $_top = $top
   set $_node = $node
   set $_prevl = $prevl

   set $top = (struct route_node *)$arg0
   set $node = (struct route_node *)$arg1
   set $prevl = $node

   # first try left
   #echo try left\n
   set $node = $prevl->link[0]

   # otherwise try right
   if ($node == 0)
     #echo left null, try right\n
     set $node = $prevl->link[1]
   end

   # otherwise go up, till we find the first right that
   # we havn't been to yet
   if ($node == 0)
     set $node = $prevl
     while ($node != $top)
        #echo right null, try up and right\n

        set $prevl = $node
        set $parent = $node->parent
        set $node = $parent->link[1]

        if ($node != 0 && $node != $prevl)
          #echo found node \n
          loop_break
        end

        #echo go up\n
        set $node = $parent
     end
   end

   #printf "next node: 0x%x\n", $node

   set $_ = $node

   set $top = $_top
   set $node = $_node
   set $prevl = $_prevl
end
document walk_route_table_next
Return the next node to visit in the given route_table (or subset of) and
the given current node.

Arguments:
1st: (struct route_node *) to the top of the route_table to walk
2nd: (struct route_node *) to the current node

Returns: The (struct route_node *) for the next to visit in $_
end

define walk_route_table
   set $_visited = $visited
   set $_node = $node
   set $top = $_top

   set $node = (struct route_node *)$arg0
   set $top = (struct route_node *)$arg0
   set $visited = 0

   while ($node != 0)
     printf "Node: 0x%x", $node

     if ($node->info != 0)
       printf "\tinfo: 0x%x", $node->info
       set $visited = $visited + 1
     end

     printf "\n"

     walk_route_table_next $top $node
     set $node = $_

     # we've gotten back to the top, finish
     if ($node == $top)
       set $node = 0
     end
   end
   printf "Visited: %u\n", $visited

   set $top = $_top
   set $visited = $_visited
   set $node = $_node
end

document walk_route_table
Walk through a routing table (or subset thereof) and dump all the non-null
(struct route_node *)->info pointers.

Argument: A lib/thread.h::(struct route_node *) pointing to the route_node
under which all data should be dumped
end

define dump_timeval
   set $tv = (struct timeval *)$arg0
   set $day = 3600*24

   if $tv->tv_sec > $day
     printf "%d days, ", $tv->tv_sec / $day
   end
   if $tv->tv_sec > 3600
     printf "%dh", $tv->tv_sec / 3600
   end
   if ($tv->tv_sec % 3600) > 60
     printf "%dm", ($tv->tv_sec % 3600) / 60
   end
   printf "%d", $tv->tv_sec % 3600 % 60
   if $tv->tv_usec != 0
     printf ".%06d", $tv->tv_usec
   end
   printf "s"
end

define dump_s_addr
   set $addr = (char *)$arg0

   printf "%d.%d.%d.%d", $addr[0], $addr[1], $addr[2], $addr[3]
end

define dump_s6_addr
   set $a6 = (char *)$arg0
   set $f = 0
   while ($f < 16)
     printf "%x%x", $a6[$f], $a6[$f]
     if ($f > 0)
       printf ":"
     end
   end
end

define dump_prefix4
   set $p = $arg0
   echo IPv4:
   dump_s_addr &($p->u.prefix4)
   printf "/%d\n", $p->prefixlen
end
document dump_prefix4
Textual dump of a (struct prefix4 *) argument.
end

define dump_prefix6
   set $p = $arg0
   echo IPv6:
   dump_s6_addr &($p->u.prefix6)
   printf "/%d\n", $p->prefixlen
end
document dump_prefix6
Textual dump of a (struct prefix6 *) argument.
end

define dump_prefix
   set $p = $arg0

   if ($p->family == 2)
     dump_prefix4 $p
   end
   if ($p->family == 10)
     dump_prefix6 $p
   end
end

define dump_ospf_lsa_flags
   set $flags = $arg0

   printf "%u: ", $flags

   if $flags & 0x1
     echo Self,
   end
   if $flags & 0x2
     echo Self-checked,
   end
   if $flags & 0x4
     echo Recvd,
   end
   if $flags & 0x8
     echo Apprvd,
   end
   if $flags & 0x10
     echo Discard,
   end
   if $flags & 0x20
     echo Local-Xlt,
   end
   if $flags & 0x40
     echo Premature-Aged,
   end
   if $flags & 0x40
     echo In-Maxage,
   end
   echo \n
end

define dump_ospf_lsa_data
   set $lsad = (struct lsa_header *)$arg0

   echo ID / AdvRtr:  \t\t
   dump_s_addr &$lsad->id.s_addr
   echo \ : \
   dump_s_addr &$lsad->adv_router.s_addr
   echo \n

   def_ntohs &$lsad->ls_age
   printf "Type: %2u Age: %4u,", $lsad->type, $_

   def_ntohs &$lsad->length
   printf " length: %2u", $_

   def_ntohl &$lsad->ls_seqnum
   printf " Seqnum: 0x%08x", $_

   def_ntohs &$lsad->checksum
   printf " csum: 0x%04x\n", $_

   # return the age
   def_ntohs &$lsad->ls_age
end

define dump_ospf_lsa
   set $lsa = (struct ospf_lsa *)$arg0

   #print/x *$lsa

   dump_ospf_lsa_data $lsa->data

   set $relage = $_ + (relative_time.tv_sec - $lsa->tv_recv.tv_sec)
   printf "Relative age: %4u\n", $relage

   dump_ospf_lsa_flags $lsa->flags

   echo tv_recv: \
   dump_timeval &$lsa->tv_recv
   echo \ tv_orig: \
   dump_timeval &$lsa->tv_orig
   echo \n

   printf "lock %2u", $lsa->lock
   printf " stat %2d", $lsa->stat
   printf " rtx count: %u", $lsa->retransmit_counter
   printf " rfsh list: %d", $lsa->refresh_list
   printf "\n\n"
end

define walk_ospf_lsdb
   set $node = (struct route_node *)$arg0
   set $top = (struct route_node *)$arg0
   set $visited = 0

   while ($node != 0)
     set $prevl = $node

     if ($node->info != 0)
       dump_ospf_lsa $node->info
       set $visited = $visited + 1
     end

     walk_route_table_next $top $node
     set $node = $_

     # we've gotten back to the top, finish
     if ($node == $top)
       set $node = 0
     end
   end
   printf "Visited: %u\n", $visited
end

document walk_ospf_lsdb
Walk through an OSPF LSDB (or subset thereof) and dump all the LSAs
contained there-in.

Argument: A (struct route_node *) pointing to the top of the
LSDB route-table which should be dumped.
end

define rn_next_down
   set $node = $arg0
   while ($node != 0)
     print/x $node
     if ($node->link[0] != 0)
       set $node = $node->link[0]
     else
       set $node = $node->link[1]
     end
   end
end

document rn_next_down
Walk left-down a given route table, dumping locations of route_nodes

Argument: A single (struct route_node *).
end

define rn_next_up
   set $top = (struct route_node *)$arg0
   set $node = (struct route_node *)$arg1

   while ($node != $top)
     echo walk up\n

     set $prevl = $node
     set $parent = $node->parent
     set $node = $parent->link[1]

     if ($node != 0 && $node != $prevl)
       echo found a node\n
       loop_break
     end

     echo going up\n
     set $node = $parent
   end
   output/x $node
   echo \n
end

document rn_next_up
Walk up-and-right from the given route_node to the next valid route_node
which is not the given "top" route_node

Arguments:
1st: A (struct route_node *) to the top of the route table.
2nd: The (struct route_node *) to walk up from
end

define ospf_backbone_lsdb_top
   set $type = $arg0

   set $ospf = ospf_master->ospf->head->data

   output/x ((struct ospf *)$ospf)->backbone->lsdb->type[$type]->db->top
   echo \n
end
document ospf_backbone_lsdb_top
Dump location of the LSDB in the backbone area for the given LSA type

Argument: Integer LSA type
end

regards,
-- 
Paul Jakma	paul at jakma.org	@pjakma	Key ID: 64A2FF6A
Fortune:
Someday somebody has got to decide whether the typewriter is the machine,
or the person who operates it.




More information about the Quagga-dev mailing list