|
11 | 11 | namespace dart {
|
12 | 12 |
|
13 | 13 | static void IterateFrames(const GrowableObjectArray& code_list,
|
14 |
| - const GrowableObjectArray& pc_offset_list) { |
| 14 | + const GrowableObjectArray& pc_offset_list, |
| 15 | + int skip_frames) { |
15 | 16 | StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
|
16 | 17 | StackFrame* frame = frames.NextFrame();
|
17 | 18 | ASSERT(frame != NULL); // We expect to find a dart invocation frame.
|
18 | 19 | Code& code = Code::Handle();
|
19 | 20 | Smi& offset = Smi::Handle();
|
20 | 21 | while (frame != NULL) {
|
21 | 22 | if (frame->IsDartFrame()) {
|
22 |
| - code = frame->LookupDartCode(); |
23 |
| - offset = Smi::New(frame->pc() - code.EntryPoint()); |
24 |
| - code_list.Add(code); |
25 |
| - pc_offset_list.Add(offset); |
| 23 | + if (skip_frames > 0) { |
| 24 | + skip_frames--; |
| 25 | + } else { |
| 26 | + code = frame->LookupDartCode(); |
| 27 | + offset = Smi::New(frame->pc() - code.EntryPoint()); |
| 28 | + code_list.Add(code); |
| 29 | + pc_offset_list.Add(offset); |
| 30 | + } |
26 | 31 | }
|
27 | 32 | frame = frames.NextFrame();
|
28 | 33 | }
|
29 | 34 | }
|
30 | 35 |
|
31 |
| - |
32 |
| -// An utility method for convenient printing of dart stack traces when |
33 |
| -// inside 'gdb'. Note: This function will only work when there is a |
34 |
| -// valid exit frame information. It will not work when a breakpoint is |
35 |
| -// set in dart code and control is got inside 'gdb' without going through |
36 |
| -// the runtime or native transition stub. |
37 |
| -void _printCurrentStacktrace() { |
| 36 | +// Creates a Stacktrace object from the current stack. |
| 37 | +// |
| 38 | +// Skips the first skip_frames Dart frames. |
| 39 | +static const Stacktrace& GetCurrentStacktrace(int skip_frames) { |
38 | 40 | const GrowableObjectArray& code_list =
|
39 | 41 | GrowableObjectArray::Handle(GrowableObjectArray::New());
|
40 | 42 | const GrowableObjectArray& pc_offset_list =
|
41 | 43 | GrowableObjectArray::Handle(GrowableObjectArray::New());
|
42 |
| - IterateFrames(code_list, pc_offset_list); |
| 44 | + IterateFrames(code_list, pc_offset_list, skip_frames); |
43 | 45 | const Array& code_array = Array::Handle(Array::MakeArray(code_list));
|
44 | 46 | const Array& pc_offset_array =
|
45 | 47 | Array::Handle(Array::MakeArray(pc_offset_list));
|
46 | 48 | const Stacktrace& stacktrace = Stacktrace::Handle(
|
47 | 49 | Stacktrace::New(code_array, pc_offset_array));
|
| 50 | + return stacktrace; |
| 51 | +} |
| 52 | + |
| 53 | +// An utility method for convenient printing of dart stack traces when |
| 54 | +// inside 'gdb'. Note: This function will only work when there is a |
| 55 | +// valid exit frame information. It will not work when a breakpoint is |
| 56 | +// set in dart code and control is got inside 'gdb' without going through |
| 57 | +// the runtime or native transition stub. |
| 58 | +void _printCurrentStacktrace() { |
| 59 | + const Stacktrace& stacktrace = GetCurrentStacktrace(0); |
48 | 60 | OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
|
49 | 61 | }
|
50 | 62 |
|
| 63 | +DEFINE_NATIVE_ENTRY(StackTrace_current, 0) { |
| 64 | + const Stacktrace& stacktrace = GetCurrentStacktrace(1); |
| 65 | + return stacktrace.raw(); |
| 66 | +} |
| 67 | + |
51 | 68 | } // namespace dart
|
0 commit comments