Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 14711013: Implement backtracing and toggling of execution tracing in ARM simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/stack_frame.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <math.h> // for isnan. 5 #include <math.h> // for isnan.
6 #include <setjmp.h> 6 #include <setjmp.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #if defined(TARGET_ARCH_ARM) 10 #if defined(TARGET_ARCH_ARM)
11 11
12 // Only build the simulator if not compiling for real ARM hardware. 12 // Only build the simulator if not compiling for real ARM hardware.
13 #if !defined(HOST_ARCH_ARM) 13 #if !defined(HOST_ARCH_ARM)
14 14
15 #include "vm/simulator.h" 15 #include "vm/simulator.h"
16 16
17 #include "vm/assembler.h" 17 #include "vm/assembler.h"
18 #include "vm/constants_arm.h" 18 #include "vm/constants_arm.h"
19 #include "vm/disassembler.h" 19 #include "vm/disassembler.h"
20 #include "vm/native_arguments.h" 20 #include "vm/native_arguments.h"
21 #include "vm/stack_frame.h"
21 #include "vm/thread.h" 22 #include "vm/thread.h"
22 23
23 namespace dart { 24 namespace dart {
24 25
25 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution."); 26 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution.");
26 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); 27 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");
27 28
28 29
29 // This macro provides a platform independent use of sscanf. The reason for 30 // This macro provides a platform independent use of sscanf. The reason for
30 // SScanF not being implemented in a platform independent way through 31 // SScanF not being implemented in a platform independent way through
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 ((AL << kConditionShift) | (0xf << 24) | kBreakpointSvcCode); 107 ((AL << kConditionShift) | (0xf << 24) | kBreakpointSvcCode);
107 static const int32_t kNopInstr = // nop 108 static const int32_t kNopInstr = // nop
108 ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12)); 109 ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12));
109 110
110 Simulator* sim_; 111 Simulator* sim_;
111 112
112 bool GetValue(char* desc, uint32_t* value); 113 bool GetValue(char* desc, uint32_t* value);
113 bool GetFValue(char* desc, float* value); 114 bool GetFValue(char* desc, float* value);
114 bool GetDValue(char* desc, double* value); 115 bool GetDValue(char* desc, double* value);
115 116
117 void PrintDartFrame(uword pc, uword fp, uword sp,
118 const Function& function,
119 intptr_t token_pos,
120 bool is_optimized,
121 bool is_inlined);
122 void PrintBacktrace();
123
116 // Set or delete a breakpoint. Returns true if successful. 124 // Set or delete a breakpoint. Returns true if successful.
117 bool SetBreakpoint(Instr* breakpc); 125 bool SetBreakpoint(Instr* breakpc);
118 bool DeleteBreakpoint(Instr* breakpc); 126 bool DeleteBreakpoint(Instr* breakpc);
119 127
120 // Undo and redo all breakpoints. This is needed to bracket disassembly and 128 // Undo and redo all breakpoints. This is needed to bracket disassembly and
121 // execution to skip past breakpoints when run from the debugger. 129 // execution to skip past breakpoints when run from the debugger.
122 void UndoBreakpoints(); 130 void UndoBreakpoints();
123 void RedoBreakpoints(); 131 void RedoBreakpoints();
124 }; 132 };
125 133
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 return false; 255 return false;
248 } 256 }
249 *value = *(reinterpret_cast<double*>(addr)); 257 *value = *(reinterpret_cast<double*>(addr));
250 return true; 258 return true;
251 } 259 }
252 } 260 }
253 return false; 261 return false;
254 } 262 }
255 263
256 264
265 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp,
266 const Function& function,
267 intptr_t token_pos,
268 bool is_optimized,
269 bool is_inlined) {
270 const Script& script = Script::Handle(function.script());
271 const String& func_name = String::Handle(function.QualifiedUserVisibleName());
272 const String& url = String::Handle(script.url());
273 intptr_t line = -1;
274 intptr_t column = -1;
275 if (token_pos >= 0) {
276 script.GetTokenLocation(token_pos, &line, &column);
277 }
278 OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s%s (%s:%d:%d)\n",
279 pc, fp, sp,
280 is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
281 func_name.ToCString(),
282 url.ToCString(),
283 line, column);
284 }
285
286
287 void SimulatorDebugger::PrintBacktrace() {
288 StackFrameIterator frames(sim_->get_register(FP),
289 sim_->get_register(SP),
290 sim_->get_pc(),
291 StackFrameIterator::kDontValidateFrames);
292 StackFrame* frame = frames.NextFrame();
293 ASSERT(frame != NULL);
294 Function& function = Function::Handle();
295 Function& inlined_function = Function::Handle();
296 Code& code = Code::Handle();
297 Code& unoptimized_code = Code::Handle();
298 while (frame != NULL) {
299 if (frame->IsDartFrame()) {
300 code = frame->LookupDartCode();
301 function = code.function();
302 if (code.is_optimized()) {
303 // For optimized frames, extract all the inlined functions if any
304 // into the stack trace.
305 InlinedFunctionsIterator it(frame);
306 while (!it.Done()) {
307 // Print each inlined frame with its pc in the corresponding
308 // unoptimized frame.
309 inlined_function = it.function();
310 unoptimized_code = it.code();
311 uword unoptimized_pc = it.pc();
312 it.Advance();
313 if (!it.Done()) {
314 PrintDartFrame(unoptimized_pc, frame->fp(), frame->sp(),
315 inlined_function,
316 unoptimized_code.GetTokenIndexOfPC(unoptimized_pc),
317 true, true);
318 }
319 }
320 // Print the optimized inlining frame below.
321 }
322 PrintDartFrame(frame->pc(), frame->fp(), frame->sp(),
323 function,
324 code.GetTokenIndexOfPC(frame->pc()),
325 code.is_optimized(), false);
326 } else {
327 OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s frame\n",
328 frame->pc(), frame->fp(), frame->sp(),
329 frame->IsEntryFrame() ? "entry" :
330 frame->IsExitFrame() ? "exit" :
331 frame->IsStubFrame() ? "stub" : "invalid");
332 }
333 frame = frames.NextFrame();
334 }
335 }
336
337
257 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { 338 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
258 // Check if a breakpoint can be set. If not return without any side-effects. 339 // Check if a breakpoint can be set. If not return without any side-effects.
259 if (sim_->break_pc_ != NULL) { 340 if (sim_->break_pc_ != NULL) {
260 return false; 341 return false;
261 } 342 }
262 343
263 // Set the breakpoint. 344 // Set the breakpoint.
264 sim_->break_pc_ = breakpc; 345 sim_->break_pc_ = breakpc;
265 sim_->break_instr_ = breakpc->InstructionBits(); 346 sim_->break_instr_ = breakpc->InstructionBits();
266 // Not setting the breakpoint instruction in the code itself. It will be set 347 // Not setting the breakpoint instruction in the code itself. It will be set
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 "del -- delete breakpoints\n" 424 "del -- delete breakpoints\n"
344 "flags -- print flag values\n" 425 "flags -- print flag values\n"
345 "gdb -- transfer control to gdb\n" 426 "gdb -- transfer control to gdb\n"
346 "h/help -- print this help string\n" 427 "h/help -- print this help string\n"
347 "break <address> -- set break point at specified address\n" 428 "break <address> -- set break point at specified address\n"
348 "p/print <reg or value or *addr> -- print integer value\n" 429 "p/print <reg or value or *addr> -- print integer value\n"
349 "pf/printfloat <sreg or *addr> -- print float value\n" 430 "pf/printfloat <sreg or *addr> -- print float value\n"
350 "pd/printdouble <dreg or *addr> -- print double value\n" 431 "pd/printdouble <dreg or *addr> -- print double value\n"
351 "po/printobject <*reg or *addr> -- print object\n" 432 "po/printobject <*reg or *addr> -- print object\n"
352 "si/stepi -- single step an instruction\n" 433 "si/stepi -- single step an instruction\n"
434 "trace -- toggle execution tracing mode\n"
435 "bt -- print backtrace\n"
353 "unstop -- if current pc is a stop instr make it a nop\n" 436 "unstop -- if current pc is a stop instr make it a nop\n"
354 "q/quit -- Quit the debugger and exit the program\n"); 437 "q/quit -- Quit the debugger and exit the program\n");
355 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 438 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
356 OS::Print("Quitting\n"); 439 OS::Print("Quitting\n");
357 OS::Exit(0); 440 OS::Exit(0);
358 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 441 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
359 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 442 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
360 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 443 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
361 // Execute the one instruction we broke at with breakpoints disabled. 444 // Execute the one instruction we broke at with breakpoints disabled.
362 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 445 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 OS::Print("C flag: %d; ", sim_->fp_c_flag_); 557 OS::Print("C flag: %d; ", sim_->fp_c_flag_);
475 OS::Print("V flag: %d\n", sim_->fp_v_flag_); 558 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
476 } else if (strcmp(cmd, "unstop") == 0) { 559 } else if (strcmp(cmd, "unstop") == 0) {
477 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 560 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
478 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 561 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
479 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) { 562 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
480 stop_instr->SetInstructionBits(kNopInstr); 563 stop_instr->SetInstructionBits(kNopInstr);
481 } else { 564 } else {
482 OS::Print("Not at debugger stop.\n"); 565 OS::Print("Not at debugger stop.\n");
483 } 566 }
567 } else if (strcmp(cmd, "trace") == 0) {
568 FLAG_trace_sim = !FLAG_trace_sim;
569 OS::Print("execution tracing %s\n", FLAG_trace_sim ? "on" : "off");
570 } else if (strcmp(cmd, "bt") == 0) {
571 PrintBacktrace();
484 } else { 572 } else {
485 OS::Print("Unknown command: %s\n", cmd); 573 OS::Print("Unknown command: %s\n", cmd);
486 } 574 }
487 } 575 }
488 delete[] line; 576 delete[] line;
489 } 577 }
490 578
491 // Add all the breakpoints back to stop execution and enter the debugger 579 // Add all the breakpoints back to stop execution and enter the debugger
492 // shell when hit. 580 // shell when hit.
493 RedoBreakpoints(); 581 RedoBreakpoints();
(...skipping 2428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3010 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
2923 } 3011 }
2924 buf->Longjmp(); 3012 buf->Longjmp();
2925 } 3013 }
2926 3014
2927 } // namespace dart 3015 } // namespace dart
2928 3016
2929 #endif // !defined(HOST_ARCH_ARM) 3017 #endif // !defined(HOST_ARCH_ARM)
2930 3018
2931 #endif // defined TARGET_ARCH_ARM 3019 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/stack_frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698