如何用Python版LLDB库正确打印C程序main函数的char** argv
问题:Python版LLDB API无法读取C程序main函数的argv[1]及之后的参数
在Xcode中启动C程序并停在main(int argc, char **argv)入口时,使用LLDB命令p argv[0]和p argv[1]能正常打印对应参数字符串,但通过Python版LLDB API尝试读取时遇到问题:
- 手动编写的打印函数无法获取第二个输入字符串
- 使用
argv.GetChildAtIndex时,索引0有效,但索引1、2均无效 - 手动计算地址偏移的方式也未成功(已通过C程序确认输入参数确实存在)
尝试的代码
打印argv的函数
def print_argv(argv: lldb.SBValue, target:SBTarget): pointer = argv.Dereference() summary = pointer.GetSummary().strip('\\"') print(summary) str_len = len(summary) next_str_address:int = pointer.GetLoadAddress() + str_len + 1 pointer_type = pointer.GetType() addr = SBAddress(next_str_address, target) next_value = target.CreateValueFromAddress("argv", addr, pointer_type) summary = next_value.GetSummary().strip('\\"')
调试调用代码
debugger = lldb.SBDebugger.Create() debugger.SetAsync(False) target = debugger.CreateTargetWithFileAndArch (str(binary_path), lldb.LLDB_ARCH_DEFAULT) assert target, "Failed to create target" target.BreakpointCreateByName ("main", target.GetExecutable().GetFilename()) launch_info = lldb.SBLaunchInfo(str_args) launch_info.SetWorkingDirectory(os.getcwd()) error = lldb.SBError() process = target.Launch(launch_info, error) assert process, "Failed to launch process" for _ in range(1000):# Putting an upper limit on the number of functions to trace state = process.GetState() if state == lldb.eStateStopped: for thread in process: frame = thread.frames[0] function_name = frame.GetFunctionName() if function_name in function_names: for arg in frame.arguments: if arg.name == "argv": print_argv(arg, 3, target) process.Continue()
解决方案
问题出在GetChildAtIndex的调用参数上,需要将第三个参数can_create_synthetic设为True,让LLDB创建合成值来访问指针数组的后续元素:
child = argv.GetChildAtIndex(1, lldb.eNoDynamicValues, True)
因为char** argv本质是指向指针数组的指针,LLDB默认不会自动解析数组的后续元素,开启can_create_synthetic=True后,LLDB会生成对应的合成数组视图,从而允许通过索引访问argv[1]、argv[2]等参数。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

