renode/renode

Save statefile inside a Hook (it hangs) via python script

asmitaj08 opened this issue · 3 comments

Hi,
I am trying to save the state inside the cpu Hook which occurs when the main function is reached. Trying on nrf52840 zephyr-shell sample example. Here is the code :

# !/usr/bin/env -S python3 -m bpython -i
import time
from pyrenode3 import RPath
import System   # import sys
from pyrenode3.wrappers import Analyzer, Emulation, Monitor
from Antmicro.Renode.Peripherals.CPU import ICpuSupportingGdb
state_file= "statefile.dat"
e = Emulation()
m = Monitor()
# Tetsing for nrf52840.resc
mach = e.add_mach("nrf52840")
mach.load_repl("platforms/cpus/nrf52840.repl")
mach.load_elf("https://dl.antmicro.com/projects/renode/renode-nrf52840-zephyr_shell_module.elf-gf8d05cf-s_1310072-c00fbffd6b65c6238877c4fe52e8228c2a38bf1f")

pc_main = mach.sysbus.GetSymbolAddress("main")
print(f"Main func addr : {hex(pc_main)}")

def hook_addr_main(cpu, addr):
    print(f'Inside main hook. state_file_name : {state_file}')
    # mach.sysbus.cpu.Pause()
    m.execute(f"Save @{state_file}")
    print("machine paused at main, and state saved")
    
Action1 = getattr(System, 'Action`2')
hook_action_main = Action1[ICpuSupportingGdb, System.UInt64](hook_addr_main)
mach.sysbus.cpu.AddHook(pc_main,hook_action_main)
Analyzer(mach.sysbus.uart0).Show()
e.StartAll()
time.sleep(1)
mach.sysbus.cpu.RemoveHooksAt(pc_main)
m.execute("Clear")
print("cleared previous mach")
time.sleep(1)
print("Loading the saved file")
m.execute(f"Load @{state_file}")
nrf52840 = e.get_mach("nrf52840")
print(f"***Mach here : {nrf52840}")
Analyzer(nrf52840.sysbus.uart0).Show()
e.StartAll()
print("Done")
input()

In this case, it just hangs inside Hook. But if I execute Save statefile outside hook , it works ok. Any suggestions?
Thanks !

Hi,
I referred Load and Save feature - https://renode.readthedocs.io/en/latest/basic/saving.html
I was wondering if there is any other way to do it via Python, instead of m.execute(f"Save @{state_file}") ?
Thanks!

I tried EmulationManager.Instance.Save(state_file), but same issue. It just hangs when I do it inside the hook. Unable to figure out. Or is there any other way in which I can save the resister context (snapshot) at a particular address ?
Also, I tried doing it differently, i.e. saving the sate outside based on the flag which is enabled inside the hook. Like :

while reach_target_flag == 0:
    pass
if reach_target_flag == 1:
    mach.sysbus.cpu.Pause()
    try:
        EmulationManager.Instance.Save(state_file)
        print(f"Save command executed: Save @{state_file}")
    except Exception as e:
         print(f"Error executing save command: {e}")
    print("reached flag")
    reach_target_flag = 0

Where reach_target_flag is set inside hook. But it gives me error :
Error executing save command: Error encountered during saving: Pointer or ThreadLocal or SpinLock encountered during serialization.

Some help/suggestions would be appreciated. Thank you!

Able to solve after I removed the Hook, after the flag is set in the 2nd approach.