POSIXThread.cpp revision 010a8d85100602eff09bd61a85987efd0001188a
1//===-- POSIXThread.cpp -----------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Breakpoint/Watchpoint.h"
19#include "lldb/Core/Debugger.h"
20#include "lldb/Core/State.h"
21#include "lldb/Host/Host.h"
22#include "lldb/Target/Process.h"
23#include "lldb/Target/StopInfo.h"
24#include "lldb/Target/Target.h"
25#include "POSIXStopInfo.h"
26#include "POSIXThread.h"
27#include "ProcessPOSIX.h"
28#include "ProcessPOSIXLog.h"
29#include "ProcessMonitor.h"
30#include "RegisterContext_i386.h"
31#include "RegisterContext_x86_64.h"
32#include "RegisterContextPOSIX.h"
33#include "RegisterContextLinux_x86_64.h"
34#include "RegisterContextFreeBSD_x86_64.h"
35
36#include "UnwindLLDB.h"
37
38using namespace lldb;
39using namespace lldb_private;
40
41
42POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
43    : Thread(process, tid),
44      m_frame_ap()
45{
46    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
47    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
48        log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
49
50    // Set the current watchpoints for this thread.
51    Target &target = GetProcess()->GetTarget();
52    const WatchpointList &wp_list = target.GetWatchpointList();
53    size_t wp_size = wp_list.GetSize();
54
55    for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++)
56    {
57        lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
58        if (wp.get() && wp->IsEnabled())
59        {
60            assert(EnableHardwareWatchpoint(wp.get()));
61        }
62    }
63}
64
65POSIXThread::~POSIXThread()
66{
67    DestroyThread();
68}
69
70ProcessMonitor &
71POSIXThread::GetMonitor()
72{
73    ProcessSP base = GetProcess();
74    ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base);
75    return process.GetMonitor();
76}
77
78void
79POSIXThread::RefreshStateAfterStop()
80{
81    // Invalidate all registers in our register context. We don't set "force" to
82    // true because the stop reply packet might have had some register values
83    // that were expedited and these will already be copied into the register
84    // context by the time this function gets called. The KDPRegisterContext
85    // class has been made smart enough to detect when it needs to invalidate
86    // which registers are valid by putting hooks in the register read and
87    // register supply functions where they check the process stop ID and do
88    // the right thing.
89    //if (StateIsStoppedState(GetState())
90    {
91        const bool force = false;
92        GetRegisterContext()->InvalidateIfNeeded (force);
93    }
94    // FIXME: This should probably happen somewhere else.
95    SetResumeState(eStateRunning);
96    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
97    if (log)
98        log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to running", __FUNCTION__, GetID());
99}
100
101const char *
102POSIXThread::GetInfo()
103{
104    return NULL;
105}
106
107lldb::RegisterContextSP
108POSIXThread::GetRegisterContext()
109{
110    if (!m_reg_context_sp)
111    {
112        ArchSpec arch = Host::GetArchitecture();
113
114        switch (arch.GetCore())
115        {
116        default:
117            assert(false && "CPU type not supported!");
118            break;
119
120        case ArchSpec::eCore_x86_32_i386:
121        case ArchSpec::eCore_x86_32_i486:
122        case ArchSpec::eCore_x86_32_i486sx:
123            m_reg_context_sp.reset(new RegisterContext_i386(*this, 0));
124            break;
125
126        case ArchSpec::eCore_x86_64_x86_64:
127// TODO: Use target OS/architecture detection rather than ifdefs so that
128// lldb built on FreeBSD can debug on Linux and vice-versa.
129#ifdef __linux__
130            m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
131#endif
132#ifdef __FreeBSD__
133            m_reg_context_sp.reset(new RegisterContextFreeBSD_x86_64(*this, 0));
134#endif
135            break;
136        }
137    }
138    return m_reg_context_sp;
139}
140
141lldb::RegisterContextSP
142POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
143{
144    lldb::RegisterContextSP reg_ctx_sp;
145    uint32_t concrete_frame_idx = 0;
146
147    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
148    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
149        log->Printf ("POSIXThread::%s ()", __FUNCTION__);
150
151    if (frame)
152        concrete_frame_idx = frame->GetConcreteFrameIndex();
153
154    if (concrete_frame_idx == 0)
155        reg_ctx_sp = GetRegisterContext();
156    else
157    {
158        assert(GetUnwinder());
159        reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
160    }
161
162    return reg_ctx_sp;
163}
164
165bool
166POSIXThread::CalculateStopInfo()
167{
168    SetStopInfo (m_stop_info_sp);
169    return true;
170}
171
172Unwind *
173POSIXThread::GetUnwinder()
174{
175    if (m_unwinder_ap.get() == NULL)
176        m_unwinder_ap.reset(new UnwindLLDB(*this));
177
178    return m_unwinder_ap.get();
179}
180
181void
182POSIXThread::WillResume(lldb::StateType resume_state)
183{
184    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
185    if (log)
186        log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to %s", __FUNCTION__, GetID(), StateAsCString(resume_state));
187    // TODO: the line below shouldn't really be done, but
188    // the POSIXThread might rely on this so I will leave this in for now
189    SetResumeState(resume_state);
190}
191
192void
193POSIXThread::DidStop()
194{
195    // Don't set the thread state to stopped unless we really stopped.
196}
197
198bool
199POSIXThread::Resume()
200{
201    lldb::StateType resume_state = GetResumeState();
202    ProcessMonitor &monitor = GetMonitor();
203    bool status;
204
205    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
206    if (log)
207        log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__,
208                         StateAsCString(resume_state));
209
210    switch (resume_state)
211    {
212    default:
213        assert(false && "Unexpected state for resume!");
214        status = false;
215        break;
216
217    case lldb::eStateRunning:
218        SetState(resume_state);
219        status = monitor.Resume(GetID(), GetResumeSignal());
220        break;
221
222    case lldb::eStateStepping:
223        SetState(resume_state);
224        status = monitor.SingleStep(GetID(), GetResumeSignal());
225        break;
226    case lldb::eStateStopped:
227    case lldb::eStateSuspended:
228        status = true;
229        break;
230    }
231
232    return status;
233}
234
235void
236POSIXThread::Notify(const ProcessMessage &message)
237{
238    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
239    if (log)
240        log->Printf ("POSIXThread::%s () message kind = '%s' for tid %" PRIu64,
241                     __FUNCTION__, message.PrintKind(), GetID());
242
243    switch (message.GetKind())
244    {
245    default:
246        assert(false && "Unexpected message kind!");
247        break;
248
249    case ProcessMessage::eExitMessage:
250        // Nothing to be done.
251        break;
252
253    case ProcessMessage::eLimboMessage:
254        LimboNotify(message);
255        break;
256
257    case ProcessMessage::eSignalMessage:
258        SignalNotify(message);
259        break;
260
261    case ProcessMessage::eSignalDeliveredMessage:
262        SignalDeliveredNotify(message);
263        break;
264
265    case ProcessMessage::eTraceMessage:
266        TraceNotify(message);
267        break;
268
269    case ProcessMessage::eBreakpointMessage:
270        BreakNotify(message);
271        break;
272
273    case ProcessMessage::eWatchpointMessage:
274        WatchNotify(message);
275        break;
276
277    case ProcessMessage::eCrashMessage:
278        CrashNotify(message);
279        break;
280
281    case ProcessMessage::eNewThreadMessage:
282        ThreadNotify(message);
283        break;
284    }
285}
286
287bool
288POSIXThread::EnableHardwareWatchpoint(Watchpoint *wp)
289{
290    bool wp_set = false;
291    if (wp)
292    {
293        addr_t wp_addr = wp->GetLoadAddress();
294        size_t wp_size = wp->GetByteSize();
295        bool wp_read = wp->WatchpointRead();
296        bool wp_write = wp->WatchpointWrite();
297        uint32_t wp_hw_index = wp->GetHardwareIndex();
298        RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
299        if (reg_ctx)
300            wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size,
301                                                             wp_read, wp_write,
302                                                             wp_hw_index);
303    }
304    return wp_set;
305}
306
307bool
308POSIXThread::DisableHardwareWatchpoint(Watchpoint *wp)
309{
310    bool result = false;
311    if (wp)
312    {
313        lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
314        if (reg_ctx_sp.get())
315            result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
316    }
317    return result;
318}
319
320uint32_t
321POSIXThread::NumSupportedHardwareWatchpoints()
322{
323    lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
324    if (reg_ctx_sp.get())
325        return reg_ctx_sp->NumSupportedHardwareWatchpoints();
326    return 0;
327}
328
329uint32_t
330POSIXThread::FindVacantWatchpointIndex()
331{
332    uint32_t hw_index = LLDB_INVALID_INDEX32;
333    uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
334    uint32_t wp_idx;
335    RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
336    if (reg_ctx)
337    {
338        for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
339        {
340            if (reg_ctx->IsWatchpointVacant(wp_idx))
341            {
342                hw_index = wp_idx;
343                break;
344            }
345        }
346    }
347    return hw_index;
348}
349
350void
351POSIXThread::BreakNotify(const ProcessMessage &message)
352{
353    bool status;
354    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
355
356    assert(GetRegisterContext());
357    status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
358    assert(status && "Breakpoint update failed!");
359
360    // With our register state restored, resolve the breakpoint object
361    // corresponding to our current PC.
362    assert(GetRegisterContext());
363    lldb::addr_t pc = GetRegisterContext()->GetPC();
364    if (log)
365        log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
366    lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
367    assert(bp_site);
368    lldb::break_id_t bp_id = bp_site->GetID();
369    assert(bp_site && bp_site->ValidForThisThread(this));
370
371    // Make this thread the selected thread
372    GetProcess()->GetThreadList().SetSelectedThreadByID(GetID());
373
374    m_breakpoint = bp_site;
375    SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
376}
377
378void
379POSIXThread::WatchNotify(const ProcessMessage &message)
380{
381    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
382
383    lldb::addr_t halt_addr = message.GetHWAddress();
384    if (log)
385        log->Printf ("POSIXThread::%s () Hardware Watchpoint Address = 0x%8.8"
386                     PRIx64, __FUNCTION__, halt_addr);
387
388    RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
389    if (reg_ctx)
390    {
391        uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
392        uint32_t wp_idx;
393        for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
394        {
395            if (reg_ctx->IsWatchpointHit(wp_idx))
396            {
397                // Clear the watchpoint hit here
398                reg_ctx->ClearWatchpointHits();
399                break;
400            }
401        }
402
403        if (wp_idx == num_hw_wps)
404            return;
405
406        Target &target = GetProcess()->GetTarget();
407        lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
408        const WatchpointList &wp_list = target.GetWatchpointList();
409        lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
410
411        if (wp_sp)
412            SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this,
413                                                                    wp_sp->GetID()));
414    }
415}
416
417void
418POSIXThread::TraceNotify(const ProcessMessage &message)
419{
420    RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
421    if (reg_ctx)
422    {
423        uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
424        uint32_t wp_idx;
425        for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
426        {
427            if (reg_ctx->IsWatchpointHit(wp_idx))
428            {
429                WatchNotify(message);
430                return;
431            }
432        }
433    }
434    SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
435}
436
437void
438POSIXThread::LimboNotify(const ProcessMessage &message)
439{
440    SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
441}
442
443void
444POSIXThread::SignalNotify(const ProcessMessage &message)
445{
446    int signo = message.GetSignal();
447
448    SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
449    SetResumeSignal(signo);
450}
451
452void
453POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
454{
455    int signo = message.GetSignal();
456
457    SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
458    SetResumeSignal(signo);
459}
460
461void
462POSIXThread::CrashNotify(const ProcessMessage &message)
463{
464    // FIXME: Update stop reason as per bugzilla 14598
465    int signo = message.GetSignal();
466
467    assert(message.GetKind() == ProcessMessage::eCrashMessage);
468
469    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
470    if (log)
471        log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'",
472                     __FUNCTION__, signo, message.PrintCrashReason());
473
474    SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo,
475                                                         message.GetCrashReason(),
476                                                         message.GetFaultAddress())));
477    SetResumeSignal(signo);
478}
479
480void
481POSIXThread::ThreadNotify(const ProcessMessage &message)
482{
483    SetStopInfo (lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this)));
484}
485
486unsigned
487POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
488{
489    unsigned reg;
490    ArchSpec arch = Host::GetArchitecture();
491
492    switch (arch.GetCore())
493    {
494    default:
495        assert(false && "CPU type not supported!");
496        break;
497
498    case ArchSpec::eCore_x86_32_i386:
499    case ArchSpec::eCore_x86_32_i486:
500    case ArchSpec::eCore_x86_32_i486sx:
501    case ArchSpec::eCore_x86_64_x86_64:
502        {
503            RegisterContextSP base = GetRegisterContext();
504            if (base) {
505                RegisterContextPOSIX &context = static_cast<RegisterContextPOSIX &>(*base);
506                reg = context.GetRegisterIndexFromOffset(offset);
507            }
508        }
509        break;
510    }
511    return reg;
512}
513
514const char *
515POSIXThread::GetRegisterName(unsigned reg)
516{
517    const char * name = nullptr;
518    ArchSpec arch = Host::GetArchitecture();
519
520    switch (arch.GetCore())
521    {
522    default:
523        assert(false && "CPU type not supported!");
524        break;
525
526    case ArchSpec::eCore_x86_32_i386:
527    case ArchSpec::eCore_x86_32_i486:
528    case ArchSpec::eCore_x86_32_i486sx:
529    case ArchSpec::eCore_x86_64_x86_64:
530        name = GetRegisterContext()->GetRegisterName(reg);
531        break;
532    }
533    return name;
534}
535
536const char *
537POSIXThread::GetRegisterNameFromOffset(unsigned offset)
538{
539    return GetRegisterName(GetRegisterIndexFromOffset(offset));
540}
541
542