From fc1c78e60e9b305386f4c3fc811463f3b24cf6d4 Mon Sep 17 00:00:00 2001 From: mmentovai Date: Thu, 28 Sep 2006 21:09:37 +0000 Subject: Handle frame pointer omission (#21), part 3: SourceLineResolver and PDBSourceLineWriter changes. r=bryner. - PDBSourceLineWriter (dump_syms) outputs stack frame debugging information - SourceLineResolver reads the new information and puts it into a new StackFrameInfo structure, which is stored in a ContainedRangeMap. FillSourceLineInfo passes the StackFrameInfo back to the caller. - The base Stackwalker makes StackFrameInfo data available to subclasses during stackwalking, but does not use this information directly itself. Stackwalkers may access stack_frame_info_ for enhanced stackwalking (this will be part 4). - New test data for the updated dumped-symbol format http://groups.google.com/group/airbag-dev/browse_thread/thread/735f191c9a1a1de4 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@38 4c0a9323-5329-0410-9bdc-e9ce6186880e --- .../windows/dump_syms/pdb_source_line_writer.cc | 78 +++++++++++++++++++++- .../windows/dump_syms/pdb_source_line_writer.h | 4 ++ .../dump_syms/testdata/dump_syms_regtest.out | 63 +++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) (limited to 'src/tools/windows/dump_syms') diff --git a/src/tools/windows/dump_syms/pdb_source_line_writer.cc b/src/tools/windows/dump_syms/pdb_source_line_writer.cc index 5e9422f5..18b5d9ce 100644 --- a/src/tools/windows/dump_syms/pdb_source_line_writer.cc +++ b/src/tools/windows/dump_syms/pdb_source_line_writer.cc @@ -219,10 +219,86 @@ bool PDBSourceLineWriter::PrintFunctions() { return true; } +bool PDBSourceLineWriter::PrintFrameData() { + // It would be nice if it were possible to output frame data alongside the + // associated function, as is done with line numbers, but the DIA API + // doesn't make it possible to get the frame data in that way. + + CComPtr tables; + if (FAILED(session_->getEnumTables(&tables))) + return false; + + // Pick up the first table that supports IDiaEnumFrameData. + CComPtr frame_data_enum; + CComPtr table; + ULONG count; + while (!frame_data_enum && + SUCCEEDED(tables->Next(1, &table, &count)) && + count == 1) { + table->QueryInterface(_uuidof(IDiaEnumFrameData), + reinterpret_cast(&frame_data_enum)); + table.Release(); + } + if (!frame_data_enum) + return false; + + CComPtr frame_data; + while (SUCCEEDED(frame_data_enum->Next(1, &frame_data, &count)) && + count == 1) { + DWORD type; + if (FAILED(frame_data->get_type(&type))) + return false; + + DWORD rva; + if (FAILED(frame_data->get_relativeVirtualAddress(&rva))) + return false; + + DWORD code_size; + if (FAILED(frame_data->get_lengthBlock(&code_size))) + return false; + + DWORD prolog_size; + if (FAILED(frame_data->get_lengthProlog(&prolog_size))) + return false; + + // epliog_size is always 0. + DWORD epilog_size = 0; + + DWORD parameter_size; + if (FAILED(frame_data->get_lengthParams(¶meter_size))) + return false; + + DWORD saved_register_size; + if (FAILED(frame_data->get_lengthSavedRegisters(&saved_register_size))) + return false; + + DWORD local_size; + if (FAILED(frame_data->get_lengthLocals(&local_size))) + return false; + + DWORD max_stack_size; + if (FAILED(frame_data->get_maxStack(&max_stack_size))) + return false; + + BSTR program_string; + if (FAILED(frame_data->get_program(&program_string))) + return false; + + fprintf(output_, "STACK WIN %x %x %x %x %x %x %x %x %x %ws\n", + type, rva, code_size, prolog_size, epilog_size, + parameter_size, saved_register_size, local_size, max_stack_size, + program_string); + + frame_data.Release(); + } + + return true; +} + bool PDBSourceLineWriter::WriteMap(FILE *map_file) { bool ret = false; output_ = map_file; - if (PrintSourceFiles() && PrintFunctions()) { + if (PrintSourceFiles() && PrintFunctions() && PrintFrameData()) { ret = true; } diff --git a/src/tools/windows/dump_syms/pdb_source_line_writer.h b/src/tools/windows/dump_syms/pdb_source_line_writer.h index 7decbf2d..c6c6563a 100644 --- a/src/tools/windows/dump_syms/pdb_source_line_writer.h +++ b/src/tools/windows/dump_syms/pdb_source_line_writer.h @@ -76,6 +76,10 @@ class PDBSourceLineWriter { // Returns true on success. bool PrintSourceFiles(); + // Outputs all of the frame information necessary to construct stack + // backtraces in the absence of frame pointers. Returns true on success. + bool PrintFrameData(); + // The session for the currently-open pdb file. CComPtr session_; diff --git a/src/tools/windows/dump_syms/testdata/dump_syms_regtest.out b/src/tools/windows/dump_syms/testdata/dump_syms_regtest.out index 8ca9d3dc..d18e01a9 100644 --- a/src/tools/windows/dump_syms/testdata/dump_syms_regtest.out +++ b/src/tools/windows/dump_syms/testdata/dump_syms_regtest.out @@ -1530,3 +1530,66 @@ FUNC 2264 94 __security_init_cookie 22e5 6 215 770 22eb b 216 770 22f6 2 218 770 +STACK WIN 4 1000 187 39 0 8 8 23c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1023 164 16 0 8 c 23c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 576 - ^ = +STACK WIN 4 1190 a 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11a0 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11b0 15 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11d0 10 2 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 11e0 163 24 0 4 8 10 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1350 19b 29 0 4 c 1c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1362 189 17 0 4 10 1c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 32 - ^ = +STACK WIN 4 1363 188 16 0 4 14 1c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 36 - ^ = $ebx $T0 32 - ^ = +STACK WIN 4 14f0 1d3 28 0 4 c 1c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1502 1c1 16 0 4 10 1c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 32 - ^ = +STACK WIN 4 16d0 326 29 0 0 c 2c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 16e2 314 17 0 0 10 2c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 48 - ^ = +STACK WIN 4 16e3 313 16 0 0 14 2c 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 52 - ^ = $ebx $T0 48 - ^ = +STACK WIN 4 1a00 1b1 27 0 0 8 20 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1a12 19f 15 0 0 c 20 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 36 - ^ = +STACK WIN 4 1bc0 35 8 0 4 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1bc5 2d 3 0 4 4 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +STACK WIN 4 1bc6 29 2 0 4 8 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +STACK WIN 4 1c02 f 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1c11 4b 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1c5c 176 c 0 0 c 20 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = +STACK WIN 4 1d82 14 0 0 0 c 20 0 $T0 $ebp = $T2 $esp = $T1 .raSearchStart = $eip $T1 ^ = $ebp $T0 = $esp $T1 4 + = $L $T0 .cbSavedRegs - = $P $T1 4 + .cbParams + = +STACK WIN 4 1dd2 e2 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1eb4 a 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 1ebe 104 9 0 0 0 328 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = +STACK WIN 4 1fc8 9f c 0 4 c 24 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = +STACK WIN 4 205e 8 0 0 4 c 24 0 $T0 $ebp = $T2 $esp = $T1 .raSearchStart = $eip $T1 ^ = $ebp $T0 = $esp $T1 4 + = $L $T0 .cbSavedRegs - = $P $T1 4 + .cbParams + = +STACK WIN 4 2067 12 0 0 4 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2079 24 2 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 207a 22 1 0 0 4 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 207b 20 0 0 0 8 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 209d 24 2 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 209e 22 1 0 0 4 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 209f 20 0 0 0 8 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 20d0 29 0 0 4 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2100 42 18 0 8 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 210e 33 a 0 8 4 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +STACK WIN 4 210f 31 9 0 8 8 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +STACK WIN 4 2118 27 0 0 8 c 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +STACK WIN 4 2142 6c c 0 4 c 18 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = +STACK WIN 4 2188 14 0 0 4 c 18 0 $T0 $ebp = $T2 $esp = $T1 .raSearchStart = $eip $T1 ^ = $ebp $T0 = $esp $T1 4 + = $L $T0 .cbSavedRegs - = $P $T1 4 + .cbParams + = +STACK WIN 4 2215 23 0 0 10 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2238 29 1 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2239 27 0 0 0 4 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2261 3 0 0 0 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2261 3 0 0 4 0 0 0 $T2 $esp .cbLocals + .cbSavedRegs + = $T0 .raSearchStart = $eip $T0 ^ = $esp $T0 4 + = +STACK WIN 4 2264 94 15 0 0 0 10 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = +STACK WIN 4 2278 7e 1 0 0 4 10 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = +STACK WIN 4 2279 7c 0 0 0 8 10 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = +STACK WIN 4 2295 5f 0 0 0 c 10 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = +STACK WIN 0 1d82 14 0 0 0 0 0 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = +STACK WIN 0 205e 9 0 0 0 0 0 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = +STACK WIN 0 2188 14 0 0 0 0 0 0 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 20 - ^ = -- cgit v1.2.1