@@ -47,8 +47,6 @@ TraceInstructionDumper::TraceInstructionDumper(
47
47
}
48
48
}
49
49
50
- // / \return
51
- // / Return \b true if the cursor could move one step.
52
50
bool TraceInstructionDumper::TryMoveOneStep () {
53
51
if (!m_cursor_up->Next ()) {
54
52
SetNoMoreData ();
@@ -57,17 +55,6 @@ bool TraceInstructionDumper::TryMoveOneStep() {
57
55
return true ;
58
56
}
59
57
60
- // / Helper struct that holds symbol, disassembly and address information of an
61
- // / instruction.
62
- struct InstructionSymbolInfo {
63
- SymbolContext sc;
64
- Address address;
65
- lldb::addr_t load_address;
66
- lldb::DisassemblerSP disassembler;
67
- lldb::InstructionSP instruction;
68
- lldb_private::ExecutionContext exe_ctx;
69
- };
70
-
71
58
// This custom LineEntry validator is neded because some line_entries have
72
59
// 0 as line, which is meaningless. Notice that LineEntry::IsValid only
73
60
// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX.
@@ -122,46 +109,35 @@ IsSameInstructionSymbolContext(const InstructionSymbolInfo &prev_insn,
122
109
return curr_line_valid == prev_line_valid;
123
110
}
124
111
125
- // / Dump the symbol context of the given instruction address if it's different
126
- // / from the symbol context of the previous instruction in the trace.
127
- // /
128
- // / \param[in] prev_sc
129
- // / The symbol context of the previous instruction in the trace.
130
- // /
131
- // / \param[in] address
132
- // / The address whose symbol information will be dumped.
133
- // /
134
- // / \return
135
- // / The symbol context of the current address, which might differ from the
136
- // / previous one.
137
- static void
138
- DumpInstructionSymbolContext (Stream &s,
139
- Optional<InstructionSymbolInfo> prev_insn,
140
- InstructionSymbolInfo &insn) {
112
+ void TraceInstructionDumper::DumpInstructionSymbolContext (
113
+ const Optional<InstructionSymbolInfo> &prev_insn,
114
+ const InstructionSymbolInfo &insn) {
141
115
if (prev_insn && IsSameInstructionSymbolContext (*prev_insn, insn))
142
116
return ;
143
117
144
- s. Printf ( " " ) ;
118
+ m_s << " " ;
145
119
146
120
if (!insn.sc .module_sp )
147
- s. Printf ( " (none)" ) ;
121
+ m_s << " (none)" ;
148
122
else if (!insn.sc .function && !insn.sc .symbol )
149
- s. Printf ( " %s `(none)" ,
150
- insn.sc .module_sp ->GetFileSpec ().GetFilename ().AsCString ());
123
+ m_s. Format ( " {0} `(none)" ,
124
+ insn.sc .module_sp ->GetFileSpec ().GetFilename ().AsCString ());
151
125
else
152
- insn.sc .DumpStopContext (&s , insn.exe_ctx .GetTargetPtr (), insn.address ,
126
+ insn.sc .DumpStopContext (&m_s , insn.exe_ctx .GetTargetPtr (), insn.address ,
153
127
/* show_fullpaths=*/ false ,
154
128
/* show_module=*/ true , /* show_inlined_frames=*/ false ,
155
129
/* show_function_arguments=*/ true ,
156
130
/* show_function_name=*/ true );
157
- s. Printf ( " \n " ) ;
131
+ m_s << " \n " ;
158
132
}
159
133
160
- static void DumpInstructionDisassembly (Stream &s, InstructionSymbolInfo &insn) {
134
+ void TraceInstructionDumper::DumpInstructionDisassembly (
135
+ const InstructionSymbolInfo &insn) {
161
136
if (!insn.instruction )
162
137
return ;
163
- s.Printf (" " );
164
- insn.instruction ->Dump (&s, /* max_opcode_byte_size=*/ 0 , /* show_address=*/ false ,
138
+ m_s << " " ;
139
+ insn.instruction ->Dump (&m_s, /* max_opcode_byte_size=*/ 0 ,
140
+ /* show_address=*/ false ,
165
141
/* show_bytes=*/ false , &insn.exe_ctx , &insn.sc ,
166
142
/* prev_sym_ctx=*/ nullptr ,
167
143
/* disassembly_addr_format=*/ nullptr ,
@@ -172,6 +148,26 @@ void TraceInstructionDumper::SetNoMoreData() { m_no_more_data = true; }
172
148
173
149
bool TraceInstructionDumper::HasMoreData () { return !m_no_more_data; }
174
150
151
+ void TraceInstructionDumper::PrintMissingInstructionsMessage () {
152
+ m_s << " ...missing instructions\n " ;
153
+ }
154
+
155
+ void TraceInstructionDumper::PrintInstructionHeader () {
156
+ m_s.Format (" {0}: " , m_cursor_up->GetId ());
157
+
158
+ if (m_options.show_tsc ) {
159
+ m_s << " [tsc=" ;
160
+
161
+ if (Optional<uint64_t > timestamp =
162
+ m_cursor_up->GetCounter (lldb::eTraceCounterTSC))
163
+ m_s.Format (" {0:x+16}" , *timestamp);
164
+ else
165
+ m_s << " unavailable" ;
166
+
167
+ m_s << " ] " ;
168
+ }
169
+ }
170
+
175
171
void TraceInstructionDumper::PrintEvents () {
176
172
if (!m_options.show_events )
177
173
return ;
@@ -182,90 +178,76 @@ void TraceInstructionDumper::PrintEvents() {
182
178
});
183
179
}
184
180
185
- Optional<lldb::tid_t > TraceInstructionDumper::DumpInstructions (size_t count) {
181
+ // / Find the symbol context for the given address reusing the previous
182
+ // / instruction's symbol context when possible.
183
+ static SymbolContext
184
+ CalculateSymbolContext (const Address &address,
185
+ const InstructionSymbolInfo &prev_insn_info) {
186
+ AddressRange range;
187
+ if (prev_insn_info.sc .GetAddressRange (eSymbolContextEverything, 0 ,
188
+ /* inline_block_range*/ false , range) &&
189
+ range.Contains (address))
190
+ return prev_insn_info.sc ;
191
+
192
+ SymbolContext sc;
193
+ address.CalculateSymbolContext (&sc, eSymbolContextEverything);
194
+ return sc;
195
+ }
196
+
197
+ // / Find the disassembler for the given address reusing the previous
198
+ // / instruction's disassembler when possible.
199
+ static std::tuple<DisassemblerSP, InstructionSP>
200
+ CalculateDisass (const InstructionSymbolInfo &insn_info,
201
+ const InstructionSymbolInfo &prev_insn_info,
202
+ const ExecutionContext &exe_ctx) {
203
+ if (prev_insn_info.disassembler ) {
204
+ if (InstructionSP instruction =
205
+ prev_insn_info.disassembler ->GetInstructionList ()
206
+ .GetInstructionAtAddress (insn_info.address ))
207
+ return std::make_tuple (prev_insn_info.disassembler , instruction);
208
+ }
209
+
210
+ if (insn_info.sc .function ) {
211
+ if (DisassemblerSP disassembler =
212
+ insn_info.sc .function ->GetInstructions (exe_ctx, nullptr )) {
213
+ if (InstructionSP instruction =
214
+ disassembler->GetInstructionList ().GetInstructionAtAddress (
215
+ insn_info.address ))
216
+ return std::make_tuple (disassembler, instruction);
217
+ }
218
+ }
219
+ // We fallback to a single instruction disassembler
220
+ Target &target = exe_ctx.GetTargetRef ();
221
+ const ArchSpec arch = target.GetArchitecture ();
222
+ AddressRange range (insn_info.address , arch.GetMaximumOpcodeByteSize ());
223
+ DisassemblerSP disassembler =
224
+ Disassembler::DisassembleRange (arch, /* plugin_name*/ nullptr ,
225
+ /* flavor*/ nullptr , target, range);
226
+ return std::make_tuple (
227
+ disassembler,
228
+ disassembler ? disassembler->GetInstructionList ().GetInstructionAtAddress (
229
+ insn_info.address )
230
+ : InstructionSP ());
231
+ }
232
+
233
+ Optional<lldb::user_id_t >
234
+ TraceInstructionDumper::DumpInstructions (size_t count) {
186
235
ThreadSP thread_sp = m_cursor_up->GetExecutionContextRef ().GetThreadSP ();
187
236
if (!thread_sp) {
188
- m_s. Printf ( " invalid thread" ) ;
237
+ m_s << " invalid thread" ;
189
238
return None;
190
239
}
191
240
192
241
bool was_prev_instruction_an_error = false ;
193
-
194
- auto printMissingInstructionsMessage = [&]() {
195
- m_s.Printf (" ...missing instructions\n " );
196
- };
197
-
198
- auto printInstructionHeader = [&](uint64_t id) {
199
- m_s.Printf (" %" PRIu64 " : " , id);
200
-
201
- if (m_options.show_tsc ) {
202
- m_s.Printf (" [tsc=" );
203
-
204
- if (Optional<uint64_t > timestamp = m_cursor_up->GetCounter (lldb::eTraceCounterTSC))
205
- m_s.Printf (" 0x%016" PRIx64, *timestamp);
206
- else
207
- m_s.Printf (" unavailable" );
208
-
209
- m_s.Printf (" ] " );
210
- }
211
- };
212
-
213
242
InstructionSymbolInfo prev_insn_info;
243
+ Optional<lldb::user_id_t > last_id;
214
244
215
- Target &target = thread_sp->GetProcess ()->GetTarget ();
216
245
ExecutionContext exe_ctx;
217
- target.CalculateExecutionContext (exe_ctx);
218
- const ArchSpec &arch = target.GetArchitecture ();
219
-
220
- // Find the symbol context for the given address reusing the previous
221
- // instruction's symbol context when possible.
222
- auto calculateSymbolContext = [&](const Address &address) {
223
- AddressRange range;
224
- if (prev_insn_info.sc .GetAddressRange (eSymbolContextEverything, 0 ,
225
- /* inline_block_range*/ false ,
226
- range) &&
227
- range.Contains (address))
228
- return prev_insn_info.sc ;
229
-
230
- SymbolContext sc;
231
- address.CalculateSymbolContext (&sc, eSymbolContextEverything);
232
- return sc;
233
- };
234
-
235
- // Find the disassembler for the given address reusing the previous
236
- // instruction's disassembler when possible.
237
- auto calculateDisass = [&](const Address &address, const SymbolContext &sc) {
238
- if (prev_insn_info.disassembler ) {
239
- if (InstructionSP instruction =
240
- prev_insn_info.disassembler ->GetInstructionList ()
241
- .GetInstructionAtAddress (address))
242
- return std::make_tuple (prev_insn_info.disassembler , instruction);
243
- }
246
+ thread_sp->GetProcess ()->GetTarget ().CalculateExecutionContext (exe_ctx);
244
247
245
- if (sc.function ) {
246
- if (DisassemblerSP disassembler =
247
- sc.function ->GetInstructions (exe_ctx, nullptr )) {
248
- if (InstructionSP instruction =
249
- disassembler->GetInstructionList ().GetInstructionAtAddress (
250
- address))
251
- return std::make_tuple (disassembler, instruction);
252
- }
253
- }
254
- // We fallback to a single instruction disassembler
255
- AddressRange range (address, arch.GetMaximumOpcodeByteSize ());
256
- DisassemblerSP disassembler =
257
- Disassembler::DisassembleRange (arch, /* plugin_name*/ nullptr ,
258
- /* flavor*/ nullptr , target, range);
259
- return std::make_tuple (disassembler,
260
- disassembler ? disassembler->GetInstructionList ()
261
- .GetInstructionAtAddress (address)
262
- : InstructionSP ());
263
- };
264
-
265
- Optional<lldb::user_id_t > last_id;
266
248
for (size_t i = 0 ; i < count; i++) {
267
249
if (!HasMoreData ()) {
268
- m_s. Printf ( " no more data\n " ) ;
250
+ m_s << " no more data\n " ;
269
251
break ;
270
252
}
271
253
last_id = m_cursor_up->GetId ();
@@ -277,15 +259,15 @@ Optional<lldb::tid_t> TraceInstructionDumper::DumpInstructions(size_t count) {
277
259
278
260
if (const char *err = m_cursor_up->GetError ()) {
279
261
if (!m_cursor_up->IsForwards () && !was_prev_instruction_an_error)
280
- printMissingInstructionsMessage ();
262
+ PrintMissingInstructionsMessage ();
281
263
282
264
was_prev_instruction_an_error = true ;
283
265
284
- printInstructionHeader (m_cursor_up-> GetId () );
266
+ PrintInstructionHeader ( );
285
267
m_s << err;
286
268
} else {
287
269
if (m_cursor_up->IsForwards () && was_prev_instruction_an_error)
288
- printMissingInstructionsMessage ();
270
+ PrintMissingInstructionsMessage ();
289
271
290
272
was_prev_instruction_an_error = false ;
291
273
@@ -294,24 +276,26 @@ Optional<lldb::tid_t> TraceInstructionDumper::DumpInstructions(size_t count) {
294
276
if (!m_options.raw ) {
295
277
insn_info.load_address = m_cursor_up->GetLoadAddress ();
296
278
insn_info.exe_ctx = exe_ctx;
297
- insn_info.address .SetLoadAddress (insn_info.load_address , &target);
298
- insn_info.sc = calculateSymbolContext (insn_info.address );
279
+ insn_info.address .SetLoadAddress (insn_info.load_address ,
280
+ exe_ctx.GetTargetPtr ());
281
+ insn_info.sc =
282
+ CalculateSymbolContext (insn_info.address , prev_insn_info);
299
283
std::tie (insn_info.disassembler , insn_info.instruction ) =
300
- calculateDisass (insn_info. address , insn_info. sc );
284
+ CalculateDisass (insn_info, prev_insn_info, exe_ctx );
301
285
302
- DumpInstructionSymbolContext (m_s, prev_insn_info, insn_info);
286
+ DumpInstructionSymbolContext (prev_insn_info, insn_info);
303
287
}
304
288
305
- printInstructionHeader (m_cursor_up-> GetId () );
306
- m_s.Printf ( " 0x%016 " PRIx64 , m_cursor_up->GetLoadAddress ());
289
+ PrintInstructionHeader ( );
290
+ m_s.Format ( " {0:x+16} " , m_cursor_up->GetLoadAddress ());
307
291
308
292
if (!m_options.raw )
309
- DumpInstructionDisassembly (m_s, insn_info);
293
+ DumpInstructionDisassembly (insn_info);
310
294
311
295
prev_insn_info = insn_info;
312
296
}
313
297
314
- m_s. Printf ( " \n " ) ;
298
+ m_s << " \n " ;
315
299
316
300
if (!m_options.forwards ) {
317
301
// If we move backwards, we print the events after printing
0 commit comments