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
1115 }1115 }
1116}1116}
1117 1117
1118/* It's at the target address, check if it has a matching type */1118/*
1119static bool check_matching_type(struct type_state *state,1119 * It's at the target address, check if it has a matching type.
1120 struct data_loc_info *dloc, int reg,1120 * It returns 1 if found, 0 if not or -1 if not found but no need to
1121 Dwarf_Die *cu_die, Dwarf_Die *type_die)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 */
1124static 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)
1122{1127{
1123 Dwarf_Word size;1128 Dwarf_Word size;
1124 u32 insn_offset = dloc->ip - dloc->ms->sym->start;1129 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
1137 * dereference a memory location.1142 * dereference a memory location.
1138 */1143 */
1139 if (tag != DW_TAG_pointer_type && tag != DW_TAG_array_type)1144 if (tag != DW_TAG_pointer_type && tag != DW_TAG_array_type)
1140 return false;1145 return -1;
1141 1146
1142 /* Remove the pointer and get the target type */1147 /* Remove the pointer and get the target type */
1143 if (die_get_real_type(&state->regs[reg].type, type_die) == NULL)1148 if (die_get_real_type(&state->regs[reg].type, type_die) == NULL)
1144 return false;1149 return -1;
1145 1150
1146 dloc->type_offset = dloc->op->offset;1151 dloc->type_offset = dloc->op->offset;
1147 1152
1148 /* Get the size of the actual type */1153 /* Get the size of the actual type */
1149 if (dwarf_aggregate_size(type_die, &size) < 0 ||1154 if (dwarf_aggregate_size(type_die, &size) < 0 ||
1150 (unsigned)dloc->type_offset >= size)1155 (unsigned)dloc->type_offset >= size)
1151 return false;1156 return -1;
1152 1157
1153 return true;1158 return 1;
1154 }1159 }
1155 1160
1156 if (reg == dloc->fbreg) {1161 if (reg == dloc->fbreg) {
@@ -1160,18 +1165,18 @@ static bool check_matching_type(struct type_state *state, · 3 unmodified lines
1160 1165
1161 stack = find_stack_state(state, dloc->type_offset);1166 stack = find_stack_state(state, dloc->type_offset);
1162 if (stack == NULL)1167 if (stack == NULL)
1163 return false;1168 return 0;
1164 1169
1165 if (stack->kind == TSR_KIND_CANARY) {1170 if (stack->kind == TSR_KIND_CANARY) {
1166 setup_stack_canary(dloc);1171 setup_stack_canary(dloc);
1167 return false;1172 return -1;
1168 }1173 }
1169 1174
1170 *type_die = stack->type;1175 *type_die = stack->type;
1171 /* Update the type offset from the start of slot */1176 /* Update the type offset from the start of slot */
1172 dloc->type_offset -= stack->offset;1177 dloc->type_offset -= stack->offset;
1173 1178
1174 return true;1179 return 1;
1175 }1180 }
1176 1181
1177 if (dloc->fb_cfa) {1182 if (dloc->fb_cfa) {
@@ -1185,22 +1190,22 @@ static bool check_matching_type(struct type_state *state, · 7 unmodified lines
1185 fbreg = -1;1190 fbreg = -1;
1186 1191
1187 if (reg != fbreg)1192 if (reg != fbreg)
1188 return false;1193 return 0;
1189 1194
1190 stack = find_stack_state(state, dloc->type_offset - fboff);1195 stack = find_stack_state(state, dloc->type_offset - fboff);
1191 if (stack == NULL)1196 if (stack == NULL)
1192 return false;1197 return 0;
1193 1198
1194 if (stack->kind == TSR_KIND_CANARY) {1199 if (stack->kind == TSR_KIND_CANARY) {
1195 setup_stack_canary(dloc);1200 setup_stack_canary(dloc);
1196 return false;1201 return -1;
1197 }1202 }
1198 1203
1199 *type_die = stack->type;1204 *type_die = stack->type;
1200 /* Update the type offset from the start of slot */1205 /* Update the type offset from the start of slot */
1201 dloc->type_offset -= fboff + stack->offset;1206 dloc->type_offset -= fboff + stack->offset;
1202 1207
1203 return true;1208 return 1;
1204 }1209 }
1205 1210
1206 if (state->regs[reg].kind == TSR_KIND_PERCPU_BASE) {1211 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
1212 if (get_global_var_type(cu_die, dloc, dloc->ip, var_addr,1217 if (get_global_var_type(cu_die, dloc, dloc->ip, var_addr,
1213 &var_offset, type_die)) {1218 &var_offset, type_die)) {
1214 dloc->type_offset = var_offset;1219 dloc->type_offset = var_offset;
1215 return true;1220 return 1;
1216 }1221 }
1217 return false;1222 /* No need to retry per-cpu (global) variables */
1223 return -1;
1218 }1224 }
1219 1225
1220 if (state->regs[reg].ok && state->regs[reg].kind == TSR_KIND_POINTER) {1226 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
1231 /* Get the size of the actual type */1237 /* Get the size of the actual type */
1232 if (dwarf_aggregate_size(type_die, &size) < 0 ||1238 if (dwarf_aggregate_size(type_die, &size) < 0 ||
1233 (unsigned)dloc->type_offset >= size)1239 (unsigned)dloc->type_offset >= size)
1234 return false;1240 return -1;
1235 1241
1236 return true;1242 return 1;
1237 }1243 }
1238 1244
1239 if (state->regs[reg].ok && state->regs[reg].kind == TSR_KIND_CANARY) {1245 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
1246 */1252 */
1247 setup_stack_canary(dloc);1253 setup_stack_canary(dloc);
1248 1254
1249 return false;1255 return -1;
1250 }1256 }
1251 1257
1252 if (map__dso(dloc->ms->map)->kernel && arch__is(dloc->arch, "x86")) {1258 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
1262 if (get_global_var_type(cu_die, dloc, dloc->ip, addr,1268 if (get_global_var_type(cu_die, dloc, dloc->ip, addr,
1263 &offset, type_die)) {1269 &offset, type_die)) {
1264 dloc->type_offset = offset;1270 dloc->type_offset = offset;
1265 return true;1271 return 1;
1266 }1272 }
1267 return false;1273 return -1;
1268 }1274 }
1269 1275
1270 /* Access to per-cpu base like "-0x7dcf0500(,%rdx,8)" */1276 /* 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
1280 pr_debug_dtp(" percpu base\n");1286 pr_debug_dtp(" percpu base\n");
1281 1287
1282 dloc->type_offset = offset;1288 dloc->type_offset = offset;
1283 return true;1289 return 1;
1284 }1290 }
1291 pr_debug_dtp(" negative offset\n");
1292 return -1;
1285 }1293 }
1286 }1294 }
1287 1295
1288 pr_debug_dtp("\n");1296 pr_debug_dtp("\n");
1289 return false;1297 return 0;
1290}1298}
1291 1299
1292/* Iterate instructions in basic blocks and update type table */1300/* Iterate instructions in basic blocks and update type table */
1293static bool find_data_type_insn(struct data_loc_info *dloc, int reg,1301static int find_data_type_insn(struct data_loc_info *dloc, int reg,
1294 struct list_head *basic_blocks,1302 struct list_head *basic_blocks,
1295 struct die_var_type *var_types,1303 struct die_var_type *var_types,
1296 Dwarf_Die *cu_die, Dwarf_Die *type_die)1304 Dwarf_Die *cu_die, Dwarf_Die *type_die)
1297{1305{
1298 struct type_state state;1306 struct type_state state;
1299 struct symbol *sym = dloc->ms->sym;1307 struct symbol *sym = dloc->ms->sym;
1300 struct annotation *notes = symbol__annotation(sym);1308 struct annotation *notes = symbol__annotation(sym);
1301 struct annotated_basic_block *bb;1309 struct annotated_basic_block *bb;
1302 bool found = false;1310 int ret = 0;
1303 1311
1304 init_type_state(&state, dloc->arch);1312 init_type_state(&state, dloc->arch);
1305 1313
@@ -1317,8 +1325,8 @@ static bool find_data_type_insn(struct data_loc_info *dloc, int reg, · 11 unmodified lines
1317 update_var_state(&state, dloc, addr, dl->al.offset, var_types);1325 update_var_state(&state, dloc, addr, dl->al.offset, var_types);
1318 1326
1319 if (this_ip == dloc->ip) {1327 if (this_ip == dloc->ip) {
1320 found = check_matching_type(&state, dloc, reg,1328 ret = check_matching_type(&state, dloc, reg,
1321 cu_die, type_die);1329 cu_die, type_die);
1322 goto out;1330 goto out;
1323 }1331 }
1324 1332
@@ -1331,7 +1339,7 @@ static bool find_data_type_insn(struct data_loc_info *dloc, int reg, · 6 unmodified lines
1331 1339
1332out:1340out:
1333 exit_type_state(&state);1341 exit_type_state(&state);
1334 return found;1342 return ret;
1335}1343}
1336 1344
1337/*1345/*
@@ -1355,6 +1363,7 @@ static int find_data_type_block(struct data_loc_info *dloc, int reg, · 17 unmodified lines
1355 for (int i = nr_scopes - 1; i >= 0; i--) {1363 for (int i = nr_scopes - 1; i >= 0; i--) {
1356 Dwarf_Addr base, start, end;1364 Dwarf_Addr base, start, end;
1357 LIST_HEAD(this_blocks);1365 LIST_HEAD(this_blocks);
1366 int found;
1358 1367
1359 if (dwarf_ranges(&scopes[i], 0, &base, &start, &end) < 0)1368 if (dwarf_ranges(&scopes[i], 0, &base, &start, &end) < 0)
1360 break;1369 break;
@@ -1385,15 +1394,19 @@ again: · 24 unmodified lines
1385 fixup_var_address(var_types, start);1394 fixup_var_address(var_types, start);
1386 1395
1387 /* Find from start of this scope to the target instruction */1396 /* Find from start of this scope to the target instruction */
1388 if (find_data_type_insn(dloc, reg, &basic_blocks, var_types,1397 found = find_data_type_insn(dloc, reg, &basic_blocks, var_types,
1389 cu_die, type_die)) {1398 cu_die, type_die);
1390 ret = 0;1399 if (found > 0) {
1391 pr_debug_dtp("found by insn track: %#x(reg%d) type-offset=%#x",1400 pr_debug_dtp("found by insn track: %#x(reg%d) type-offset=%#x",
1392 dloc->op->offset, reg, dloc->type_offset);1401 dloc->op->offset, reg, dloc->type_offset);
1393 pr_debug_type_name(type_die, TSR_KIND_TYPE);1402 pr_debug_type_name(type_die, TSR_KIND_TYPE);
1403 ret = 0;
1394 break;1404 break;
1395 }1405 }
1396 1406
1407 if (found < 0)
1408 break;
1409
1397 /* Go up to the next scope and find blocks to the start */1410 /* Go up to the next scope and find blocks to the start */
1398 prev_dst_ip = dst_ip;1411 prev_dst_ip = dst_ip;
1399 dst_ip = src_ip;1412 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