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

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') | runtime/vm/stack_frame.cc » ('J')
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_inlined);
121 void PrintBacktrace();
122
116 // Set or delete a breakpoint. Returns true if successful. 123 // Set or delete a breakpoint. Returns true if successful.
117 bool SetBreakpoint(Instr* breakpc); 124 bool SetBreakpoint(Instr* breakpc);
118 bool DeleteBreakpoint(Instr* breakpc); 125 bool DeleteBreakpoint(Instr* breakpc);
119 126
120 // Undo and redo all breakpoints. This is needed to bracket disassembly and 127 // Undo and redo all breakpoints. This is needed to bracket disassembly and
121 // execution to skip past breakpoints when run from the debugger. 128 // execution to skip past breakpoints when run from the debugger.
122 void UndoBreakpoints(); 129 void UndoBreakpoints();
123 void RedoBreakpoints(); 130 void RedoBreakpoints();
124 }; 131 };
125 132
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 return false; 254 return false;
248 } 255 }
249 *value = *(reinterpret_cast<double*>(addr)); 256 *value = *(reinterpret_cast<double*>(addr));
250 return true; 257 return true;
251 } 258 }
252 } 259 }
253 return false; 260 return false;
254 } 261 }
255 262
256 263
264 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp,
265 const Function& function,
266 intptr_t token_pos,
267 bool is_inlined) {
268 const Script& script = Script::Handle(function.script());
269 const String& func_name = String::Handle(function.QualifiedUserVisibleName());
270 const String& url = String::Handle(script.url());
271 intptr_t line = -1;
272 intptr_t column = -1;
273 if (token_pos >= 0) {
274 script.GetTokenLocation(token_pos, &line, &column);
275 }
276 OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s%s (%s:%d:%d)\n",
277 pc, fp, sp,
278 is_inlined ? "inlined " : "",
279 func_name.ToCString(),
280 url.ToCString(),
281 line, column);
282 }
283
284
285 void SimulatorDebugger::PrintBacktrace() {
286 StackFrameIterator frames(sim_->get_register(FP),
287 sim_->get_register(SP),
288 sim_->get_register(PC),
289 StackFrameIterator::kDontValidateFrames);
290 StackFrame* frame = frames.NextFrame();
291 ASSERT(frame != NULL);
292 Function& function = Function::Handle();
293 Code& code = Code::Handle();
294 while (frame != NULL) {
295 if (frame->IsDartFrame()) {
296 code = frame->LookupDartCode();
297 if (code.is_optimized()) {
298 // For optimized frames, extract all the inlined functions if any
299 // into the stack trace.
300 for (InlinedFunctionsIterator it(frame); !it.Done(); it.Advance()) {
301 function = it.function();
302 code = it.code();
303 uword pc = it.pc();
304 ASSERT(pc != 0);
305 ASSERT(code.EntryPoint() <= pc);
306 ASSERT(pc < (code.EntryPoint() + code.Size()));
307 PrintDartFrame(pc, frame->fp(), frame->sp(),
308 function,
309 code.GetTokenIndexOfPC(pc),
310 !it.Done());
311 }
312 } else {
313 function = code.function();
314 PrintDartFrame(frame->pc(), frame->fp(), frame->sp(),
315 function,
316 code.GetTokenIndexOfPC(frame->pc()),
317 false);
318 }
319 } else {
320 OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s frame\n",
321 frame->pc(), frame->fp(), frame->sp(),
322 frame->IsEntryFrame() ? "entry" :
323 frame->IsExitFrame() ? "exit" :
324 frame->IsStubFrame() ? "stub" : "invalid");
325 }
326 frame = frames.NextFrame();
327 }
328 }
329
330
257 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { 331 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
258 // Check if a breakpoint can be set. If not return without any side-effects. 332 // Check if a breakpoint can be set. If not return without any side-effects.
259 if (sim_->break_pc_ != NULL) { 333 if (sim_->break_pc_ != NULL) {
260 return false; 334 return false;
261 } 335 }
262 336
263 // Set the breakpoint. 337 // Set the breakpoint.
264 sim_->break_pc_ = breakpc; 338 sim_->break_pc_ = breakpc;
265 sim_->break_instr_ = breakpc->InstructionBits(); 339 sim_->break_instr_ = breakpc->InstructionBits();
266 // Not setting the breakpoint instruction in the code itself. It will be set 340 // 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" 417 "del -- delete breakpoints\n"
344 "flags -- print flag values\n" 418 "flags -- print flag values\n"
345 "gdb -- transfer control to gdb\n" 419 "gdb -- transfer control to gdb\n"
346 "h/help -- print this help string\n" 420 "h/help -- print this help string\n"
347 "break <address> -- set break point at specified address\n" 421 "break <address> -- set break point at specified address\n"
348 "p/print <reg or value or *addr> -- print integer value\n" 422 "p/print <reg or value or *addr> -- print integer value\n"
349 "pf/printfloat <sreg or *addr> -- print float value\n" 423 "pf/printfloat <sreg or *addr> -- print float value\n"
350 "pd/printdouble <dreg or *addr> -- print double value\n" 424 "pd/printdouble <dreg or *addr> -- print double value\n"
351 "po/printobject <*reg or *addr> -- print object\n" 425 "po/printobject <*reg or *addr> -- print object\n"
352 "si/stepi -- single step an instruction\n" 426 "si/stepi -- single step an instruction\n"
427 "trace -- toggle execution tracing mode\n"
428 "bt -- print backtrace\n"
353 "unstop -- if current pc is a stop instr make it a nop\n" 429 "unstop -- if current pc is a stop instr make it a nop\n"
354 "q/quit -- Quit the debugger and exit the program\n"); 430 "q/quit -- Quit the debugger and exit the program\n");
355 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 431 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
356 OS::Print("Quitting\n"); 432 OS::Print("Quitting\n");
357 OS::Exit(0); 433 OS::Exit(0);
358 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 434 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
359 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 435 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
360 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 436 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
361 // Execute the one instruction we broke at with breakpoints disabled. 437 // Execute the one instruction we broke at with breakpoints disabled.
362 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 438 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_); 550 OS::Print("C flag: %d; ", sim_->fp_c_flag_);
475 OS::Print("V flag: %d\n", sim_->fp_v_flag_); 551 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
476 } else if (strcmp(cmd, "unstop") == 0) { 552 } else if (strcmp(cmd, "unstop") == 0) {
477 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 553 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
478 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 554 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
479 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) { 555 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
480 stop_instr->SetInstructionBits(kNopInstr); 556 stop_instr->SetInstructionBits(kNopInstr);
481 } else { 557 } else {
482 OS::Print("Not at debugger stop.\n"); 558 OS::Print("Not at debugger stop.\n");
483 } 559 }
560 } else if (strcmp(cmd, "trace") == 0) {
561 FLAG_trace_sim = !FLAG_trace_sim;
562 OS::Print("execution tracing %s\n", FLAG_trace_sim ? "on" : "off");
563 } else if (strcmp(cmd, "bt") == 0) {
564 PrintBacktrace();
484 } else { 565 } else {
485 OS::Print("Unknown command: %s\n", cmd); 566 OS::Print("Unknown command: %s\n", cmd);
486 } 567 }
487 } 568 }
488 delete[] line; 569 delete[] line;
489 } 570 }
490 571
491 // Add all the breakpoints back to stop execution and enter the debugger 572 // Add all the breakpoints back to stop execution and enter the debugger
492 // shell when hit. 573 // shell when hit.
493 RedoBreakpoints(); 574 RedoBreakpoints();
(...skipping 2428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3003 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
2923 } 3004 }
2924 buf->Longjmp(); 3005 buf->Longjmp();
2925 } 3006 }
2926 3007
2927 } // namespace dart 3008 } // namespace dart
2928 3009
2929 #endif // !defined(HOST_ARCH_ARM) 3010 #endif // !defined(HOST_ARCH_ARM)
2930 3011
2931 #endif // defined TARGET_ARCH_ARM 3012 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/stack_frame.h » ('j') | runtime/vm/stack_frame.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698