blob: dd6b40e13f755d743ef41e985e4877cc63b5cefe [file] [log] [blame]
# Copyright 2020 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import gdb
import json
def remove_gdb_output_prefix(str):
""" gdb output contains a "$%d =" prefix, the function remove the prefix
"""
idx = str.find("=")
return str[idx + 1:]
def check_type_and_ctype(input_json, input_type, ctype):
assert(input_json["type"] == input_type)
assert(input_json["ctype"] == ctype)
def check_basic_value(input_json, input_type, ctype, value):
check_type_and_ctype(input_json, input_type, ctype)
assert(input_json["value"] == value)
def gdb_extract_variable_to_json(variable_name):
""" extract a variable from gdb
Args:
variable_name:
a string, the name of the variable to extract
Returns:
A json Object in Python
"""
variable = gdb.execute("p {}".format(variable_name), to_string=True)
variable = remove_gdb_output_prefix(variable)
variable_json = json.loads(variable)
return variable_json
def json_equal_except_address(testcase, json0, json1):
""" check if all content of two json are same except the address fields
The function will check the two json objects recursively to set address fields to None,
then convert two json objects into strings with sorted keys, and check if the two strings
are same.
"""
def replace_address_by_None(input_json):
if isinstance(input_json, dict):
for (k, v) in input_json.items():
if k == "address":
input_json[k] = None
else:
replace_address_by_None(v)
elif isinstance(input_json, list):
for item in input_json:
replace_address_by_None(item)
replace_address_by_None(json0)
replace_address_by_None(json1)
json0 = json.dumps(json0, sort_keys=True)
json1 = json.dumps(json1, sort_keys=True)
testcase.assertEqual(json0, json1)
def test_json_variable(testcase, testname, line, variable_name_list):
for variable_name in variable_name_list:
variable_json = gdb_extract_variable_to_json(variable_name)
with open("test/{}_{}_{}.json".format(testname, str(line), variable_name), "r") as f:
expect_variable = json.load(f)
json_equal_except_address(testcase, variable_json, expect_variable)
class TestGdbJsonPrinter(unittest.TestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.maxDiff = None
def test_basic_types(self):
gdb.execute("file test_examples/basic_types")
gdb.execute("b 42")
gdb.execute("r")
variable_json = gdb_extract_variable_to_json("a")
check_basic_value(variable_json, "int", "uint8_t", "1")
variable_json = gdb_extract_variable_to_json("a")
check_basic_value(variable_json, "int", "uint8_t", "1")
variable_json = gdb_extract_variable_to_json("b")
check_basic_value(variable_json, "int", "int8_t", "-2")
variable_json = gdb_extract_variable_to_json("c")
check_basic_value(variable_json, "int", "uint16_t", "3")
variable_json = gdb_extract_variable_to_json("d")
check_basic_value(variable_json, "int", "int16_t", "-4")
variable_json = gdb_extract_variable_to_json("e")
check_basic_value(variable_json, "int", "uint32_t", "5")
variable_json = gdb_extract_variable_to_json("f")
check_basic_value(variable_json, "int", "int32_t", "-6")
variable_json = gdb_extract_variable_to_json("g")
check_basic_value(variable_json, "int", "uint64_t", "7")
variable_json = gdb_extract_variable_to_json("h")
check_basic_value(variable_json, "int", "int64_t", "-8")
variable_json = gdb_extract_variable_to_json("i")
check_basic_value(variable_json, "float", "float", "9.0")
variable_json = gdb_extract_variable_to_json("j")
check_basic_value(variable_json, "float", "double", "-10.0")
variable_json = gdb_extract_variable_to_json("k")
check_type_and_ctype(variable_json, "pointer", "const char *")
check_basic_value(
variable_json["reference"], "int", "const char", "72")
variable_json = gdb_extract_variable_to_json("l")
check_type_and_ctype(variable_json, "pointer", "void *")
assert(variable_json["reference"] == "cannot extract void ptr")
variable_json = gdb_extract_variable_to_json("m")
check_type_and_ctype(variable_json, "pointer", "char *")
assert(variable_json["reference"] == "nullptr")
variable_json = gdb_extract_variable_to_json("o")
check_basic_value(variable_json, "enum", "Animal", "0")
gdb.execute("b 61")
gdb.execute("c")
variable_json = gdb_extract_variable_to_json("a")
check_basic_value(variable_json, "int", "const uint8_t", "1")
variable_json = gdb_extract_variable_to_json("a")
check_basic_value(variable_json, "int", "const uint8_t", "1")
variable_json = gdb_extract_variable_to_json("b")
check_basic_value(variable_json, "int", "const int8_t", "-2")
variable_json = gdb_extract_variable_to_json("c")
check_basic_value(variable_json, "int", "const uint16_t", "3")
variable_json = gdb_extract_variable_to_json("d")
check_basic_value(variable_json, "int", "const int16_t", "-4")
variable_json = gdb_extract_variable_to_json("e")
check_basic_value(variable_json, "int", "const uint32_t", "5")
variable_json = gdb_extract_variable_to_json("f")
check_basic_value(variable_json, "int", "const int32_t", "-6")
variable_json = gdb_extract_variable_to_json("g")
check_basic_value(variable_json, "int", "const uint64_t", "7")
variable_json = gdb_extract_variable_to_json("h")
check_basic_value(variable_json, "int", "const int64_t", "-8")
variable_json = gdb_extract_variable_to_json("i")
check_basic_value(variable_json, "float", "const float", "9.0")
variable_json = gdb_extract_variable_to_json("j")
check_basic_value(variable_json, "float", "const double", "-10.0")
variable_json = gdb_extract_variable_to_json("k")
check_type_and_ctype(variable_json, "pointer", "const char *")
check_basic_value(
variable_json["reference"], "int", "const char", "72")
variable_json = gdb_extract_variable_to_json("l")
check_type_and_ctype(variable_json, "pointer", "const void *")
assert(variable_json["reference"] == "cannot extract void ptr")
variable_json = gdb_extract_variable_to_json("m")
check_type_and_ctype(variable_json, "pointer", "const char *")
assert(variable_json["reference"] == "nullptr")
variable_json = gdb_extract_variable_to_json("o")
check_basic_value(variable_json, "enum", "const Animal", "1")
def test_objects(self):
gdb.execute("file test_examples/objects")
gdb.execute("b 37")
gdb.execute("r")
test_json_variable(self, "objects", 37, ["bar", "foo"])
def test_objects1(self):
gdb.execute("file test_examples/objects1")
gdb.execute("b 41")
gdb.execute("r")
test_json_variable(self, "objects1", 41, ["bar", "foo"])
def test_objects2(self):
gdb.execute("file test_examples/objects2")
gdb.execute("b 85")
gdb.execute("r")
test_json_variable(
self,
"objects2",
85,
["a", "b", "c", "d", "e", "f", "w", "x", "y", "z"])
def test_array(self):
gdb.execute("file test_examples/array")
gdb.execute("b 42")
gdb.execute("r")
test_json_variable(self, "array", 42, ["a", "b", "bar", "foo"])
def test_reference(self):
gdb.execute("file test_examples/reference")
gdb.execute("b 41")
gdb.execute("r")
test_json_variable(
self,
"reference",
41,
["bar", "foo", "bar_ref", "foo_ref", "bar_ptr", "foo_ptr"])
unittest.main()