I'm currently using simpleperf
, which is a ported version of perf for Android, in my Nexus 5. What I hope to do is to dynamically get native functions' execution sequence.
I guess there should be a way to dump a sample record once there is a branch event. So what I have to do is to execute simpleperf record -e branch-loads:u -p [pid]
.
Below I listed some relative events supported in my device. I tried branch-loads
and branch-instructions
for my purpose. But neither of them returned expected result. I believe this is due to branch includes functions as well as conditional jumps.
root@hammerhead:/data/local/tmp # ./simpleperf32 list
List of hw-cache events:
...
branch-loads
branch-load-misses
branch-stores
branch-store-misses
node-loads
node-load-misses
node-stores
node-store-misses
node-prefetches
node-prefetch-misses
List of hardware events:
cpu-cycles
instructions
branch-instructions
branch-misses
bus-cycles
stalled-cycles-frontend
stalled-cycles-backend
So, how could I get function call events ONLY? Or if I'm on a wrong way, please point me the right one. Thanks.
perf list
doesn't list actual hardware events, it is just a list of perf-predefined list, and it is not fully supported by any CPU. Some CPUs maps several events to perf's predefined, other map different event set.
You should check documentation of your CPU core (qualcomm krait 400) to find actual hardware performance monitoring events (counters) and use them as raw (encoding to perf stat -e rXXXX
or to RAW in perf_attr is architecture specific too). Also you can try perf stat
/ perf stat -d
to check which events are counted (supported) from some default lists.
Your nexus 5 is based on Krait 400 CPU core.
There were some problems reported in krait: How to get perf_event results for 2nd Nexus7 with Krait CPU and there was link to patch, defining standard events for krait:
http://www.serverphorums.com/read.php?12,850329
There are two sets of mapping from predefined perf to actual hw events. One with support of branch-instructions
event and other without:
/*
+ * Krait HW events mapping
+ */
+static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
According to selection code, this is feature of later versions of Krait CPU:
+static int krait_pmu_init(struct arm_pmu *cpu_pmu)
+{
+ u32 id = read_cpuid_id() & 0xffffff00;
+
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Krait";
+ /* Some early versions of Krait don't support PC write events */
+ if (id == 0x511f0400 || id == 0x510f0600)
+ cpu_pmu->map_event = krait_map_event_no_branch;
+ else
+ cpu_pmu->map_event = krait_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
+}
As I can decode cpuid - Krait 400 and Krait 600 have no support of branch-instruction PMU event (PC write event).
Update: For your Nexus 5x if it use ARM Cortex A57 core, there is list of raw events, based on "Table 11-24 from the "Cortex A57 Technical Reference Manual""
https://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/lib/events/arm_cortex_a57_events.h
Still no counter for all branches. There are BRANCH_MISPRED & BRANCH_PRED but I have no access to docs and don't know will they count all branches or not.