| import unittest |
| import gdb |
| |
| |
| def get_n(n_str): |
| return int(n_str.split("=")[1].strip()) |
| |
| |
| class HeapMemoryTest(unittest.TestCase): |
| |
| def setUp(self): |
| gdb.execute('set pagination on') |
| gdb.execute("file test/sample_heap_test.o") |
| gdb.execute("source heap_print_script.py") |
| gdb.execute("delete") |
| gdb.execute("watch_heap") |
| |
| def check_memory(self, n, array_ptr_str, offset=1): |
| """ |
| It is used to test what we got from 'print_ptr' is what we expect. |
| Sample test program allocates array of n int's using malloc and then |
| assigns 1 to n values to that array. So checking that malloc_ptr_str |
| is 1 to n, following big endian size and size of int as 32 bits |
| |
| Parameters |
| ---------- |
| n : int |
| array length |
| array_ptr_str : str |
| whole output from print_ptr command including memory content |
| offset : int |
| checking memory content starts from offset value. By default it is 1 |
| """ |
| |
| data = array_ptr_str.split("\n")[3] |
| bytes_from_heap = data.split(" ") |
| actual_start = offset |
| for i in range(0, n * 4, 4): |
| hex_str = bytes_from_heap[i+3][2:] |
| hex_str += bytes_from_heap[i+2][2:] |
| hex_str += bytes_from_heap[i+1][2:] |
| hex_str += bytes_from_heap[i][2:] |
| int_of_hex = int(hex_str, 16) |
| self.assertEqual(actual_start, int_of_hex) |
| actual_start += 1 |
| |
| def test_malloc(self): |
| print("malloc test") |
| gdb.execute("b 20") |
| gdb.execute("r") |
| n_str = gdb.execute("print n", to_string=True) |
| n = get_n(n_str) |
| malloc_ptr_array_str = gdb.execute( |
| "print_ptr malloc_ptr", to_string=True) |
| print(malloc_ptr_array_str) |
| self.check_memory(n, malloc_ptr_array_str) |
| self.assertTrue(True) |
| |
| def test_realloc(self): |
| print("realloc test") |
| gdb.execute("b 27") |
| gdb.execute("r") |
| new_n = gdb.execute("print new_n", to_string=True) |
| n = get_n(new_n) |
| malloc_ptr_str = gdb.execute("print_ptr malloc_ptr", to_string=True) |
| print(malloc_ptr_str) |
| self.check_memory(n, malloc_ptr_str) |
| |
| def test_offset(self): |
| """ |
| Testcase to test raw_pointers that are offset |
| """ |
| |
| print("offset test. we have array of 20 (80 bytes) and \ |
| we offset it by 3, so new length should be 68") |
| offset = 3 |
| gdb.execute("b 27") |
| gdb.execute("r") |
| new_n = gdb.execute("print new_n", to_string=True) |
| n = get_n(new_n) |
| malloc_ptr_str = gdb.execute( |
| "print_ptr malloc_ptr + {}".format(offset), to_string=True) |
| print(malloc_ptr_str) |
| self.check_memory(n - offset, malloc_ptr_str, offset+1) |
| |
| def test_free(self): |
| print("free test") |
| gdb.execute("b 28") |
| gdb.execute("r") |
| malloc_ptr_str = gdb.execute("print_ptr malloc_ptr", to_string=True) |
| data = malloc_ptr_str.split("\n")[2].strip() |
| self.assertEqual(data, "No address mapping found!") |
| |
| def test_new(self): |
| print("operator new[] test") |
| gdb.execute("b 41") |
| gdb.execute("r") |
| n_str = gdb.execute("print n", to_string=True) |
| n = get_n(n_str) |
| new_ptr_array_str = gdb.execute("print_ptr new_ptr", to_string=True) |
| self.check_memory(n, new_ptr_array_str) |
| |
| def test_delete(self): |
| print("operator delete[]") |
| gdb.execute("b 42") |
| gdb.execute("r") |
| new_ptr_array_str = gdb.execute("print_ptr new_ptr", to_string=True) |
| data = new_ptr_array_str.split("\n")[2].strip() |
| self.assertEqual(data, "No address mapping found!") |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |