11605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen""" 2b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny ChenThis LLDB module contains miscellaneous utilities. 330e4850a3f4687cab5b2465125072d5658786efaJohnny ChenSome of the test suite takes advantage of the utility functions defined here. 430e4850a3f4687cab5b2465125072d5658786efaJohnny ChenThey can also be useful for general purpose lldb scripting. 51605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen""" 61605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 71605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chenimport lldb 80bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chenimport os, sys 9ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chenimport StringIO 101605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 118a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# =================================================== 128a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# Utilities for locating/checking executable programs 138a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# =================================================== 14979cb5da1f9aee5d23d8facfb7d5a781406cca28Johnny Chen 150bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef is_exe(fpath): 16efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen """Returns True if fpath is an executable.""" 170bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 180bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen 190bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef which(program): 20efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen """Returns the full path to a program; None otherwise.""" 210bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen fpath, fname = os.path.split(program) 220bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if fpath: 230bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if is_exe(program): 240bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return program 250bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen else: 260bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen for path in os.environ["PATH"].split(os.pathsep): 270bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen exe_file = os.path.join(path, program) 280bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if is_exe(exe_file): 290bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return exe_file 300bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return None 310bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen 3251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# =================================================== 3351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# Disassembly for an SBFunction or an SBSymbol object 3451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# =================================================== 3551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 3651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chendef disassemble(target, function_or_symbol): 3751ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen """Disassemble the function or symbol given a target. 3851ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 3951ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen It returns the disassembly content in a string object. 4051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen """ 4151ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen buf = StringIO.StringIO() 4251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen insts = function_or_symbol.GetInstructions(target) 43d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen for i in insts: 4451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen print >> buf, i 4551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen return buf.getvalue() 4651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 474c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ========================================================== 484c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# Integer (byte size 1, 2, 4, and 8) to bytearray conversion 494c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ========================================================== 504c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 514c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef int_to_bytearray(val, bytesize): 524c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """Utility function to convert an integer into a bytearray. 534c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 54d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen It returns the bytearray in the little endian format. It is easy to get the 55d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen big endian format, just do ba.reverse() on the returned object. 564c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """ 57f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen import struct 584c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 594c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 1: 604c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return bytearray([val]) 614c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 624c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen # Little endian followed by a format character. 634c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen template = "<%c" 644c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 2: 654c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'h' 664c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 674c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'i' 684c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 694c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'q' 704c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen else: 714c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return None 724c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 73f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen packed = struct.pack(fmt, val) 744c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return bytearray(map(ord, packed)) 754c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 764c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef bytearray_to_int(bytes, bytesize): 774c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """Utility function to convert a bytearray into an integer. 784c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 79d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen It interprets the bytearray in the little endian format. For a big endian 80d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen bytearray, just do ba.reverse() on the object before passing it in. 814c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """ 82f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen import struct 834c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 844c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 1: 851ee6d9f49ca2e806197c2c6d7fa85e143b74da59Filipe Cabecinhas return bytes[0] 864c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 874c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen # Little endian followed by a format character. 884c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen template = "<%c" 894c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 2: 904c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'h' 914c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 924c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'i' 934c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 944c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'q' 954c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen else: 964c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return None 974c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 98f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen unpacked = struct.unpack(fmt, str(bytes)) 994c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return unpacked[0] 1004c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 1014c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 102bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 103bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# Get the description of an lldb object or None if not available 104bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 105bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chendef get_description(obj, option=None): 106bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """Calls lldb_obj.GetDescription() and returns a string, or None. 107bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 108ecd4feb5111432d2878e95461220c720cb2d24c8Johnny Chen For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra 109ecd4feb5111432d2878e95461220c720cb2d24c8Johnny Chen option can be passed in to describe the detailed level of description 110ecd4feb5111432d2878e95461220c720cb2d24c8Johnny Chen desired: 111bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelBrief 112bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelFull 113bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelVerbose 114bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """ 115bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen method = getattr(obj, 'GetDescription') 116bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not method: 117bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 118ecd4feb5111432d2878e95461220c720cb2d24c8Johnny Chen tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint) 1198a0d8971ba98e562091d3281620a5254048050a1Johnny Chen if isinstance(obj, tuple): 120bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen if option is None: 121bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen option = lldb.eDescriptionLevelBrief 122bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 123bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen stream = lldb.SBStream() 124bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if option is None: 125bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream) 126bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen else: 127bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream, option) 128bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not success: 129bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 130bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return stream.GetData() 131bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 132bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 133168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 134168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart 135168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 136be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 13747342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef state_type_to_str(enum): 138be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stateType string given an enum.""" 139be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStateInvalid: 14059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 141be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateUnloaded: 14259b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "unloaded" 14342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen elif enum == lldb.eStateConnected: 14442da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen return "connected" 145be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateAttaching: 14659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "attaching" 147be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateLaunching: 14859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "launching" 149be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStopped: 15059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stopped" 151be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateRunning: 15259b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "running" 153be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStepping: 15459b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stepping" 155be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateCrashed: 15659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "crashed" 157be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateDetached: 15859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "detached" 159be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateExited: 16059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exited" 161be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateSuspended: 16259b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "suspended" 163be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 16442da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StateType enum") 165be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 16647342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef stop_reason_to_str(enum): 167be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stopReason string given an enum.""" 168be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStopReasonInvalid: 16959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 170be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonNone: 17159b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "none" 172be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonTrace: 17359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "trace" 174be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonBreakpoint: 17559b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "breakpoint" 176be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonWatchpoint: 17759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "watchpoint" 178be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonSignal: 17959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "signal" 180be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonException: 18159b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exception" 182be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonPlanComplete: 18359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "plancomplete" 184ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea elif enum == lldb.eStopReasonThreadExiting: 185ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea return "threadexiting" 186be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 18742da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StopReason enum") 188be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 189e70826104d551d48c5af91f56f9ed3937af14870Johnny Chendef symbol_type_to_str(enum): 190e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen """Returns the symbolType string given an enum.""" 191e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen if enum == lldb.eSymbolTypeInvalid: 192e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "invalid" 193e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeAbsolute: 194e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "absolute" 195e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeCode: 196e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "code" 197e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeData: 198e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "data" 199e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeTrampoline: 200e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "trampoline" 201e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeRuntime: 202e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "runtime" 203e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeException: 204e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "exception" 205e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeSourceFile: 206e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "sourcefile" 207e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeHeaderFile: 208e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "headerfile" 209e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeObjectFile: 210e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "objectfile" 211e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeCommonBlock: 212e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "commonblock" 213e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeBlock: 214e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "block" 215e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeLocal: 216e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "local" 217e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeParam: 218e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "param" 219e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeVariable: 220e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "variable" 221e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeVariableType: 222e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "variabletype" 223e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeLineEntry: 224e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "lineentry" 225e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeLineHeader: 226e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "lineheader" 227e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeScopeBegin: 228e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "scopebegin" 229e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeScopeEnd: 230e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "scopeend" 231e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeAdditional: 232e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "additional" 233e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeCompiler: 234e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "compiler" 235e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeInstrumentation: 236e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "instrumentation" 237e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen elif enum == lldb.eSymbolTypeUndefined: 238e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen return "undefined" 239e70826104d551d48c5af91f56f9ed3937af14870Johnny Chen 24047342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef value_type_to_str(enum): 2412c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen """Returns the valueType string given an enum.""" 2422c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen if enum == lldb.eValueTypeInvalid: 2432c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "invalid" 2442c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableGlobal: 2452c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "global_variable" 2462c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableStatic: 2472c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "static_variable" 2482c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableArgument: 2492c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "argument_variable" 2502c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableLocal: 2512c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "local_variable" 2522c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegister: 2532c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register" 2542c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegisterSet: 2552c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register_set" 2562c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeConstResult: 2572c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "constant_result" 2582c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen else: 25942da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown ValueType enum") 2602c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen 261be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 262168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 263ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea# Get stopped threads due to each stop reason. 264ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea# ================================================== 265ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea 266ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Maleadef sort_stopped_threads(process, 267ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea breakpoint_threads = None, 268ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea crashed_threads = None, 269ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea watchpoint_threads = None, 270ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea signal_threads = None, 271ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea exiting_threads = None, 272ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea other_threads = None): 273ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea """ Fills array *_threads with threads stopped for the corresponding stop 274ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea reason. 275ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea """ 276ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea for lst in [breakpoint_threads, 277ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea watchpoint_threads, 278ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea signal_threads, 279ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea exiting_threads, 280ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea other_threads]: 281ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea if lst is not None: 282ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea lst[:] = [] 283ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea 284ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea for thread in process: 285ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea dispatched = False 286ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads), 287ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea (lldb.eStopReasonException, crashed_threads), 288ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea (lldb.eStopReasonWatchpoint, watchpoint_threads), 289ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea (lldb.eStopReasonSignal, signal_threads), 290ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea (lldb.eStopReasonThreadExiting, exiting_threads), 291ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea (None, other_threads)]: 292ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea if not dispatched and list is not None: 293ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea if thread.GetStopReason() == reason or reason is None: 294ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea list.append(thread) 295ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea dispatched = True 296ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea 297ff5c6d9c07c02c80b24a59c25d9f5edd518479c4Daniel Malea# ================================================== 298431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham# Utility functions for setting breakpoints 299431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham# ================================================== 300431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 301431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_by_file_and_line (test, file_name, line_number, extra_options = None, num_expected_locations = 1, loc_exact=False, module_name=None): 302431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Set a breakpoint by file and line, returning the breakpoint number. 303431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 304431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham If extra_options is not None, then we append it to the breakpoint set command. 305431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 306431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham If num_expected_locations is -1 we check that we got AT LEAST one location, otherwise we check that num_expected_locations equals the number of locations. 307431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 308431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham If loc_exact is true, we check that there is one location, and that location must be at the input file and line number.""" 309431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 310431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if file_name == None: 311431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command = 'breakpoint set -l %d'%(line_number) 312431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 313431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number) 314431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 3152fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton if module_name: 3162fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton command += " --shlib '%s'" % (module_name) 3172fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton 318431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if extra_options: 319431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command += " " + extra_options 320431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 321431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = run_break_set_command (test, command) 322431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 323431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if num_expected_locations == 1 and loc_exact: 324431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name) 325431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 326431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations = num_expected_locations) 327431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 328431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return get_bpno_from_match (break_results) 329431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 330431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None): 331431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line. 332431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 333431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match.""" 334431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command = 'breakpoint set -n "%s"'%(symbol) 3352fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton 3362fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton if module_name: 3372fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton command += " --shlib '%s'" % (module_name) 3382fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton 339431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if extra_options: 340431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command += " " + extra_options 341431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 342431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = run_break_set_command (test, command) 343431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 344431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if num_expected_locations == 1 and sym_exact: 345431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name) 346431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 347431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations = num_expected_locations) 348431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 349431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return get_bpno_from_match (break_results) 350431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 351431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None): 352431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line.""" 353431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 3542fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton command = 'breakpoint set -S "%s"' % (selector) 3552fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton 3562fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton if module_name: 3572fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton command += ' --shlib "%s"' % (module_name) 3582fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton 359431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if extra_options: 360431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command += " " + extra_options 361431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 362431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = run_break_set_command (test, command) 363431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 364431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if num_expected_locations == 1: 365431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name) 366431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 367431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations = num_expected_locations) 368431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 369431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return get_bpno_from_match (break_results) 370431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 371431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_by_regexp (test, regexp, extra_options=None, num_expected_locations=-1): 372431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line.""" 373431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 374431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command = 'breakpoint set -r "%s"'%(regexp) 375431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if extra_options: 376431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command += " " + extra_options 377431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 378431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = run_break_set_command (test, command) 379431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 380431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations=num_expected_locations) 381431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 382431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return get_bpno_from_match (break_results) 383431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 384431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1): 385431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line.""" 386431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command = 'breakpoint set -p "%s"'%(regexp) 387431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if extra_options: 388431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham command += " " + extra_options 389431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 390431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = run_break_set_command (test, command) 391431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 392431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham check_breakpoint_result (test, break_results, num_locations=num_expected_locations) 393431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 394431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return get_bpno_from_match (break_results) 395431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 396431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef run_break_set_command (test, command): 397431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham """Run the command passed in - it must be some break set variant - and analyze the result. 398431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham Returns a dictionary of information gleaned from the command-line results. 399431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham Will assert if the breakpoint setting fails altogether. 400431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 401431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham Dictionary will contain: 402431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham bpno - breakpoint of the newly created breakpoint, -1 on error. 403431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham num_locations - number of locations set for the breakpoint. 404431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 405431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham If there is only one location, the dictionary MAY contain: 406431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham file - source file name 407431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham line_no - source line number 408431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham symbol - symbol name 409431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham inline_symbol - inlined symbol name 410431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham offset - offset from the original symbol 411431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham module - module 412431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham address - address at which the breakpoint was set.""" 413431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 414431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$", 415431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.", 416431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+), address = (?P<address>0x[0-9a-fA-F]+)$", 417431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"] 418431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham match_object = test.match (command, patterns) 419431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results = match_object.groupdict() 420431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 421431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # We always insert the breakpoint number, setting it to -1 if we couldn't find it 422431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # Also, make sure it gets stored as an integer. 423431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if not 'bpno' in break_results: 424431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results['bpno'] = -1 425431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 426431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results['bpno'] = int(break_results['bpno']) 427431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 428431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # We always insert the number of locations 429431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1... 430431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # We also make sure it is an integer. 431431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 432431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if not 'num_locations' in break_results: 433431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham num_locations = 1 434431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 435431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham num_locations = break_results['num_locations'] 436431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if num_locations == 'no': 437431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham num_locations = 0 438431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 439431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham num_locations = int(break_results['num_locations']) 440431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 441431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results['num_locations'] = num_locations 442431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 443431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if 'line_no' in break_results: 444431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham break_results['line_no'] = int(break_results['line_no']) 445431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 446431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return break_results 447431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 448431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef get_bpno_from_match (break_results): 449431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham return int (break_results['bpno']) 450431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 451431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamdef check_breakpoint_result (test, break_results, file_name=None, line_number=-1, symbol_name=None, symbol_match_exact=True, module_name=None, offset=-1, num_locations=-1): 452431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 453431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_num_locations = break_results['num_locations'] 454431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 455431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if num_locations == -1: 456431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.") 457431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 458431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations)) 459431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 460431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if file_name: 461431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_file_name = "" 462431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if 'file' in break_results: 463431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_file_name = break_results['file'] 464431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name)) 465431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 466431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if line_number != -1: 467431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_file_line = -1 468431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if 'line_no' in break_results: 469431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_line_number = break_results['line_no'] 470431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 471431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number)) 472431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 473431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if symbol_name: 474431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_symbol_name = "" 475431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham # Look first for the inlined symbol name, otherwise use the symbol name: 476431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if 'inline_symbol' in break_results and break_results['inline_symbol']: 477431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_symbol_name = break_results['inline_symbol'] 478431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham elif 'symbol' in break_results: 479431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_symbol_name = break_results['symbol'] 480431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 481431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if symbol_match_exact: 482431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name)) 483431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham else: 484431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name)) 485431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 486431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if module_name: 487431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_nodule_name = None 488431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham if 'module' in break_results: 489431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham out_module_name = break_results['module'] 490431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 491431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham test.assertTrue (module_name.find(out_module_name) != -1, "Symbol module name '%s' isn't in expected module name '%s'."%(out_module_name, module_name)) 492431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham 493431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham# ================================================== 494168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes 495168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 496be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 497e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_threads(process, reason): 4985aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen """Returns the thread(s) with the specified stop reason in a list. 4995aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen 5005aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen The list can be empty if no such thread exists. 5015aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen """ 502e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads = [] 503d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen for t in process: 504e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen if t.GetStopReason() == reason: 505e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads.append(t) 506e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return threads 507e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 508e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_thread(process, reason): 509e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen """A convenience function which returns the first thread with the given stop 510e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen reason or None. 511e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 512e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen Example usages: 513e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 514e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 1. Get the stopped thread due to a breakpoint condition 515e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 516e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 517e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen from lldbutil import get_stopped_thread 5183d8ae4681b81b42a404ad77a231c6f743040e644Johnny Chen thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete) 519166b89f089d6bec5bb9dd40470a4dc951ffc9daaGreg Clayton self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") 520e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 521e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 522e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 2. Get the thread stopped due to a breakpoint 523e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 524e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 525e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen from lldbutil import get_stopped_thread 5263d8ae4681b81b42a404ad77a231c6f743040e644Johnny Chen thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) 527166b89f089d6bec5bb9dd40470a4dc951ffc9daaGreg Clayton self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") 528e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 529e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 530e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen """ 531e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads = get_stopped_threads(process, reason) 532e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen if len(threads) == 0: 533e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return None 534e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return threads[0] 535e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 536318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_threads_stopped_at_breakpoint (process, bkpt): 537318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" 538318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen stopped_threads = [] 539318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen threads = [] 540318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 541318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint) 542318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 543318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if len(stopped_threads) == 0: 544318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return threads 545318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 546318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen for thread in stopped_threads: 547ec95492f93f5610d23344adf10ea4224795a4d46Johnny Chen # Make sure we've hit our breakpoint... 548318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen break_id = thread.GetStopReasonDataAtIndex (0) 549318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if break_id == bkpt.GetID(): 550318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen threads.append(thread) 551318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 552318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return threads 553318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 554318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef continue_to_breakpoint (process, bkpt): 555318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 556318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen process.Continue() 557318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if process.GetState() != lldb.eStateStopped: 558318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return None 559318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen else: 560318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return get_threads_stopped_at_breakpoint (process, bkpt) 561318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 56269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chendef get_caller_symbol(thread): 56369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 56469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen Returns the symbol name for the call site of the leaf function. 56569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 56669af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen depth = thread.GetNumFrames() 56769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if depth <= 1: 56869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 56969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen caller = thread.GetFrameAtIndex(1).GetSymbol() 57069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if caller: 57169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return caller.GetName() 57269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen else: 57369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 57469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 57569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 576318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_function_names(thread): 5771605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 5781605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of function names from the stack frames of this thread. 5791605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 5801605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFuncName(i): 58164abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen return thread.GetFrameAtIndex(i).GetFunctionName() 5821605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 5831605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFuncName, range(thread.GetNumFrames())) 5841605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 5851605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 586318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_symbol_names(thread): 587b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 588b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of symbols for this thread. 589b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 590b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetSymbol(i): 591b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetSymbol().GetName() 592b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 593b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetSymbol, range(thread.GetNumFrames())) 594b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 595b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 596318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_pc_addresses(thread): 597b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 598b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of pc addresses for this thread. 599b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 600b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetPCAddress(i): 601b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetPCAddress() 602b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 603b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetPCAddress, range(thread.GetNumFrames())) 604b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 605b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 606318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_filenames(thread): 6071605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6081605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of file names from the stack frames of this thread. 6091605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6101605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFilename(i): 6111605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename() 6121605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6131605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFilename, range(thread.GetNumFrames())) 6141605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6151605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 616318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_line_numbers(thread): 6171605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6181605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of line numbers from the stack frames of this thread. 6191605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6201605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetLineNumber(i): 6211605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 6221605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6231605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetLineNumber, range(thread.GetNumFrames())) 6241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 626318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_module_names(thread): 6271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of module names from the stack frames of this thread. 6291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 6301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetModuleName(i): 6311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename() 6321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetModuleName, range(thread.GetNumFrames())) 6341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 6351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 636318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_stack_frames(thread): 63788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 63888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen Returns a sequence of stack frames for this thread. 63988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 64088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen def GetStackFrame(i): 64188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return thread.GetFrameAtIndex(i) 64288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 64388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return map(GetStackFrame, range(thread.GetNumFrames())) 64488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 64588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 646318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktrace(thread, string_buffer = False): 6471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """Prints a simple stack trace of this thread.""" 64830425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 649ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 650b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen target = thread.GetProcess().GetTarget() 651b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 6521605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen depth = thread.GetNumFrames() 6531605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 654318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen mods = get_module_names(thread) 655318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen funcs = get_function_names(thread) 656318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen symbols = get_symbol_names(thread) 657318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen files = get_filenames(thread) 658318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen lines = get_line_numbers(thread) 659318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen addrs = get_pc_addresses(thread) 66030425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 661ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen if thread.GetStopReason() != lldb.eStopReasonInvalid: 66247342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chen desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) 663ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen else: 664ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen desc = "" 665ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 666ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc 6671605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 668b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen for i in range(depth): 669b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen frame = thread.GetFrameAtIndex(i) 670b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen function = frame.GetFunction() 671b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 672b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen load_addr = addrs[i].GetLoadAddress(target) 673960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen if not function: 674b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen file_addr = addrs[i].GetFileAddress() 67549f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress() 67649f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen symbol_offset = file_addr - start_addr 67749f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( 67849f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset) 679b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen else: 68049f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( 68164abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen num=i, addr=load_addr, mod=mods[i], 68264abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i], 6837d4c7fecd679c157804577313203c5212cb59a5eJohnny Chen file=files[i], line=lines[i], 6847d4c7fecd679c157804577313203c5212cb59a5eJohnny Chen args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()') 685b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 686b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen if string_buffer: 687ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 688b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 689b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 690318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktraces(process, string_buffer = False): 691b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """Prints the stack traces of all the threads.""" 692b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 693ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 694b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 6950a19a1b9c25117854f226256805239d95153ed2dGreg Clayton print >> output, "Stack traces for " + str(process) 6961605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 697311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen for thread in process: 698311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen print >> output, print_stacktrace(thread, string_buffer=True) 69930425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 70030425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen if string_buffer: 701ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 702185e2c103c2af449262046495b3f8d1640794543Johnny Chen 703185e2c103c2af449262046495b3f8d1640794543Johnny Chen# =================================== 704185e2c103c2af449262046495b3f8d1640794543Johnny Chen# Utility functions related to Frames 705185e2c103c2af449262046495b3f8d1640794543Johnny Chen# =================================== 706185e2c103c2af449262046495b3f8d1640794543Johnny Chen 707abb3b2d796da9e081cd545b710d23c514489f895Johnny Chendef get_parent_frame(frame): 708abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen """ 709abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen Returns the parent frame of the input frame object; None if not available. 710abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen """ 711abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen thread = frame.GetThread() 712abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen parent_found = False 713abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen for f in thread: 714abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen if parent_found: 715abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen return f 716abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen if f.GetFrameID() == frame.GetFrameID(): 717abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen parent_found = True 718abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen 719abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen # If we reach here, no parent has been found, return None. 720abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen return None 721abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen 72249f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chendef get_args_as_string(frame, showFuncName=True): 723abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen """ 724abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen Returns the args of the input frame object as a string. 725abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen """ 726abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen # arguments => True 727abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen # locals => False 728abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen # statics => False 729abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen # in_scope_only => True 730abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen vars = frame.GetVariables(True, False, False, True) # type of SBValueList 731abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen args = [] # list of strings 732abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen for var in vars: 733abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen args.append("(%s)%s=%s" % (var.GetTypeName(), 734abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen var.GetName(), 7350fb0bcc9d4e951145e1b8c783652224c09b23af4Greg Clayton var.GetValue())) 736960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen if frame.GetFunction(): 737bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen name = frame.GetFunction().GetName() 738960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen elif frame.GetSymbol(): 739bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen name = frame.GetSymbol().GetName() 740bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen else: 741bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen name = "" 74249f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen if showFuncName: 74349f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen return "%s(%s)" % (name, ", ".join(args)) 74449f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen else: 74549f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen return "(%s)" % (", ".join(args)) 74649f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen 747185e2c103c2af449262046495b3f8d1640794543Johnny Chendef print_registers(frame, string_buffer = False): 748b299877fa8e5e94f9f86da47583bc2d3b85a41f5Johnny Chen """Prints all the register sets of the frame.""" 749185e2c103c2af449262046495b3f8d1640794543Johnny Chen 750185e2c103c2af449262046495b3f8d1640794543Johnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 751185e2c103c2af449262046495b3f8d1640794543Johnny Chen 7520a19a1b9c25117854f226256805239d95153ed2dGreg Clayton print >> output, "Register sets for " + str(frame) 753185e2c103c2af449262046495b3f8d1640794543Johnny Chen 754728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen registerSet = frame.GetRegisters() # Return type of SBValueList. 755728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen print >> output, "Frame registers (size of register set = %d):" % registerSet.GetSize() 756728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen for value in registerSet: 757185e2c103c2af449262046495b3f8d1640794543Johnny Chen #print >> output, value 758185e2c103c2af449262046495b3f8d1640794543Johnny Chen print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()) 759185e2c103c2af449262046495b3f8d1640794543Johnny Chen for child in value: 7600fb0bcc9d4e951145e1b8c783652224c09b23af4Greg Clayton print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue()) 761185e2c103c2af449262046495b3f8d1640794543Johnny Chen 762185e2c103c2af449262046495b3f8d1640794543Johnny Chen if string_buffer: 763185e2c103c2af449262046495b3f8d1640794543Johnny Chen return output.getvalue() 764728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 765728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_registers(frame, kind): 766728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """Returns the registers given the frame and the kind of registers desired. 767728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 768728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen Returns None if there's no such kind. 769728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """ 770728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen registerSet = frame.GetRegisters() # Return type of SBValueList. 771728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen for value in registerSet: 772728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen if kind.lower() in value.GetName().lower(): 773728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen return value 774728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 775728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen return None 776728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 777728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_GPRs(frame): 778728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """Returns the general purpose registers of the frame as an SBValue. 779728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 780fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen The returned SBValue object is iterable. An example: 781fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 782fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen from lldbutil import get_GPRs 783fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen regs = get_GPRs(frame) 784fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen for reg in regs: 785fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen print "%s => %s" % (reg.GetName(), reg.GetValue()) 786fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 787728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """ 788728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen return get_registers(frame, "general purpose") 789728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 790728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_FPRs(frame): 791728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """Returns the floating point registers of the frame as an SBValue. 792728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 793fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen The returned SBValue object is iterable. An example: 794fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 795fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen from lldbutil import get_FPRs 796fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen regs = get_FPRs(frame) 797fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen for reg in regs: 798fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen print "%s => %s" % (reg.GetName(), reg.GetValue()) 799fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 800728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """ 801728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen return get_registers(frame, "floating point") 802728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 803728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_ESRs(frame): 804728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """Returns the exception state registers of the frame as an SBValue. 805728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen 806fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen The returned SBValue object is iterable. An example: 807fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 808fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen from lldbutil import get_ESRs 809fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen regs = get_ESRs(frame) 810fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen for reg in regs: 811fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen print "%s => %s" % (reg.GetName(), reg.GetValue()) 812fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen ... 813728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen """ 814728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen return get_registers(frame, "exception state") 815084fd8945b922818e069adfb72ac39936466e221Johnny Chen 8168c06276d9d97d969f2c0c4dc0b7d25eb693d8e74Johnny Chen# ====================================== 8178c06276d9d97d969f2c0c4dc0b7d25eb693d8e74Johnny Chen# Utility classes/functions for SBValues 8188c06276d9d97d969f2c0c4dc0b7d25eb693d8e74Johnny Chen# ====================================== 819084fd8945b922818e069adfb72ac39936466e221Johnny Chen 820084fd8945b922818e069adfb72ac39936466e221Johnny Chenclass BasicFormatter(object): 821638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """The basic formatter inspects the value object and prints the value.""" 822084fd8945b922818e069adfb72ac39936466e221Johnny Chen def format(self, value, buffer=None, indent=0): 823084fd8945b922818e069adfb72ac39936466e221Johnny Chen if not buffer: 824084fd8945b922818e069adfb72ac39936466e221Johnny Chen output = StringIO.StringIO() 825084fd8945b922818e069adfb72ac39936466e221Johnny Chen else: 826084fd8945b922818e069adfb72ac39936466e221Johnny Chen output = buffer 827638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen # If there is a summary, it suffices. 828638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen val = value.GetSummary() 829638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen # Otherwise, get the value. 830638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen if val == None: 831638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen val = value.GetValue() 832638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen if val == None and value.GetNumChildren() > 0: 833638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen val = "%s (location)" % value.GetLocation() 834638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen print >> output, "{indentation}({type}) {name} = {value}".format( 835084fd8945b922818e069adfb72ac39936466e221Johnny Chen indentation = ' ' * indent, 836084fd8945b922818e069adfb72ac39936466e221Johnny Chen type = value.GetTypeName(), 837084fd8945b922818e069adfb72ac39936466e221Johnny Chen name = value.GetName(), 838638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen value = val) 839084fd8945b922818e069adfb72ac39936466e221Johnny Chen return output.getvalue() 840084fd8945b922818e069adfb72ac39936466e221Johnny Chen 841084fd8945b922818e069adfb72ac39936466e221Johnny Chenclass ChildVisitingFormatter(BasicFormatter): 842638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """The child visiting formatter prints the value and its immediate children. 843638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen 844638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen The constructor takes a keyword arg: indent_child, which defaults to 2. 845638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """ 846638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen def __init__(self, indent_child=2): 847638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """Default indentation of 2 SPC's for the children.""" 848638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen self.cindent = indent_child 849084fd8945b922818e069adfb72ac39936466e221Johnny Chen def format(self, value, buffer=None): 850084fd8945b922818e069adfb72ac39936466e221Johnny Chen if not buffer: 851084fd8945b922818e069adfb72ac39936466e221Johnny Chen output = StringIO.StringIO() 852084fd8945b922818e069adfb72ac39936466e221Johnny Chen else: 853084fd8945b922818e069adfb72ac39936466e221Johnny Chen output = buffer 854084fd8945b922818e069adfb72ac39936466e221Johnny Chen 855084fd8945b922818e069adfb72ac39936466e221Johnny Chen BasicFormatter.format(self, value, buffer=output) 856084fd8945b922818e069adfb72ac39936466e221Johnny Chen for child in value: 857638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen BasicFormatter.format(self, child, buffer=output, indent=self.cindent) 858638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen 859638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen return output.getvalue() 860638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen 861638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chenclass RecursiveDecentFormatter(BasicFormatter): 862638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """The recursive decent formatter prints the value and the decendents. 863638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen 864638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen The constructor takes two keyword args: indent_level, which defaults to 0, 865638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen and indent_child, which defaults to 2. The current indentation level is 866638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen determined by indent_level, while the immediate children has an additional 867638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen indentation by inden_child. 868638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen """ 869638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen def __init__(self, indent_level=0, indent_child=2): 870638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen self.lindent = indent_level 871638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen self.cindent = indent_child 872638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen def format(self, value, buffer=None): 873638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen if not buffer: 874638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen output = StringIO.StringIO() 875638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen else: 876638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen output = buffer 877638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen 878638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen BasicFormatter.format(self, value, buffer=output, indent=self.lindent) 879638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen new_indent = self.lindent + self.cindent 880638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen for child in value: 881638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen if child.GetSummary() != None: 882638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen BasicFormatter.format(self, child, buffer=output, indent=new_indent) 883638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen else: 884638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen if child.GetNumChildren() > 0: 885638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen rdf = RecursiveDecentFormatter(indent_level=new_indent) 886638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen rdf.format(child, buffer=output) 887638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen else: 888638ebcfea6328816ba5e9fd21e40cf5d3f060e2eJohnny Chen BasicFormatter.format(self, child, buffer=output, indent=new_indent) 889084fd8945b922818e069adfb72ac39936466e221Johnny Chen 890084fd8945b922818e069adfb72ac39936466e221Johnny Chen return output.getvalue() 891