Build folded-stack format for inferno-flamegraph. category: 'code' for CODE sections, 'data' for .rodata/.data sections, 'all' for everything.
(entries, category)
| 398 | |
| 399 | |
| 400 | def build_folded_stacks(entries, category): |
| 401 | """Build folded-stack format for inferno-flamegraph. |
| 402 | |
| 403 | category: 'code' for CODE sections, 'data' for .rodata/.data sections, |
| 404 | 'all' for everything. |
| 405 | """ |
| 406 | stacks = defaultdict(int) |
| 407 | |
| 408 | for section, crate, symbol, size in entries: |
| 409 | is_code = section == "CODE" |
| 410 | is_data = section in (".rodata", ".data", ".bss", ".data.rel.ro") |
| 411 | |
| 412 | if category == "code" and not is_code: |
| 413 | continue |
| 414 | if category == "data" and not is_data: |
| 415 | continue |
| 416 | if category == "all" and not (is_code or is_data): |
| 417 | continue |
| 418 | |
| 419 | parts = [crate] |
| 420 | if category == "all": |
| 421 | parts.append("code" if is_code else "data") |
| 422 | if symbol: |
| 423 | sym_parts = symbol_to_path(symbol) |
| 424 | parts.extend(sym_parts) |
| 425 | else: |
| 426 | parts.append(section) |
| 427 | |
| 428 | stack = ";".join(parts) |
| 429 | stacks[stack] += size |
| 430 | |
| 431 | lines = [] |
| 432 | for stack_key, size in sorted(stacks.items()): |
| 433 | lines.append(f"{stack_key} {size}") |
| 434 | return "\n".join(lines) |
| 435 | |
| 436 | |
| 437 | def symbol_to_path(symbol): |