Merge "Emit the frame for DEX PC before the frame for native PC." am: 4a2178836e
am: 9ba37712e5
Change-Id: I8f6d12c0011efbb2e2c7c84545086b88d4d5b2b2
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 91bcc66..c5dd45b 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -128,9 +128,28 @@
}
frames->resize(total_frames);
size_t cur_frame = 0;
- for (size_t i = num_ignore_frames; i < unwinder.NumFrames(); i++, cur_frame++) {
+ for (size_t i = num_ignore_frames; i < unwinder.NumFrames(); i++) {
auto frame = &unwinder_frames[i];
- backtrace_frame_data_t* back_frame = &frames->at(cur_frame);
+
+ // Inject extra 'virtual' frame that represents the dex pc data.
+ // The dex pc is magic register defined in the Mterp interpreter,
+ // and thus it will be restored/observed in the frame after it.
+ // Adding the dex frame first here will create something like:
+ // #7 pc 006b1ba1 libartd.so ExecuteMterpImpl+14625
+ // #8 pc 0015fa20 core.vdex java.util.Arrays.binarySearch+8
+ // #9 pc 0039a1ef libartd.so art::interpreter::Execute+719
+ if (frame->dex_pc != 0) {
+ backtrace_frame_data_t* dex_frame = &frames->at(cur_frame++);
+ dex_frame->num = cur_frame;
+ dex_frame->pc = frame->dex_pc;
+ dex_frame->rel_pc = frame->dex_pc;
+ dex_frame->sp = frame->sp;
+ dex_frame->stack_size = 0;
+ dex_frame->func_offset = 0;
+ FillInDexFrame(stack_map, frame->dex_pc, dex_frame);
+ }
+
+ backtrace_frame_data_t* back_frame = &frames->at(cur_frame++);
back_frame->num = cur_frame;
@@ -147,19 +166,6 @@
back_frame->map.offset = frame->map_offset;
back_frame->map.load_bias = frame->map_load_bias;
back_frame->map.flags = frame->map_flags;
-
- // Inject a frame that represents the dex pc data.
- if (frame->dex_pc != 0) {
- cur_frame++;
- backtrace_frame_data_t* dex_frame = &frames->at(cur_frame);
- dex_frame->num = cur_frame;
- dex_frame->pc = frame->dex_pc;
- dex_frame->rel_pc = frame->dex_pc;
- dex_frame->sp = back_frame->sp;
- dex_frame->stack_size = 0;
- dex_frame->func_offset = 0;
- FillInDexFrame(stack_map, frame->dex_pc, dex_frame);
- }
}
return true;