• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#   Copyright 2020 - The Android Open Source Project
2#
3#   Licensed under the Apache License, Version 2.0 (the "License");
4#   you may not use this file except in compliance with the License.
5#   You may obtain a copy of the License at
6#
7#       http://www.apache.org/licenses/LICENSE-2.0
8#
9#   Unless required by applicable law or agreed to in writing, software
10#   distributed under the License is distributed on an "AS IS" BASIS,
11#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12#   See the License for the specific language governing permissions and
13#   limitations under the License.
14
15import unittest
16import gdb
17import json
18
19
20def remove_gdb_output_prefix(str):
21    """ gdb output contains a "$%d =" prefix, the function remove the prefix
22    """
23    idx = str.find("=")
24    return str[idx + 1:]
25
26
27def check_type_and_ctype(input_json, input_type, ctype):
28    assert(input_json["type"] == input_type)
29    assert(input_json["ctype"] == ctype)
30
31
32def check_basic_value(input_json, input_type, ctype, value):
33    check_type_and_ctype(input_json, input_type, ctype)
34    assert(input_json["value"] == value)
35
36
37def gdb_extract_variable_to_json(variable_name):
38    """ extract a variable from gdb
39
40    Args:
41        variable_name:
42            a string, the name of the variable to extract
43    Returns:
44        A json Object in Python
45    """
46    variable = gdb.execute("p {}".format(variable_name), to_string=True)
47    variable = remove_gdb_output_prefix(variable)
48    variable_json = json.loads(variable)
49    return variable_json
50
51
52def json_equal_except_address(testcase, json0, json1):
53    """ check if all content of two json are same except the address fields
54
55    The function will check the two json objects recursively to set address fields to None,
56    then convert two json objects into strings with sorted keys, and check if the two strings
57    are same.
58    """
59    def replace_address_by_None(input_json):
60        if isinstance(input_json, dict):
61            for (k, v) in input_json.items():
62                if k == "address":
63                    input_json[k] = None
64                else:
65                    replace_address_by_None(v)
66        elif isinstance(input_json, list):
67            for item in input_json:
68                replace_address_by_None(item)
69
70    replace_address_by_None(json0)
71    replace_address_by_None(json1)
72    json0 = json.dumps(json0, sort_keys=True)
73    json1 = json.dumps(json1, sort_keys=True)
74    testcase.assertEqual(json0, json1)
75
76
77def test_json_variable(testcase, testname, line, variable_name_list):
78    for variable_name in variable_name_list:
79        variable_json = gdb_extract_variable_to_json(variable_name)
80        with open("test/{}_{}_{}.json".format(testname, str(line), variable_name), "r") as f:
81            expect_variable = json.load(f)
82        json_equal_except_address(testcase, variable_json, expect_variable)
83
84
85class TestGdbJsonPrinter(unittest.TestCase):
86
87    def __init__(self, *args, **kwargs):
88        super().__init__(*args, **kwargs)
89        self.maxDiff = None
90
91    def test_basic_types(self):
92        gdb.execute("file test_examples/basic_types")
93        gdb.execute("b 42")
94        gdb.execute("r")
95
96        variable_json = gdb_extract_variable_to_json("a")
97        check_basic_value(variable_json, "int", "uint8_t", "1")
98
99        variable_json = gdb_extract_variable_to_json("a")
100        check_basic_value(variable_json, "int", "uint8_t", "1")
101
102        variable_json = gdb_extract_variable_to_json("b")
103        check_basic_value(variable_json, "int", "int8_t", "-2")
104
105        variable_json = gdb_extract_variable_to_json("c")
106        check_basic_value(variable_json, "int", "uint16_t", "3")
107
108        variable_json = gdb_extract_variable_to_json("d")
109        check_basic_value(variable_json, "int", "int16_t", "-4")
110
111        variable_json = gdb_extract_variable_to_json("e")
112        check_basic_value(variable_json, "int", "uint32_t", "5")
113
114        variable_json = gdb_extract_variable_to_json("f")
115        check_basic_value(variable_json, "int", "int32_t", "-6")
116
117        variable_json = gdb_extract_variable_to_json("g")
118        check_basic_value(variable_json, "int", "uint64_t", "7")
119
120        variable_json = gdb_extract_variable_to_json("h")
121        check_basic_value(variable_json, "int", "int64_t", "-8")
122
123        variable_json = gdb_extract_variable_to_json("i")
124        check_basic_value(variable_json, "float", "float", "9.0")
125
126        variable_json = gdb_extract_variable_to_json("j")
127        check_basic_value(variable_json, "float", "double", "-10.0")
128
129        variable_json = gdb_extract_variable_to_json("k")
130        check_type_and_ctype(variable_json, "pointer", "const char *")
131        check_basic_value(
132            variable_json["reference"], "int", "const char", "72")
133
134        variable_json = gdb_extract_variable_to_json("l")
135        check_type_and_ctype(variable_json, "pointer", "void *")
136        assert(variable_json["reference"] == "cannot extract void ptr")
137
138        variable_json = gdb_extract_variable_to_json("m")
139        check_type_and_ctype(variable_json, "pointer", "char *")
140        assert(variable_json["reference"] == "nullptr")
141
142        variable_json = gdb_extract_variable_to_json("o")
143        check_basic_value(variable_json, "enum", "Animal", "0")
144
145        gdb.execute("b 61")
146        gdb.execute("c")
147
148        variable_json = gdb_extract_variable_to_json("a")
149        check_basic_value(variable_json, "int", "const uint8_t", "1")
150
151        variable_json = gdb_extract_variable_to_json("a")
152        check_basic_value(variable_json, "int", "const uint8_t", "1")
153
154        variable_json = gdb_extract_variable_to_json("b")
155        check_basic_value(variable_json, "int", "const int8_t", "-2")
156
157        variable_json = gdb_extract_variable_to_json("c")
158        check_basic_value(variable_json, "int", "const uint16_t", "3")
159
160        variable_json = gdb_extract_variable_to_json("d")
161        check_basic_value(variable_json, "int", "const int16_t", "-4")
162
163        variable_json = gdb_extract_variable_to_json("e")
164        check_basic_value(variable_json, "int", "const uint32_t", "5")
165
166        variable_json = gdb_extract_variable_to_json("f")
167        check_basic_value(variable_json, "int", "const int32_t", "-6")
168
169        variable_json = gdb_extract_variable_to_json("g")
170        check_basic_value(variable_json, "int", "const uint64_t", "7")
171
172        variable_json = gdb_extract_variable_to_json("h")
173        check_basic_value(variable_json, "int", "const int64_t", "-8")
174
175        variable_json = gdb_extract_variable_to_json("i")
176        check_basic_value(variable_json, "float", "const float", "9.0")
177
178        variable_json = gdb_extract_variable_to_json("j")
179        check_basic_value(variable_json, "float", "const double", "-10.0")
180
181        variable_json = gdb_extract_variable_to_json("k")
182        check_type_and_ctype(variable_json, "pointer", "const char *")
183        check_basic_value(
184            variable_json["reference"], "int", "const char", "72")
185
186        variable_json = gdb_extract_variable_to_json("l")
187        check_type_and_ctype(variable_json, "pointer", "const void *")
188        assert(variable_json["reference"] == "cannot extract void ptr")
189
190        variable_json = gdb_extract_variable_to_json("m")
191        check_type_and_ctype(variable_json, "pointer", "const char *")
192        assert(variable_json["reference"] == "nullptr")
193
194        variable_json = gdb_extract_variable_to_json("o")
195        check_basic_value(variable_json, "enum", "const Animal", "1")
196
197    def test_objects(self):
198        gdb.execute("file test_examples/objects")
199        gdb.execute("b 37")
200        gdb.execute("r")
201        test_json_variable(self, "objects", 37, ["bar", "foo"])
202
203    def test_objects1(self):
204        gdb.execute("file test_examples/objects1")
205        gdb.execute("b 41")
206        gdb.execute("r")
207        test_json_variable(self, "objects1", 41, ["bar", "foo"])
208
209    def test_objects2(self):
210        gdb.execute("file test_examples/objects2")
211        gdb.execute("b 85")
212        gdb.execute("r")
213        test_json_variable(
214            self,
215            "objects2",
216            85,
217            ["a", "b", "c", "d", "e", "f", "w", "x", "y", "z"])
218
219    def test_array(self):
220        gdb.execute("file test_examples/array")
221        gdb.execute("b 42")
222        gdb.execute("r")
223        test_json_variable(self, "array", 42, ["a", "b", "bar", "foo"])
224
225    def test_reference(self):
226        gdb.execute("file test_examples/reference")
227        gdb.execute("b 41")
228        gdb.execute("r")
229        test_json_variable(
230            self,
231            "reference",
232            41,
233            ["bar", "foo", "bar_ref", "foo_ref", "bar_ptr", "foo_ptr"])
234
235
236unittest.main()
237