Symbolization function borrowed from glog.
| 665 | |
| 666 | // Symbolization function borrowed from glog. |
| 667 | string StackTrace::Symbolize() const { |
| 668 | string ret; |
| 669 | for (int i = 0; i < num_frames_; i++) { |
| 670 | void* pc = frames_[i]; |
| 671 | |
| 672 | char tmp[1024]; |
| 673 | const char* symbol = "(unknown)"; |
| 674 | |
| 675 | // The return address 'pc' on the stack is the address of the instruction |
| 676 | // following the 'call' instruction. In the case of calling a function annotated |
| 677 | // 'noreturn', this address may actually be the first instruction of the next |
| 678 | // function, because the function we care about ends with the 'call'. |
| 679 | // So, we subtract 1 from 'pc' so that we're pointing at the 'call' instead |
| 680 | // of the return address. |
| 681 | // |
| 682 | // For example, compiling a C program with -O2 that simply calls 'abort()' yields |
| 683 | // the following disassembly: |
| 684 | // Disassembly of section .text: |
| 685 | // |
| 686 | // 0000000000400440 <main>: |
| 687 | // 400440: 48 83 ec 08 sub $0x8,%rsp |
| 688 | // 400444: e8 c7 ff ff ff callq 400410 <abort@plt> |
| 689 | // |
| 690 | // 0000000000400449 <_start>: |
| 691 | // 400449: 31 ed xor %ebp,%ebp |
| 692 | // ... |
| 693 | // |
| 694 | // If we were to take a stack trace while inside 'abort', the return pointer |
| 695 | // on the stack would be 0x400449 (the first instruction of '_start'). By subtracting |
| 696 | // 1, we end up with 0x400448, which is still within 'main'. |
| 697 | // |
| 698 | // This also ensures that we point at the correct line number when using addr2line |
| 699 | // on logged stacks. |
| 700 | // |
| 701 | // We check that the pc is not 0 to avoid undefined behavior in the case of |
| 702 | // invalid unwinding (see KUDU-2433). |
| 703 | if (pc && google::Symbolize( |
| 704 | reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) { |
| 705 | symbol = tmp; |
| 706 | } |
| 707 | StringAppendF(&ret, " @ %*p %s\n", kPrintfPointerFieldWidth, pc, symbol); |
| 708 | } |
| 709 | return ret; |
| 710 | } |
| 711 | |
| 712 | string StackTrace::ToLogFormatHexString() const { |
| 713 | string ret; |