1cfca06d7SDimitry Andric //===-- UnwindLLDB.cpp ----------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9cfca06d7SDimitry Andric #include "lldb/Target/UnwindLLDB.h"
1014f1b3e8SDimitry Andric #include "lldb/Core/Module.h"
11f034231aSEd Maste #include "lldb/Symbol/FuncUnwinders.h"
12f034231aSEd Maste #include "lldb/Symbol/Function.h"
13f034231aSEd Maste #include "lldb/Symbol/UnwindPlan.h"
145e95aa85SEd Maste #include "lldb/Target/ABI.h"
15f034231aSEd Maste #include "lldb/Target/Process.h"
16f034231aSEd Maste #include "lldb/Target/RegisterContext.h"
17cfca06d7SDimitry Andric #include "lldb/Target/RegisterContextUnwind.h"
1814f1b3e8SDimitry Andric #include "lldb/Target/Target.h"
1914f1b3e8SDimitry Andric #include "lldb/Target/Thread.h"
20145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
2174a628f7SDimitry Andric #include "lldb/Utility/Log.h"
22f034231aSEd Maste
23f034231aSEd Maste using namespace lldb;
24f034231aSEd Maste using namespace lldb_private;
25f034231aSEd Maste
UnwindLLDB(Thread & thread)2614f1b3e8SDimitry Andric UnwindLLDB::UnwindLLDB(Thread &thread)
2714f1b3e8SDimitry Andric : Unwind(thread), m_frames(), m_unwind_complete(false),
2814f1b3e8SDimitry Andric m_user_supplied_trap_handler_functions() {
29866dcdacSEd Maste ProcessSP process_sp(thread.GetProcess());
3014f1b3e8SDimitry Andric if (process_sp) {
31866dcdacSEd Maste Args args;
32866dcdacSEd Maste process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
33866dcdacSEd Maste size_t count = args.GetArgumentCount();
3414f1b3e8SDimitry Andric for (size_t i = 0; i < count; i++) {
35866dcdacSEd Maste const char *func_name = args.GetArgumentAtIndex(i);
36866dcdacSEd Maste m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
37866dcdacSEd Maste }
38866dcdacSEd Maste }
39f034231aSEd Maste }
40f034231aSEd Maste
DoGetFrameCount()4114f1b3e8SDimitry Andric uint32_t UnwindLLDB::DoGetFrameCount() {
4214f1b3e8SDimitry Andric if (!m_unwind_complete) {
43f034231aSEd Maste //#define DEBUG_FRAME_SPEED 1
44f034231aSEd Maste #if DEBUG_FRAME_SPEED
45f034231aSEd Maste #define FRAME_COUNT 10000
4614f1b3e8SDimitry Andric using namespace std::chrono;
4714f1b3e8SDimitry Andric auto time_value = steady_clock::now();
48f034231aSEd Maste #endif
49f034231aSEd Maste if (!AddFirstFrame())
50f034231aSEd Maste return 0;
51f034231aSEd Maste
52f034231aSEd Maste ProcessSP process_sp(m_thread.GetProcess());
535f29bb8aSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
54f034231aSEd Maste
5514f1b3e8SDimitry Andric while (AddOneMoreFrame(abi)) {
56f034231aSEd Maste #if DEBUG_FRAME_SPEED
5714f1b3e8SDimitry Andric if ((m_frames.size() % FRAME_COUNT) == 0) {
5814f1b3e8SDimitry Andric const auto now = steady_clock::now();
5914f1b3e8SDimitry Andric const auto delta_t = now - time_value;
6014f1b3e8SDimitry Andric printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
6114f1b3e8SDimitry Andric duration<double, std::milli>(delta_t).count(),
6214f1b3e8SDimitry Andric (float)FRAME_COUNT / duration<double>(delta_t).count());
63f034231aSEd Maste time_value = now;
64f034231aSEd Maste }
65f034231aSEd Maste #endif
66f034231aSEd Maste }
67f034231aSEd Maste }
68f034231aSEd Maste return m_frames.size();
69f034231aSEd Maste }
70f034231aSEd Maste
AddFirstFrame()7114f1b3e8SDimitry Andric bool UnwindLLDB::AddFirstFrame() {
72f034231aSEd Maste if (m_frames.size() > 0)
73f034231aSEd Maste return true;
74f034231aSEd Maste
75e81d9d49SDimitry Andric ProcessSP process_sp(m_thread.GetProcess());
765f29bb8aSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
77e81d9d49SDimitry Andric
78f034231aSEd Maste // First, set up the 0th (initial) frame
79f034231aSEd Maste CursorSP first_cursor_sp(new Cursor());
80cfca06d7SDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(
8114f1b3e8SDimitry Andric m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
825f29bb8aSDimitry Andric if (reg_ctx_sp.get() == nullptr)
83f034231aSEd Maste goto unwind_done;
84f034231aSEd Maste
85f034231aSEd Maste if (!reg_ctx_sp->IsValid())
86f034231aSEd Maste goto unwind_done;
87f034231aSEd Maste
88f034231aSEd Maste if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
89f034231aSEd Maste goto unwind_done;
90f034231aSEd Maste
91f034231aSEd Maste if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
92f034231aSEd Maste goto unwind_done;
93f034231aSEd Maste
94f034231aSEd Maste // Everything checks out, so release the auto pointer value and let the
95f034231aSEd Maste // cursor own it in its shared pointer
96f034231aSEd Maste first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
97f034231aSEd Maste m_frames.push_back(first_cursor_sp);
98e81d9d49SDimitry Andric
99e81d9d49SDimitry Andric // Update the Full Unwind Plan for this frame if not valid
100e81d9d49SDimitry Andric UpdateUnwindPlanForFirstFrameIfInvalid(abi);
101e81d9d49SDimitry Andric
102f034231aSEd Maste return true;
103866dcdacSEd Maste
104f034231aSEd Maste unwind_done:
105145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Unwind);
10614f1b3e8SDimitry Andric if (log) {
107ead24645SDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
10814f1b3e8SDimitry Andric m_thread.GetIndexID());
109866dcdacSEd Maste }
110f034231aSEd Maste m_unwind_complete = true;
111f034231aSEd Maste return false;
112f034231aSEd Maste }
113f034231aSEd Maste
GetOneMoreFrame(ABI * abi)11414f1b3e8SDimitry Andric UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
11514f1b3e8SDimitry Andric assert(m_frames.size() != 0 &&
11614f1b3e8SDimitry Andric "Get one more frame called with empty frame list");
117027f1c96SDimitry Andric
11814f1b3e8SDimitry Andric // If we've already gotten to the end of the stack, don't bother to try
11914f1b3e8SDimitry Andric // again...
120f034231aSEd Maste if (m_unwind_complete)
121027f1c96SDimitry Andric return nullptr;
122f034231aSEd Maste
123145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Unwind);
124f034231aSEd Maste
125027f1c96SDimitry Andric CursorSP prev_frame = m_frames.back();
126f034231aSEd Maste uint32_t cur_idx = m_frames.size();
127027f1c96SDimitry Andric
128027f1c96SDimitry Andric CursorSP cursor_sp(new Cursor());
129cfca06d7SDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(
13014f1b3e8SDimitry Andric m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
131f034231aSEd Maste
13294994d37SDimitry Andric uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth();
13394994d37SDimitry Andric
134027f1c96SDimitry Andric // We want to detect an unwind that cycles erroneously and stop backtracing.
13514f1b3e8SDimitry Andric // Don't want this maximum unwind limit to be too low -- if you have a
136f73363f1SDimitry Andric // backtrace with an "infinitely recursing" bug, it will crash when the stack
137f73363f1SDimitry Andric // blows out and the first 35,000 frames are uninteresting - it's the top
138f73363f1SDimitry Andric // most 5 frames that you actually care about. So you can't just cap the
139f73363f1SDimitry Andric // unwind at 10,000 or something. Realistically anything over around 200,000
140f73363f1SDimitry Andric // is going to blow out the stack space. If we're still unwinding at that
141f73363f1SDimitry Andric // point, we're probably never going to finish.
14294994d37SDimitry Andric if (cur_idx >= max_stack_depth) {
143ead24645SDimitry Andric LLDB_LOGF(log,
144ead24645SDimitry Andric "%*sFrame %d unwound too many frames, assuming unwind has "
14514f1b3e8SDimitry Andric "gone astray, stopping.",
146f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
147027f1c96SDimitry Andric return nullptr;
148f034231aSEd Maste }
149f034231aSEd Maste
1505f29bb8aSDimitry Andric if (reg_ctx_sp.get() == nullptr) {
151cfca06d7SDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
152f73363f1SDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
153f73363f1SDimitry Andric // return false.
15414f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
15514f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
156f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
157f73363f1SDimitry Andric // still needs to be updated. Hence updating it.
158e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
159e81d9d49SDimitry Andric return nullptr;
160e81d9d49SDimitry Andric
161027f1c96SDimitry Andric return GetOneMoreFrame(abi);
162e81d9d49SDimitry Andric }
163027f1c96SDimitry Andric
164ead24645SDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",
165866dcdacSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
166027f1c96SDimitry Andric return nullptr;
167866dcdacSEd Maste }
168f034231aSEd Maste
16914f1b3e8SDimitry Andric if (!reg_ctx_sp->IsValid()) {
170f73363f1SDimitry Andric // We failed to get a valid RegisterContext. See if the regctx below this
171f73363f1SDimitry Andric // on the stack has a fallback unwind plan it can use. Subsequent calls to
172f73363f1SDimitry Andric // TryFallbackUnwindPlan() will return false.
17314f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
17414f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
175f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
176f73363f1SDimitry Andric // still needs to be updated. Hence updating it.
177e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
178e81d9d49SDimitry Andric return nullptr;
179e81d9d49SDimitry Andric
180027f1c96SDimitry Andric return GetOneMoreFrame(abi);
181e81d9d49SDimitry Andric }
182027f1c96SDimitry Andric
183ead24645SDimitry Andric LLDB_LOGF(log,
184ead24645SDimitry Andric "%*sFrame %d invalid RegisterContext for this frame, "
18514f1b3e8SDimitry Andric "stopping stack walk",
186f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
187027f1c96SDimitry Andric return nullptr;
188f034231aSEd Maste }
18914f1b3e8SDimitry Andric if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
190cfca06d7SDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
191f73363f1SDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
192f73363f1SDimitry Andric // return false.
19314f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
19414f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
195f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
196f73363f1SDimitry Andric // still needs to be updated. Hence updating it.
197e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
198e81d9d49SDimitry Andric return nullptr;
199e81d9d49SDimitry Andric
200027f1c96SDimitry Andric return GetOneMoreFrame(abi);
201e81d9d49SDimitry Andric }
202027f1c96SDimitry Andric
203ead24645SDimitry Andric LLDB_LOGF(log,
20414f1b3e8SDimitry Andric "%*sFrame %d did not get CFA for this frame, stopping stack walk",
205f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
206027f1c96SDimitry Andric return nullptr;
207f034231aSEd Maste }
20814f1b3e8SDimitry Andric if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
20914f1b3e8SDimitry Andric // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
210f73363f1SDimitry Andric // have its (constructed) CFA aligned correctly -- don't do the abi
211f73363f1SDimitry Andric // alignment check for these.
21294994d37SDimitry Andric if (!reg_ctx_sp->IsTrapHandlerFrame()) {
213205afe67SEd Maste // See if we can find a fallback unwind plan for THIS frame. It may be
214205afe67SEd Maste // that the UnwindPlan we're using for THIS frame was bad and gave us a
215f73363f1SDimitry Andric // bad CFA. If that's not it, then see if we can change the UnwindPlan
216f73363f1SDimitry Andric // for the frame below us ("NEXT") -- see if using that other UnwindPlan
217f73363f1SDimitry Andric // gets us a better unwind state.
21894994d37SDimitry Andric if (!reg_ctx_sp->TryFallbackUnwindPlan() ||
21994994d37SDimitry Andric !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||
22094994d37SDimitry Andric !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
22114f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
22214f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
223f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of
224f73363f1SDimitry Andric // prev_frame still needs to be updated. Hence updating it.
225e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
226e81d9d49SDimitry Andric return nullptr;
227e81d9d49SDimitry Andric
228027f1c96SDimitry Andric return GetOneMoreFrame(abi);
229e81d9d49SDimitry Andric }
230027f1c96SDimitry Andric
231ead24645SDimitry Andric LLDB_LOGF(log,
232ead24645SDimitry Andric "%*sFrame %d did not get a valid CFA for this frame, "
23314f1b3e8SDimitry Andric "stopping stack walk",
234f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
235027f1c96SDimitry Andric return nullptr;
23614f1b3e8SDimitry Andric } else {
237ead24645SDimitry Andric LLDB_LOGF(log,
238ead24645SDimitry Andric "%*sFrame %d had a bad CFA value but we switched the "
23914f1b3e8SDimitry Andric "UnwindPlan being used and got one that looks more "
24014f1b3e8SDimitry Andric "realistic.",
241205afe67SEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
242205afe67SEd Maste }
243205afe67SEd Maste }
244205afe67SEd Maste }
24514f1b3e8SDimitry Andric if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
246cfca06d7SDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
247f73363f1SDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
248f73363f1SDimitry Andric // return false.
24914f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
25014f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
251f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
252f73363f1SDimitry Andric // still needs to be updated. Hence updating it.
253e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
254e81d9d49SDimitry Andric return nullptr;
255e81d9d49SDimitry Andric
256027f1c96SDimitry Andric return GetOneMoreFrame(abi);
257e81d9d49SDimitry Andric }
258027f1c96SDimitry Andric
259ead24645SDimitry Andric LLDB_LOGF(log,
26014f1b3e8SDimitry Andric "%*sFrame %d did not get PC for this frame, stopping stack walk",
261f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
262027f1c96SDimitry Andric return nullptr;
263f034231aSEd Maste }
264ac9a064cSDimitry Andric
265ac9a064cSDimitry Andric // Invalid code addresses should not appear on the stack *unless* we're
266ac9a064cSDimitry Andric // directly below a trap handler frame (in this case, the invalid address is
267ac9a064cSDimitry Andric // likely the cause of the trap).
268ac9a064cSDimitry Andric if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc) &&
269ac9a064cSDimitry Andric !prev_frame->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
270cfca06d7SDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
271f73363f1SDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
272f73363f1SDimitry Andric // return false.
27314f1b3e8SDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
27414f1b3e8SDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated
275f73363f1SDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
276f73363f1SDimitry Andric // still needs to be updated. Hence updating it.
277e81d9d49SDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
278e81d9d49SDimitry Andric return nullptr;
279e81d9d49SDimitry Andric
280027f1c96SDimitry Andric return GetOneMoreFrame(abi);
281e81d9d49SDimitry Andric }
282027f1c96SDimitry Andric
283ead24645SDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk",
284f034231aSEd Maste cur_idx < 100 ? cur_idx : 100, "", cur_idx);
285027f1c96SDimitry Andric return nullptr;
286f034231aSEd Maste }
287866dcdacSEd Maste // Infinite loop where the current cursor is the same as the previous one...
28814f1b3e8SDimitry Andric if (prev_frame->start_pc == cursor_sp->start_pc &&
28914f1b3e8SDimitry Andric prev_frame->cfa == cursor_sp->cfa) {
290ead24645SDimitry Andric LLDB_LOGF(log,
291ead24645SDimitry Andric "th%d pc of this frame is the same as the previous frame and "
29214f1b3e8SDimitry Andric "CFAs for both frames are identical -- stopping unwind",
29314f1b3e8SDimitry Andric m_thread.GetIndexID());
294027f1c96SDimitry Andric return nullptr;
295866dcdacSEd Maste }
296f21a844fSEd Maste
297f034231aSEd Maste cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
298027f1c96SDimitry Andric return cursor_sp;
299866dcdacSEd Maste }
300027f1c96SDimitry Andric
UpdateUnwindPlanForFirstFrameIfInvalid(ABI * abi)30114f1b3e8SDimitry Andric void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
302e81d9d49SDimitry Andric // This function is called for First Frame only.
303e81d9d49SDimitry Andric assert(m_frames.size() == 1 && "No. of cursor frames are not 1");
304e81d9d49SDimitry Andric
305e81d9d49SDimitry Andric bool old_m_unwind_complete = m_unwind_complete;
306e81d9d49SDimitry Andric CursorSP old_m_candidate_frame = m_candidate_frame;
307e81d9d49SDimitry Andric
308e81d9d49SDimitry Andric // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
309f73363f1SDimitry Andric // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update
310f73363f1SDimitry Andric // the cfa of Frame 0 (if required).
311e81d9d49SDimitry Andric AddOneMoreFrame(abi);
312e81d9d49SDimitry Andric
313f73363f1SDimitry Andric // Remove all the frames added by above function as the purpose of using
314f73363f1SDimitry Andric // above function was just to check whether Unwinder of Frame 0 works or not.
315e81d9d49SDimitry Andric for (uint32_t i = 1; i < m_frames.size(); i++)
316e81d9d49SDimitry Andric m_frames.pop_back();
317e81d9d49SDimitry Andric
318e81d9d49SDimitry Andric // Restore status after calling AddOneMoreFrame
319e81d9d49SDimitry Andric m_unwind_complete = old_m_unwind_complete;
320e81d9d49SDimitry Andric m_candidate_frame = old_m_candidate_frame;
321e81d9d49SDimitry Andric }
322e81d9d49SDimitry Andric
AddOneMoreFrame(ABI * abi)32314f1b3e8SDimitry Andric bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
324145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Unwind);
325027f1c96SDimitry Andric
326027f1c96SDimitry Andric // Frame zero is a little different
327027f1c96SDimitry Andric if (m_frames.empty())
328027f1c96SDimitry Andric return false;
329027f1c96SDimitry Andric
33014f1b3e8SDimitry Andric // If we've already gotten to the end of the stack, don't bother to try
33114f1b3e8SDimitry Andric // again...
332027f1c96SDimitry Andric if (m_unwind_complete)
333027f1c96SDimitry Andric return false;
334027f1c96SDimitry Andric
335027f1c96SDimitry Andric CursorSP new_frame = m_candidate_frame;
336027f1c96SDimitry Andric if (new_frame == nullptr)
337027f1c96SDimitry Andric new_frame = GetOneMoreFrame(abi);
338027f1c96SDimitry Andric
33914f1b3e8SDimitry Andric if (new_frame == nullptr) {
340ead24645SDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
34114f1b3e8SDimitry Andric m_thread.GetIndexID());
342f034231aSEd Maste m_unwind_complete = true;
343f034231aSEd Maste return false;
344f034231aSEd Maste }
345f034231aSEd Maste
346027f1c96SDimitry Andric m_frames.push_back(new_frame);
347027f1c96SDimitry Andric
348f73363f1SDimitry Andric // If we can get one more frame further then accept that we get back a
349f73363f1SDimitry Andric // correct frame.
350027f1c96SDimitry Andric m_candidate_frame = GetOneMoreFrame(abi);
351027f1c96SDimitry Andric if (m_candidate_frame)
352027f1c96SDimitry Andric return true;
353027f1c96SDimitry Andric
35414f1b3e8SDimitry Andric // We can't go further from the frame returned by GetOneMore frame. Lets try
355f73363f1SDimitry Andric // to get a different frame with using the fallback unwind plan.
35614f1b3e8SDimitry Andric if (!m_frames[m_frames.size() - 2]
35714f1b3e8SDimitry Andric ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
35814f1b3e8SDimitry Andric // We don't have a valid fallback unwind plan. Accept the frame as it is.
359f73363f1SDimitry Andric // This is a valid situation when we are at the bottom of the stack.
360027f1c96SDimitry Andric return true;
361027f1c96SDimitry Andric }
362027f1c96SDimitry Andric
36314f1b3e8SDimitry Andric // Remove the possibly incorrect frame from the frame list and try to add a
364f73363f1SDimitry Andric // different one with the newly selected fallback unwind plan.
365027f1c96SDimitry Andric m_frames.pop_back();
366027f1c96SDimitry Andric CursorSP new_frame_v2 = GetOneMoreFrame(abi);
36714f1b3e8SDimitry Andric if (new_frame_v2 == nullptr) {
36814f1b3e8SDimitry Andric // We haven't got a new frame from the fallback unwind plan. Accept the
369f73363f1SDimitry Andric // frame from the original unwind plan. This is a valid situation when we
370f73363f1SDimitry Andric // are at the bottom of the stack.
371027f1c96SDimitry Andric m_frames.push_back(new_frame);
372027f1c96SDimitry Andric return true;
373027f1c96SDimitry Andric }
374027f1c96SDimitry Andric
37514f1b3e8SDimitry Andric // Push the new frame to the list and try to continue from this frame. If we
376f73363f1SDimitry Andric // can get a new frame then accept it as the correct one.
377027f1c96SDimitry Andric m_frames.push_back(new_frame_v2);
378027f1c96SDimitry Andric m_candidate_frame = GetOneMoreFrame(abi);
37914f1b3e8SDimitry Andric if (m_candidate_frame) {
38014f1b3e8SDimitry Andric // If control reached here then TryFallbackUnwindPlan had succeeded for
381f73363f1SDimitry Andric // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next
382f73363f1SDimitry Andric // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For
383f73363f1SDimitry Andric // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already
384f73363f1SDimitry Andric // updated during TryFallbackUnwindPlan call above. However, cfa field
385f73363f1SDimitry Andric // still needs to be updated. Hence updating it here and then returning.
38694994d37SDimitry Andric return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
38794994d37SDimitry Andric m_frames[m_frames.size() - 2]->cfa);
388e81d9d49SDimitry Andric }
389027f1c96SDimitry Andric
39014f1b3e8SDimitry Andric // The new frame hasn't helped in unwinding. Fall back to the original one as
391f73363f1SDimitry Andric // the default unwind plan is usually more reliable then the fallback one.
392027f1c96SDimitry Andric m_frames.pop_back();
393027f1c96SDimitry Andric m_frames.push_back(new_frame);
394027f1c96SDimitry Andric return true;
395027f1c96SDimitry Andric }
396027f1c96SDimitry Andric
DoGetFrameInfoAtIndex(uint32_t idx,addr_t & cfa,addr_t & pc,bool & behaves_like_zeroth_frame)397ead24645SDimitry Andric bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc,
398ead24645SDimitry Andric bool &behaves_like_zeroth_frame) {
39914f1b3e8SDimitry Andric if (m_frames.size() == 0) {
400f034231aSEd Maste if (!AddFirstFrame())
401f034231aSEd Maste return false;
402f034231aSEd Maste }
403f034231aSEd Maste
404f034231aSEd Maste ProcessSP process_sp(m_thread.GetProcess());
4055f29bb8aSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
406f034231aSEd Maste
407f034231aSEd Maste while (idx >= m_frames.size() && AddOneMoreFrame(abi))
408f034231aSEd Maste ;
409f034231aSEd Maste
41014f1b3e8SDimitry Andric if (idx < m_frames.size()) {
411f034231aSEd Maste cfa = m_frames[idx]->cfa;
412f034231aSEd Maste pc = m_frames[idx]->start_pc;
413ead24645SDimitry Andric if (idx == 0) {
414ead24645SDimitry Andric // Frame zero always behaves like it.
415ead24645SDimitry Andric behaves_like_zeroth_frame = true;
416ead24645SDimitry Andric } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
417ead24645SDimitry Andric // This could be an asynchronous signal, thus the
418ead24645SDimitry Andric // pc might point to the interrupted instruction rather
419ead24645SDimitry Andric // than a post-call instruction
420ead24645SDimitry Andric behaves_like_zeroth_frame = true;
421ead24645SDimitry Andric } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
422ead24645SDimitry Andric // This frame may result from signal processing installing
423ead24645SDimitry Andric // a pointer to the first byte of a signal-return trampoline
424ead24645SDimitry Andric // in the return address slot of the frame below, so this
425ead24645SDimitry Andric // too behaves like the zeroth frame (i.e. the pc might not
426ead24645SDimitry Andric // be pointing just past a call in it)
427ead24645SDimitry Andric behaves_like_zeroth_frame = true;
428344a3780SDimitry Andric } else if (m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) {
429344a3780SDimitry Andric behaves_like_zeroth_frame = true;
430ead24645SDimitry Andric } else {
431ead24645SDimitry Andric behaves_like_zeroth_frame = false;
432ead24645SDimitry Andric }
433f034231aSEd Maste return true;
434f034231aSEd Maste }
435f034231aSEd Maste return false;
436f034231aSEd Maste }
437f034231aSEd Maste
438f034231aSEd Maste lldb::RegisterContextSP
DoCreateRegisterContextForFrame(StackFrame * frame)43914f1b3e8SDimitry Andric UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
440f034231aSEd Maste lldb::RegisterContextSP reg_ctx_sp;
441f034231aSEd Maste uint32_t idx = frame->GetConcreteFrameIndex();
442f034231aSEd Maste
44314f1b3e8SDimitry Andric if (idx == 0) {
444f034231aSEd Maste return m_thread.GetRegisterContext();
445f034231aSEd Maste }
446f034231aSEd Maste
44714f1b3e8SDimitry Andric if (m_frames.size() == 0) {
448f034231aSEd Maste if (!AddFirstFrame())
449f034231aSEd Maste return reg_ctx_sp;
450f034231aSEd Maste }
451f034231aSEd Maste
452f034231aSEd Maste ProcessSP process_sp(m_thread.GetProcess());
4535f29bb8aSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
454f034231aSEd Maste
45514f1b3e8SDimitry Andric while (idx >= m_frames.size()) {
456f034231aSEd Maste if (!AddOneMoreFrame(abi))
457f034231aSEd Maste break;
458f034231aSEd Maste }
459f034231aSEd Maste
460f034231aSEd Maste const uint32_t num_frames = m_frames.size();
46114f1b3e8SDimitry Andric if (idx < num_frames) {
462f034231aSEd Maste Cursor *frame_cursor = m_frames[idx].get();
463f034231aSEd Maste reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
464f034231aSEd Maste }
465f034231aSEd Maste return reg_ctx_sp;
466f034231aSEd Maste }
467f034231aSEd Maste
468f034231aSEd Maste UnwindLLDB::RegisterContextLLDBSP
GetRegisterContextForFrameNum(uint32_t frame_num)46914f1b3e8SDimitry Andric UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
470f034231aSEd Maste RegisterContextLLDBSP reg_ctx_sp;
471f034231aSEd Maste if (frame_num < m_frames.size())
472f034231aSEd Maste reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
473f034231aSEd Maste return reg_ctx_sp;
474f034231aSEd Maste }
475f034231aSEd Maste
SearchForSavedLocationForRegister(uint32_t lldb_regnum,lldb_private::UnwindLLDB::RegisterLocation & regloc,uint32_t starting_frame_num,bool pc_reg)47614f1b3e8SDimitry Andric bool UnwindLLDB::SearchForSavedLocationForRegister(
47714f1b3e8SDimitry Andric uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc,
47814f1b3e8SDimitry Andric uint32_t starting_frame_num, bool pc_reg) {
479f034231aSEd Maste int64_t frame_num = starting_frame_num;
4800cac4ca3SEd Maste if (static_cast<size_t>(frame_num) >= m_frames.size())
481f034231aSEd Maste return false;
482f034231aSEd Maste
483f73363f1SDimitry Andric // Never interrogate more than one level while looking for the saved pc
484f73363f1SDimitry Andric // value. If the value isn't saved by frame_num, none of the frames lower on
485f73363f1SDimitry Andric // the stack will have a useful value.
48614f1b3e8SDimitry Andric if (pc_reg) {
487f034231aSEd Maste UnwindLLDB::RegisterSearchResult result;
48814f1b3e8SDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
48914f1b3e8SDimitry Andric lldb_regnum, regloc);
49094994d37SDimitry Andric return result == UnwindLLDB::RegisterSearchResult::eRegisterFound;
491f034231aSEd Maste }
49214f1b3e8SDimitry Andric while (frame_num >= 0) {
493f034231aSEd Maste UnwindLLDB::RegisterSearchResult result;
49414f1b3e8SDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
49514f1b3e8SDimitry Andric lldb_regnum, regloc);
496f034231aSEd Maste
49714f1b3e8SDimitry Andric // We descended down to the live register context aka stack frame 0 and are
498f73363f1SDimitry Andric // reading the value out of a live register.
49914f1b3e8SDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
50014f1b3e8SDimitry Andric regloc.type ==
50114f1b3e8SDimitry Andric UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
502205afe67SEd Maste return true;
503205afe67SEd Maste }
504205afe67SEd Maste
50514f1b3e8SDimitry Andric // If we have unwind instructions saying that register N is saved in
506f73363f1SDimitry Andric // register M in the middle of the stack (and N can equal M here, meaning
507f73363f1SDimitry Andric // the register was not used in this function), then change the register
508f73363f1SDimitry Andric // number we're looking for to M and keep looking for a concrete location
50914f1b3e8SDimitry Andric // down the stack, or an actual value from a live RegisterContext at frame
51014f1b3e8SDimitry Andric // 0.
51114f1b3e8SDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
51214f1b3e8SDimitry Andric regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
51314f1b3e8SDimitry Andric frame_num > 0) {
514f034231aSEd Maste result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
515f034231aSEd Maste lldb_regnum = regloc.location.register_number;
516f034231aSEd Maste }
517f034231aSEd Maste
518f034231aSEd Maste if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
519f034231aSEd Maste return true;
520f034231aSEd Maste if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
521f034231aSEd Maste return false;
522f034231aSEd Maste frame_num--;
523f034231aSEd Maste }
524f034231aSEd Maste return false;
525f034231aSEd Maste }
526