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