Index: lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py +++ lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py @@ -17,7 +17,6 @@ @skipIfRemote @skipIfNoSBHeaders @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64"]) def test_breakpoint_callback(self): """Test the that SBBreakpoint callback is invoked when a breakpoint is hit. """ self.build_and_test('driver.cpp test_breakpoint_callback.cpp', @@ -27,7 +26,6 @@ @skipIfNoSBHeaders @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) @expectedFlakeyFreeBSD - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64"]) def test_sb_api_listener_event_description(self): """ Test the description of an SBListener breakpoint event is valid.""" self.build_and_test('driver.cpp listener_test.cpp test_listener_event_description.cpp', @@ -39,7 +37,6 @@ @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) @expectedFlakeyFreeBSD @expectedFlakeyLinux # Driver occasionally returns '1' as exit status - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64"]) def test_sb_api_listener_event_process_state(self): """ Test that a registered SBListener receives events when a process changes state. Index: lldb/trunk/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py @@ -56,7 +56,6 @@ patterns = ["\(float\) \$.* = 2\.234"]) # (float) $2 = 2.234 - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) @expectedFailureWindows("llvm.org/pr21765") def test_many_expr_commands(self): self.build_and_run() @@ -99,7 +98,6 @@ # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out" @add_test_categories(['pyapi']) - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) @expectedFailureWindows # Test crashes def test_evaluate_expression_python(self): """Test SBFrame.EvaluateExpression() API for evaluating an expression.""" Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py @@ -21,7 +21,6 @@ # Find the line number to break at. self.line = line_number('main.cpp', '// Set break point at this line.') - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64","i386"]) def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py @@ -20,7 +20,6 @@ @skipIfFreeBSD # llvm.org/pr17228 @skipIfRemote - @expectedFailureAll("llvm.org/pr23560", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") def test_with_run_commands(self): """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py @@ -40,7 +40,6 @@ self.build() self.inferior_crashing_expr() - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) @expectedFailureWindows("llvm.org/pr24778") def test_inferior_crashing_step(self): """Test that stepping after a crash behaves correctly.""" Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py @@ -16,7 +16,6 @@ @add_test_categories(['pyapi']) @expectedFailureFreeBSD('llvm.org/pr17214') @expectedFailureIcc # Not really a bug. ICC combines two inlined functions. - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) @expectedFailureWindows("llvm.org/pr24778") # failed 1/365 dosep runs, (i386-clang), TestInlineStepping.py:237 failed to stop at first breakpoint in main @expectedFailureAll(oslist=["linux"], archs=["i386"]) @@ -26,7 +25,6 @@ self.inline_stepping() @add_test_categories(['pyapi']) - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_step_over_with_python_api(self): """Test stepping over and into inlined functions.""" self.build() Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/memory/read/TestMemoryRead.py @@ -22,7 +22,6 @@ # Find the line number to break inside main(). self.line = line_number('main.cpp', '// Set break point at this line.') - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_memory_read(self): """Test the 'memory read' command with plain and vector formats.""" self.build() Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py @@ -34,7 +34,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_abort(self): """Test that 'lldb-mi --interpreter' works for -exec-abort.""" @@ -84,7 +83,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_arguments_set(self): """Test that 'lldb-mi --interpreter' can pass args using -exec-arguments.""" @@ -127,7 +125,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_arguments_reset(self): """Test that 'lldb-mi --interpreter' can reset previously set args using -exec-arguments.""" @@ -208,7 +205,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races @expectedFailurei386 #xfail to get buildbot green, failing config: i386 binary running on ubuntu 14.04 x86_64 - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_next_instruction(self): """Test that 'lldb-mi --interpreter' works for instruction stepping.""" @@ -391,7 +387,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_finish(self): """Test that 'lldb-mi --interpreter' works for -exec-finish.""" Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py @@ -15,7 +15,6 @@ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - @expectedFailureAll("llvm.org/pr23560", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_eval(self): """Test that 'lldb-mi --interpreter' works for evaluating.""" Index: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h +++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h @@ -136,6 +136,15 @@ std::vector m_user_supplied_trap_handler_functions; + //----------------------------------------------------------------- + // Check if Full UnwindPlan of First frame is valid or not. + // If not then try Fallback UnwindPlan of the frame. If Fallback + // UnwindPlan succeeds then update the Full UnwindPlan with the + // Fallback UnwindPlan. + //----------------------------------------------------------------- + void + UpdateUnwindPlanForFirstFrameIfInvalid (ABI* abi); + CursorSP GetOneMoreFrame (ABI* abi); Index: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -86,6 +86,9 @@ if (m_frames.size() > 0) return true; + ProcessSP process_sp (m_thread.GetProcess()); + ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; + // First, set up the 0th (initial) frame CursorSP first_cursor_sp(new Cursor ()); RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread, @@ -108,6 +111,10 @@ // cursor own it in its shared pointer first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; m_frames.push_back (first_cursor_sp); + + // Update the Full Unwind Plan for this frame if not valid + UpdateUnwindPlanForFirstFrameIfInvalid(abi); + return true; unwind_done: @@ -161,7 +168,14 @@ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.", @@ -175,7 +189,14 @@ // See if the regctx below this on the stack has a fallback unwind plan it can use. // Subsequent calls to TryFallbackUnwindPlan() will return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", @@ -187,7 +208,14 @@ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk", @@ -212,7 +240,14 @@ || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", @@ -232,7 +267,14 @@ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk", @@ -244,7 +286,14 @@ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of + // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it. + if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + return GetOneMoreFrame (abi); + } if (log) log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", @@ -263,6 +312,33 @@ return cursor_sp; } +void +UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid (ABI *abi) +{ + // This function is called for First Frame only. + assert (m_frames.size() == 1 && "No. of cursor frames are not 1"); + + bool old_m_unwind_complete = m_unwind_complete; + CursorSP old_m_candidate_frame = m_candidate_frame; + + // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan + // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also + // update the cfa of Frame 0 (if required). + AddOneMoreFrame(abi); + + // Remove all the frames added by above function as the purpose of + // using above function was just to check whether Unwinder of Frame 0 + // works or not. + for(uint32_t i=1; ireg_ctx_lldb_sp->GetCFA(m_frames[m_frames.size() - 2]->cfa))) + return false; return true; + } - // The new frame isn't helped in unwinding. Fall back to the original one as the default unwind + // The new frame hasn't helped in unwinding. Fall back to the original one as the default unwind // plan is usually more reliable then the fallback one. m_frames.pop_back(); m_frames.push_back(new_frame);