1import unittest 2import gdb 3 4 5def get_n(n_str): 6 return int(n_str.split("=")[1].strip()) 7 8 9class HeapMemoryTest(unittest.TestCase): 10 11 def setUp(self): 12 gdb.execute('set pagination on') 13 gdb.execute("file test/sample_heap_test.o") 14 gdb.execute("source heap_print_script.py") 15 gdb.execute("delete") 16 gdb.execute("watch_heap") 17 18 def check_memory(self, n, array_ptr_str, offset=1): 19 """ 20 It is used to test what we got from 'print_ptr' is what we expect. 21 Sample test program allocates array of n int's using malloc and then 22 assigns 1 to n values to that array. So checking that malloc_ptr_str 23 is 1 to n, following big endian size and size of int as 32 bits 24 25 Parameters 26 ---------- 27 n : int 28 array length 29 array_ptr_str : str 30 whole output from print_ptr command including memory content 31 offset : int 32 checking memory content starts from offset value. By default it is 1 33 """ 34 35 data = array_ptr_str.split("\n")[3] 36 bytes_from_heap = data.split(" ") 37 actual_start = offset 38 for i in range(0, n * 4, 4): 39 hex_str = bytes_from_heap[i+3][2:] 40 hex_str += bytes_from_heap[i+2][2:] 41 hex_str += bytes_from_heap[i+1][2:] 42 hex_str += bytes_from_heap[i][2:] 43 int_of_hex = int(hex_str, 16) 44 self.assertEqual(actual_start, int_of_hex) 45 actual_start += 1 46 47 def test_malloc(self): 48 print("malloc test") 49 gdb.execute("b 20") 50 gdb.execute("r") 51 n_str = gdb.execute("print n", to_string=True) 52 n = get_n(n_str) 53 malloc_ptr_array_str = gdb.execute( 54 "print_ptr malloc_ptr", to_string=True) 55 print(malloc_ptr_array_str) 56 self.check_memory(n, malloc_ptr_array_str) 57 self.assertTrue(True) 58 59 def test_realloc(self): 60 print("realloc test") 61 gdb.execute("b 27") 62 gdb.execute("r") 63 new_n = gdb.execute("print new_n", to_string=True) 64 n = get_n(new_n) 65 malloc_ptr_str = gdb.execute("print_ptr malloc_ptr", to_string=True) 66 print(malloc_ptr_str) 67 self.check_memory(n, malloc_ptr_str) 68 69 def test_offset(self): 70 """ 71 Testcase to test raw_pointers that are offset 72 """ 73 74 print("offset test. we have array of 20 (80 bytes) and \ 75 we offset it by 3, so new length should be 68") 76 offset = 3 77 gdb.execute("b 27") 78 gdb.execute("r") 79 new_n = gdb.execute("print new_n", to_string=True) 80 n = get_n(new_n) 81 malloc_ptr_str = gdb.execute( 82 "print_ptr malloc_ptr + {}".format(offset), to_string=True) 83 print(malloc_ptr_str) 84 self.check_memory(n - offset, malloc_ptr_str, offset+1) 85 86 def test_free(self): 87 print("free test") 88 gdb.execute("b 28") 89 gdb.execute("r") 90 malloc_ptr_str = gdb.execute("print_ptr malloc_ptr", to_string=True) 91 data = malloc_ptr_str.split("\n")[2].strip() 92 self.assertEqual(data, "No address mapping found!") 93 94 def test_new(self): 95 print("operator new[] test") 96 gdb.execute("b 41") 97 gdb.execute("r") 98 n_str = gdb.execute("print n", to_string=True) 99 n = get_n(n_str) 100 new_ptr_array_str = gdb.execute("print_ptr new_ptr", to_string=True) 101 self.check_memory(n, new_ptr_array_str) 102 103 def test_delete(self): 104 print("operator delete[]") 105 gdb.execute("b 42") 106 gdb.execute("r") 107 new_ptr_array_str = gdb.execute("print_ptr new_ptr", to_string=True) 108 data = new_ptr_array_str.split("\n")[2].strip() 109 self.assertEqual(data, "No address mapping found!") 110 111 112if __name__ == '__main__': 113 unittest.main() 114