summaryrefslogtreecommitdiff
path: root/data/eo/eo_gdb.py
blob: aafe881eff503a73ff5cf4301e3e32489b812d61 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Implement eo_break that'll break on a macro/subid/whatever.

import gdb

def symbol_equal_to_string(symbol, string):
   return (symbol != None) and (symbol.name == string)

class Eo_step(gdb.Command):
   STEP_LIMIT = 10
   def __init__(self):
      gdb.Command.__init__(self, "eo_step", gdb.COMMAND_OBSCURE)
      self.START_FUNC = "_eo_call_resolve"
      self.SKIP_FUNC = "_eo_do_start"

   def invoke (self, arg, from_tty):
      # Get to the call resolve function.
      i = 0
      while not symbol_equal_to_string(gdb.selected_frame().function(), self.START_FUNC):
         if symbol_equal_to_string(gdb.selected_frame().function(), self.SKIP_FUNC):
            gdb.execute("finish", False, to_string=True)

         if i > Eo_step.STEP_LIMIT:
             break
         else:
             i += 1
         gdb.execute("step", False, to_string=True)

      # If we found the function, return from it, otherwise, fail.
      if symbol_equal_to_string(gdb.selected_frame().function(), self.START_FUNC):
         gdb.execute("finish", False, to_string=True)
      else:
         print("Search limit reached, you tried calling eo_step too far from an eo_do.")
         return

      # Step until we move to a different function. FIXME: The hook can confuse us, needs to be solved.
      cur_func = gdb.selected_frame().function()
      while gdb.selected_frame().function() == cur_func:
         gdb.execute("stepi", False, to_string=True)

      # One last call to skip into the implementation
      gdb.execute("step", True)

Eo_step()