Friday, September 16, 2011

GDB - Accessing deque and queue


In O1 mode some of the functions are optimized out and it is impossible to call them.
In case of deque and queue (which is build over deque) it is a bummer for the size() method is calculated.

After finding some examples on the Internet we found nothing usable (I guess because our gcc was using different deque memory structure.)

So we created a new version.

pdequeue_info variable
- Shows size, first, and last element

pdequeue variable [firstidx [lastidx]]
- Shows contents or a range.

define pdequeue_info
 set $var=($arg0)
 set $sizeof=sizeof( **$var._M_impl._M_start._M_node )
 set $size=$sizeof < 512 ? ( 512 / $sizeof ) : 1
 set $i=0
 while $i < $var._M_impl._M_map_size && $var._M_impl._M_map[ $i ] == 0
  set $i++
 end
 set $rv = 0
 while $i < $var._M_impl._M_map_size && $var._M_impl._M_map[ $i ] != $var._M_impl._M_finish._M_first
  set $rv += $size
  set $i++
 end
 if $var._M_impl._M_map[ $i ] != 0
  set $rv += $var._M_impl._M_finish._M_cur - $var._M_impl._M_finish._M_first
 end
 printf "size  : "
 p $rv
 if $rv > 0
  printf "first : "
  p *$var._M_impl._M_start._M_cur
  if $rv > 1
   printf "last  : "
   p *( $var._M_impl._M_finish._M_cur - 1 )
  end
 end
end

define __pdeque_show_group
 set $cur=($arg0)
 set $size=($arg1)
 set $f=($arg2)
 set $l=($arg3)
 set $j=0
 while $j < $size && $n <= $l
  if $n >= $f
    printf "[%i] : ", $n
    p *$cur
  end
  set $cur++
  set $j++
  set $n++
 end
end
define pdequeue
 set $var=($arg0)
 set $f=-1
 set $l=9999999999
 if $argc == 2
  set $f=($arg1)
  set $l=$f
 end
 if $argc == 3
  set $f=($arg1)
  set $l=($arg2)
 end
 set $sizeof=sizeof( **$var._M_impl._M_start._M_node )
 set $size=$sizeof < 512 ? ( 512 / $sizeof ) : 1
 set $i=0
 while $i < $var._M_impl._M_map_size && $var._M_impl._M_map[ $i ] == 0
  set $i++
 end
 set $n=0
 while $i < $var._M_impl._M_map_size && $var._M_impl._M_map[ $i ] != $var._M_impl._M_finish._M_first && $n <= $l
  __pdeque_show_group $var._M_impl._M_map[$i] $size $f $l
  set $i++
 end
 if $var._M_impl._M_map[ $i ] != 0 && $n <= $l
  __pdeque_show_group $var._M_impl._M_map[$i] $var._M_impl._M_finish._M_cur-$var._M_impl._M_finish._M_first $f $l
 end
end