Home | History | Annotate | Line # | Download | only in gdb.python
      1  1.1.1.2  christos # Copyright (C) 2019-2024 Free Software Foundation, Inc.
      2      1.1  christos # This program is free software; you can redistribute it and/or modify
      3      1.1  christos # it under the terms of the GNU General Public License as published by
      4      1.1  christos # the Free Software Foundation; either version 3 of the License, or
      5      1.1  christos # (at your option) any later version.
      6      1.1  christos #
      7      1.1  christos # This program is distributed in the hope that it will be useful,
      8      1.1  christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
      9      1.1  christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10      1.1  christos # GNU General Public License for more details.
     11      1.1  christos #
     12      1.1  christos # You should have received a copy of the GNU General Public License
     13      1.1  christos # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     14      1.1  christos 
     15      1.1  christos import gdb
     16      1.1  christos 
     17      1.1  christos 
     18      1.1  christos class BadKey:
     19      1.1  christos     def __repr__(self):
     20      1.1  christos         return "Bad Key"
     21      1.1  christos 
     22      1.1  christos 
     23      1.1  christos class ReallyBadKey:
     24      1.1  christos     def __repr__(self):
     25      1.1  christos         return BadKey()
     26      1.1  christos 
     27      1.1  christos 
     28      1.1  christos class pycmd1(gdb.MICommand):
     29      1.1  christos     def invoke(self, argv):
     30      1.1  christos         if argv[0] == "int":
     31      1.1  christos             return {"result": 42}
     32      1.1  christos         elif argv[0] == "str":
     33      1.1  christos             return {"result": "Hello world!"}
     34      1.1  christos         elif argv[0] == "ary":
     35      1.1  christos             return {"result": ["Hello", 42]}
     36      1.1  christos         elif argv[0] == "dct":
     37      1.1  christos             return {"result": {"hello": "world", "times": 42}}
     38      1.1  christos         elif argv[0] == "bk1":
     39      1.1  christos             return {"result": {BadKey(): "world"}}
     40      1.1  christos         elif argv[0] == "bk2":
     41      1.1  christos             return {"result": {1: "world"}}
     42      1.1  christos         elif argv[0] == "bk3":
     43      1.1  christos             return {"result": {ReallyBadKey(): "world"}}
     44      1.1  christos         elif argv[0] == "tpl":
     45      1.1  christos             return {"result": (42, "Hello")}
     46      1.1  christos         elif argv[0] == "itr":
     47      1.1  christos             return {"result": iter([1, 2, 3])}
     48      1.1  christos         elif argv[0] == "nn1":
     49      1.1  christos             return None
     50      1.1  christos         elif argv[0] == "nn2":
     51      1.1  christos             return {"result": [None]}
     52      1.1  christos         elif argv[0] == "red":
     53      1.1  christos             pycmd2("-pycmd")
     54      1.1  christos             return None
     55      1.1  christos         elif argv[0] == "nd1":
     56      1.1  christos             return [1, 2, 3]
     57      1.1  christos         elif argv[0] == "nd2":
     58      1.1  christos             return 123
     59      1.1  christos         elif argv[0] == "nd3":
     60      1.1  christos             return "abc"
     61      1.1  christos         elif argv[0] == "ik1":
     62      1.1  christos             return {"xxx yyy": 123}
     63      1.1  christos         elif argv[0] == "ik2":
     64      1.1  christos             return {"result": {"xxx yyy": 123}}
     65      1.1  christos         elif argv[0] == "ik3":
     66      1.1  christos             return {"xxx+yyy": 123}
     67      1.1  christos         elif argv[0] == "ik4":
     68      1.1  christos             return {"xxx.yyy": 123}
     69      1.1  christos         elif argv[0] == "ik5":
     70      1.1  christos             return {"123xxxyyy": 123}
     71      1.1  christos         elif argv[0] == "empty_key":
     72      1.1  christos             return {"": 123}
     73      1.1  christos         elif argv[0] == "dash-key":
     74      1.1  christos             return {"the-key": 123}
     75      1.1  christos         elif argv[0] == "exp":
     76      1.1  christos             raise gdb.GdbError()
     77      1.1  christos         else:
     78      1.1  christos             raise gdb.GdbError("Invalid parameter: %s" % argv[0])
     79      1.1  christos 
     80      1.1  christos 
     81      1.1  christos class pycmd2(gdb.MICommand):
     82      1.1  christos     def invoke(self, argv):
     83      1.1  christos         if argv[0] == "str":
     84      1.1  christos             return {"result": "Ciao!"}
     85      1.1  christos         elif argv[0] == "red":
     86      1.1  christos             pycmd1("-pycmd")
     87      1.1  christos             raise gdb.GdbError("Command redefined but we failing anyway")
     88      1.1  christos         elif argv[0] == "new":
     89      1.1  christos             pycmd1("-pycmd-new")
     90      1.1  christos             return None
     91      1.1  christos         else:
     92      1.1  christos             raise gdb.GdbError("Invalid parameter: %s" % argv[0])
     93      1.1  christos 
     94      1.1  christos 
     95      1.1  christos # This class creates a command that returns a string, which is passed
     96      1.1  christos # when the command is created.
     97      1.1  christos class pycmd3(gdb.MICommand):
     98      1.1  christos     def __init__(self, name, msg, top_level):
     99      1.1  christos         super(pycmd3, self).__init__(name)
    100      1.1  christos         self._msg = msg
    101      1.1  christos         self._top_level = top_level
    102      1.1  christos 
    103      1.1  christos     def invoke(self, args):
    104      1.1  christos         return {self._top_level: {"msg": self._msg}}
    105      1.1  christos 
    106      1.1  christos 
    107      1.1  christos # A command that is missing it's invoke method.
    108      1.1  christos class no_invoke(gdb.MICommand):
    109      1.1  christos     def __init__(self, name):
    110      1.1  christos         super(no_invoke, self).__init__(name)
    111      1.1  christos 
    112      1.1  christos 
    113      1.1  christos def free_invoke(obj, args):
    114      1.1  christos     return {"result": args}
    115      1.1  christos 
    116      1.1  christos 
    117      1.1  christos # Run some test involving catching exceptions.  It's easier to write
    118      1.1  christos # these as a Python function which is then called from the exp script.
    119      1.1  christos def run_exception_tests():
    120      1.1  christos     print("PASS")
    121  1.1.1.2  christos 
    122  1.1.1.2  christos 
    123  1.1.1.2  christos # Run some execute_mi tests.  This is easier to do from Python.
    124  1.1.1.2  christos def run_execute_mi_tests():
    125  1.1.1.2  christos     # Install the command.
    126  1.1.1.2  christos     cmd = pycmd1("-pycmd")
    127  1.1.1.2  christos     # Pass in a representative subset of the pycmd1 keys, and then
    128  1.1.1.2  christos     # check that the result via MI is the same as the result via a
    129  1.1.1.2  christos     # direct Python call.  Note that some results won't compare as
    130  1.1.1.2  christos     # equal -- for example, a Python MI command can return a tuple,
    131  1.1.1.2  christos     # but that will be translated to a Python list.
    132  1.1.1.2  christos     for name in ("int", "str", "dct"):
    133  1.1.1.2  christos         expect = cmd.invoke([name])
    134  1.1.1.2  christos         got = gdb.execute_mi("-pycmd", name)
    135  1.1.1.2  christos         if expect != got:
    136  1.1.1.2  christos             print("FAIL: saw " + repr(got) + ", but expected " + repr(expect))
    137  1.1.1.2  christos             return
    138  1.1.1.2  christos     ok = False
    139  1.1.1.2  christos     try:
    140  1.1.1.2  christos         gdb.execute_mi("-pycmd", "exp")
    141  1.1.1.2  christos     # Due to the "denaturation" problem, we have to expect a gdb.error
    142  1.1.1.2  christos     # here and not a gdb.GdbError.
    143  1.1.1.2  christos     except gdb.error:
    144  1.1.1.2  christos         ok = True
    145  1.1.1.2  christos     if not ok:
    146  1.1.1.2  christos         print("FAIL: did not throw exception")
    147  1.1.1.2  christos     print("PASS")
    148