History

perf annotate-data: Do not retry for invalid types

In some cases, it was able to find a type or location info (for per-cpu variable) but cannot match because of invalid offset or missing global information. In those cases, it's meaningless to go to the outer scope and retry because there will be no additional information. Let's change the return type of find_matching_type() and bail out if it returns -1 for the cases.

Namhyung Kim committed 2 years ago

Commit bd62de01 parent 55ee3d01 file · +48 −35Browse files

Unified · Split

tools/perf/util/annotate-data.c+48−35
@@ -1115,10 +1115,15 @@ static void setup_stack_canary(struct data_loc_info *dloc) · 1114 unmodified lines
11151115 }
11161116 }
11171117
1118−/* It's at the target address, check if it has a matching type */
1119−static bool check_matching_type(struct type_state *state,
1120− struct data_loc_info *dloc, int reg,
1121− Dwarf_Die *cu_die, Dwarf_Die *type_die)
1118+/*
1119+ * It's at the target address, check if it has a matching type.
1120+ * It returns 1 if found, 0 if not or -1 if not found but no need to
1121+ * repeat the search. The last case is for per-cpu variables which
1122+ * are similar to global variables and no additional info is needed.
1123+ */
1124+static int check_matching_type(struct type_state *state,
1125+ struct data_loc_info *dloc, int reg,
1126+ Dwarf_Die *cu_die, Dwarf_Die *type_die)
11221127 {
11231128 Dwarf_Word size;
11241129 u32 insn_offset = dloc->ip - dloc->ms->sym->start;
@@ -1137,20 +1142,20 @@ static bool check_matching_type(struct type_state *state, · 12 unmodified lines
11371142 * dereference a memory location.
11381143 */
11391144 if (tag != DW_TAG_pointer_type && tag != DW_TAG_array_type)
1140− return false;
1145+ return -1;
11411146
11421147 /* Remove the pointer and get the target type */
11431148 if (die_get_real_type(&state->regs[reg].type, type_die) == NULL)
1144− return false;
1149+ return -1;
11451150
11461151 dloc->type_offset = dloc->op->offset;
11471152
11481153 /* Get the size of the actual type */
11491154 if (dwarf_aggregate_size(type_die, &size) < 0 ||
11501155 (unsigned)dloc->type_offset >= size)
1151− return false;
1156+ return -1;
11521157
1153− return true;
1158+ return 1;
11541159 }
11551160
11561161 if (reg == dloc->fbreg) {
@@ -1160,18 +1165,18 @@ static bool check_matching_type(struct type_state *state, · 3 unmodified lines
11601165
11611166 stack = find_stack_state(state, dloc->type_offset);
11621167 if (stack == NULL)
1163− return false;
1168+ return 0;
11641169
11651170 if (stack->kind == TSR_KIND_CANARY) {
11661171 setup_stack_canary(dloc);
1167− return false;
1172+ return -1;
11681173 }
11691174
11701175 *type_die = stack->type;
11711176 /* Update the type offset from the start of slot */
11721177 dloc->type_offset -= stack->offset;
11731178
1174− return true;
1179+ return 1;
11751180 }
11761181
11771182 if (dloc->fb_cfa) {
@@ -1185,22 +1190,22 @@ static bool check_matching_type(struct type_state *state, · 7 unmodified lines
11851190 fbreg = -1;
11861191
11871192 if (reg != fbreg)
1188− return false;
1193+ return 0;
11891194
11901195 stack = find_stack_state(state, dloc->type_offset - fboff);
11911196 if (stack == NULL)
1192− return false;
1197+ return 0;
11931198
11941199 if (stack->kind == TSR_KIND_CANARY) {
11951200 setup_stack_canary(dloc);
1196− return false;
1201+ return -1;
11971202 }
11981203
11991204 *type_die = stack->type;
12001205 /* Update the type offset from the start of slot */
12011206 dloc->type_offset -= fboff + stack->offset;
12021207
1203− return true;
1208+ return 1;
12041209 }
12051210
12061211 if (state->regs[reg].kind == TSR_KIND_PERCPU_BASE) {
@@ -1212,9 +1217,10 @@ static bool check_matching_type(struct type_state *state, · 5 unmodified lines
12121217 if (get_global_var_type(cu_die, dloc, dloc->ip, var_addr,
12131218 &var_offset, type_die)) {
12141219 dloc->type_offset = var_offset;
1215− return true;
1220+ return 1;
12161221 }
1217− return false;
1222+ /* No need to retry per-cpu (global) variables */
1223+ return -1;
12181224 }
12191225
12201226 if (state->regs[reg].ok && state->regs[reg].kind == TSR_KIND_POINTER) {
@@ -1231,9 +1237,9 @@ static bool check_matching_type(struct type_state *state, · 10 unmodified lines
12311237 /* Get the size of the actual type */
12321238 if (dwarf_aggregate_size(type_die, &size) < 0 ||
12331239 (unsigned)dloc->type_offset >= size)
1234− return false;
1240+ return -1;
12351241
1236− return true;
1242+ return 1;
12371243 }
12381244
12391245 if (state->regs[reg].ok && state->regs[reg].kind == TSR_KIND_CANARY) {
@@ -1246,7 +1252,7 @@ static bool check_matching_type(struct type_state *state, · 6 unmodified lines
12461252 */
12471253 setup_stack_canary(dloc);
12481254
1249− return false;
1255+ return -1;
12501256 }
12511257
12521258 if (map__dso(dloc->ms->map)->kernel && arch__is(dloc->arch, "x86")) {
@@ -1262,9 +1268,9 @@ static bool check_matching_type(struct type_state *state, · 9 unmodified lines
12621268 if (get_global_var_type(cu_die, dloc, dloc->ip, addr,
12631269 &offset, type_die)) {
12641270 dloc->type_offset = offset;
1265− return true;
1271+ return 1;
12661272 }
1267− return false;
1273+ return -1;
12681274 }
12691275
12701276 /* Access to per-cpu base like "-0x7dcf0500(,%rdx,8)" */
@@ -1280,26 +1286,28 @@ static bool check_matching_type(struct type_state *state, · 9 unmodified lines
12801286 pr_debug_dtp(" percpu base\n");
12811287
12821288 dloc->type_offset = offset;
1283− return true;
1289+ return 1;
12841290 }
1291+ pr_debug_dtp(" negative offset\n");
1292+ return -1;
12851293 }
12861294 }
12871295
12881296 pr_debug_dtp("\n");
1289− return false;
1297+ return 0;
12901298 }
12911299
12921300 /* Iterate instructions in basic blocks and update type table */
1293−static bool find_data_type_insn(struct data_loc_info *dloc, int reg,
1294− struct list_head *basic_blocks,
1295− struct die_var_type *var_types,
1296− Dwarf_Die *cu_die, Dwarf_Die *type_die)
1301+static int find_data_type_insn(struct data_loc_info *dloc, int reg,
1302+ struct list_head *basic_blocks,
1303+ struct die_var_type *var_types,
1304+ Dwarf_Die *cu_die, Dwarf_Die *type_die)
12971305 {
12981306 struct type_state state;
12991307 struct symbol *sym = dloc->ms->sym;
13001308 struct annotation *notes = symbol__annotation(sym);
13011309 struct annotated_basic_block *bb;
1302− bool found = false;
1310+ int ret = 0;
13031311
13041312 init_type_state(&state, dloc->arch);
13051313
@@ -1317,8 +1325,8 @@ static bool find_data_type_insn(struct data_loc_info *dloc, int reg, · 11 unmodified lines
13171325 update_var_state(&state, dloc, addr, dl->al.offset, var_types);
13181326
13191327 if (this_ip == dloc->ip) {
1320− found = check_matching_type(&state, dloc, reg,
1321− cu_die, type_die);
1328+ ret = check_matching_type(&state, dloc, reg,
1329+ cu_die, type_die);
13221330 goto out;
13231331 }
13241332
@@ -1331,7 +1339,7 @@ static bool find_data_type_insn(struct data_loc_info *dloc, int reg, · 6 unmodified lines
13311339
13321340 out:
13331341 exit_type_state(&state);
1334− return found;
1342+ return ret;
13351343 }
13361344
13371345 /*
@@ -1355,6 +1363,7 @@ static int find_data_type_block(struct data_loc_info *dloc, int reg, · 17 unmodified lines
13551363 for (int i = nr_scopes - 1; i >= 0; i--) {
13561364 Dwarf_Addr base, start, end;
13571365 LIST_HEAD(this_blocks);
1366+ int found;
13581367
13591368 if (dwarf_ranges(&scopes[i], 0, &base, &start, &end) < 0)
13601369 break;
@@ -1385,15 +1394,19 @@ again: · 24 unmodified lines
13851394 fixup_var_address(var_types, start);
13861395
13871396 /* Find from start of this scope to the target instruction */
1388− if (find_data_type_insn(dloc, reg, &basic_blocks, var_types,
1389− cu_die, type_die)) {
1390− ret = 0;
1397+ found = find_data_type_insn(dloc, reg, &basic_blocks, var_types,
1398+ cu_die, type_die);
1399+ if (found > 0) {
13911400 pr_debug_dtp("found by insn track: %#x(reg%d) type-offset=%#x",
13921401 dloc->op->offset, reg, dloc->type_offset);
13931402 pr_debug_type_name(type_die, TSR_KIND_TYPE);
1403+ ret = 0;
13941404 break;
13951405 }
13961406
1407+ if (found < 0)
1408+ break;
1409+
13971410 /* Go up to the next scope and find blocks to the start */
13981411 prev_dst_ip = dst_ip;
13991412 dst_ip = src_ip;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t