@@ -162,24 +162,50 @@ def load(address, size=4):
162162 def load_pointer (address ):
163163 return struct .unpack ("<I" , load (address ))[0 ]
164164
165- heap_start , heap_size = symbols ["heap" ]
165+ if "heap" in symbols :
166+ heap_start , heap_size = symbols ["heap" ]
167+ else :
168+ print ("no static heap" )
169+ allocations_start , allocations_size = symbols ["allocations" ]
170+ allocations = load (allocations_start , allocations_size )
171+ first_zero = True
172+ potential_heap = None
173+ # The heap is the last left hand allocated section that should span all the way to the
174+ # right side list.
175+ for address , size in struct .iter_unpack ("<II" , allocations ):
176+ print (address , size )
177+ if address == 0 and first_zero :
178+ first_zero = False
179+ if first_zero :
180+ potential_heap = (address , size )
181+
182+ if not first_zero and address != 0 :
183+ if address != potential_heap [0 ] + potential_heap [1 ]:
184+ print ("no active heap" )
185+ return
186+ else :
187+ heap_start , heap_size = potential_heap
188+ break
189+ print ("found heap" , heap_start , heap_size )
166190 heap = load (heap_start , heap_size )
167191 total_byte_len = len (heap )
168192
169193 # These change every run so we load them from the symbol table
170194 mp_state_ctx = symbols ["mp_state_ctx" ][0 ]
171195 manual_symbol_map ["mp_state_ctx+20" ] = "mp_state_ctx.vm.last_pool"
172196 last_pool = load_pointer (mp_state_ctx + 20 ) # (gdb) p &mp_state_ctx.vm.last_pool
173- manual_symbol_map ["mp_state_ctx+104 " ] = "mp_state_ctx.vm.dict_main.map.table"
174- dict_main_table = load_pointer (mp_state_ctx + 104 ) # (gdb) p &mp_state_ctx.vm.dict_main.map.table
197+ manual_symbol_map ["mp_state_ctx+108 " ] = "mp_state_ctx.vm.dict_main.map.table"
198+ dict_main_table = load_pointer (mp_state_ctx + 108 ) # (gdb) p &mp_state_ctx.vm.dict_main.map.table
175199 manual_symbol_map ["mp_state_ctx+84" ] = "mp_state_ctx.vm.mp_loaded_modules_dict.map.table"
176200 imports_table = load_pointer (mp_state_ctx + 84 ) # (gdb) p &mp_state_ctx.vm.mp_loaded_modules_dict.map.table
177201
178- manual_symbol_map ["mp_state_ctx+120" ] = "mp_state_ctx.vm.mp_sys_path_obj.items"
179- manual_symbol_map ["mp_state_ctx+136" ] = "mp_state_ctx.vm.mp_sys_argv_obj.items"
202+ manual_symbol_map ["mp_state_ctx+124" ] = "mp_state_ctx.vm.mp_sys_path_obj.items"
203+ manual_symbol_map ["mp_state_ctx+140" ] = "mp_state_ctx.vm.mp_sys_argv_obj.items"
204+ manual_symbol_map ["mp_state_ctx+96" ] = "mp_state_ctx.vm.dict_main"
205+ manual_symbol_map ["0x200015e0" ] = "mp_state_ctx.vm.dict_main"
180206
181207 for i in range (READLINE_HIST_SIZE ):
182- manual_symbol_map ["mp_state_ctx+{}" .format (144 + i * 4 )] = "mp_state_ctx.vm.readline_hist[{}]" .format (i )
208+ manual_symbol_map ["mp_state_ctx+{}" .format (148 + i * 4 )] = "mp_state_ctx.vm.readline_hist[{}]" .format (i )
183209
184210 tuple_type = symbols ["mp_type_tuple" ][0 ]
185211 type_type = symbols ["mp_type_type" ][0 ]
@@ -192,6 +218,8 @@ def load_pointer(address):
192218
193219 dynamic_type = 0x40000000 # placeholder, doesn't match any memory
194220
221+ long_lived_start = load_pointer (mp_state_ctx + 272 ) # (gdb) p &mp_state_ctx.mem.gc_lowest_long_lived_ptr
222+
195223 type_colors = {
196224 dict_type : "red" ,
197225 property_type : "yellow" ,
@@ -252,9 +280,14 @@ def save_allocated_block(end, current_allocation):
252280 table = "<<table bgcolor=\" gray\" border=\" 1\" cellpadding=\" 0\" cellspacing=\" 0\" ><tr><td colspan=\" 4\" port=\" 0\" height=\" 18\" width=\" 80\" >0x{:08x}</td></tr>{}</table>>" .format (address , rows )
253281
254282 ownership_graph .add_node (address , label = table , style = "invisible" , shape = "plaintext" )
283+ print ("add 0x{:08x}" .format (address ))
255284 potential_type = None
256285 node = ownership_graph .get_node (address )
257286 node .attr ["height" ] = 0.25 * current_allocation
287+ if address >= long_lived_start :
288+ node .attr ["fontcolor" ] = "hotpink"
289+ else :
290+ node .attr ["fontcolor" ] = "black"
258291 block_data [address ] = data
259292 for k in range (len (data ) // 4 ):
260293 word = struct .unpack_from ("<I" , data , offset = (k * 4 ))[0 ]
@@ -270,6 +303,7 @@ def save_allocated_block(end, current_allocation):
270303 bgcolor = type_colors [potential_type ]
271304 elif print_unknown_types :
272305 print ("unknown type" , hex (potential_type ))
306+
273307 node .attr ["label" ] = "<" + node .attr ["label" ].replace ("\" gray\" " , "\" " + bgcolor + "\" " ) + ">"
274308
275309 if potential_type == str_type and k == 3 :
@@ -285,7 +319,7 @@ def save_allocated_block(end, current_allocation):
285319 if k < 4 :
286320 port = 0
287321 ownership_graph .add_edge (address , word , tailport = str (port )+ ":_" )
288- # print(" 0x{:08x}".format(word))
322+ print (" 0x{:08x}" .format (word ))
289323 if address in qstr_pools :
290324 if k > 0 :
291325 qstr_chunks .append (word )
@@ -421,6 +455,7 @@ def format(obj):
421455 node .attr ["label" ] = "<<table bgcolor=\" gold\" border=\" 1\" cellpadding=\" 0\" cellspacing=\" 0\" ><tr><td colspan=\" 2\" >0x{:08x}</td></tr>{}</table>>" .format (block , rows )
422456
423457 for node , degree in ownership_graph .in_degree_iter ():
458+ print (node , degree )
424459 if degree == 0 :
425460 address_bytes = struct .pack ("<I" , int (node ))
426461 location = - 1
@@ -434,6 +469,8 @@ def format(obj):
434469 source = manual_symbol_map [source ]
435470 if "readline_hist" in source :
436471 string_blocks .append (int (node ))
472+ if pointer_location > heap_start + heap_size :
473+ source = "stack " + source
437474 ownership_graph .add_edge (source , node )
438475
439476 for block in string_blocks :
@@ -517,7 +554,11 @@ def format(obj):
517554 wrapped .append (html .escape (printable_qstrs [i :i + 16 ]))
518555 node = ownership_graph .get_node (block )
519556 node .attr ["label" ] = "<<table border=\" 1\" cellspacing=\" 0\" bgcolor=\" lightsalmon\" width=\" 80\" ><tr><td height=\" 18\" >0x{:08x}</td></tr><tr><td height=\" {}\" >{}</td></tr></table>>" .format (block , 18 * (len (wrapped ) - 1 ), "<br/>" .join (wrapped ))
520- node .attr ["fontname" ] = "FiraCode-Medium"
557+ node .attr ["fontname" ] = "FiraCode-Bold"
558+ if block >= long_lived_start :
559+ node .attr ["fontcolor" ] = "hotpink"
560+ else :
561+ node .attr ["fontcolor" ] = "black"
521562 node .attr ["fontpath" ] = "/Users/tannewt/Library/Fonts/"
522563 node .attr ["fontsize" ] = 8
523564
0 commit comments