Debug.h revision 276479
1//===-- Debug.h -------------------------------------------------*- 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#ifndef liblldb_Debug_h_
11#define liblldb_Debug_h_
12
13#include <vector>
14#include "lldb/lldb-private.h"
15
16namespace lldb_private {
17
18    //------------------------------------------------------------------
19    // Tells a thread what it needs to do when the process is resumed.
20    //------------------------------------------------------------------
21    struct ResumeAction
22    {
23        lldb::tid_t tid;        // The thread ID that this action applies to, LLDB_INVALID_THREAD_ID for the default thread action
24        lldb::StateType state;  // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping.
25        int signal;             // When resuming this thread, resume it with this signal if this value is > 0
26    };
27
28    //------------------------------------------------------------------
29    // A class that contains instructions for all threads for
30    // NativeProcessProtocol::Resume(). Each thread can either run, stay
31    // suspended, or step when the process is resumed. We optionally
32    // have the ability to also send a signal to the thread when the
33    // action is run or step.
34    //------------------------------------------------------------------
35    class ResumeActionList
36    {
37    public:
38        ResumeActionList () :
39            m_actions (),
40            m_signal_handled ()
41        {
42        }
43
44        ResumeActionList (lldb::StateType default_action, int signal) :
45            m_actions(),
46            m_signal_handled ()
47        {
48            SetDefaultThreadActionIfNeeded (default_action, signal);
49        }
50
51        ResumeActionList (const ResumeAction *actions, size_t num_actions) :
52            m_actions (),
53            m_signal_handled ()
54        {
55            if (actions && num_actions)
56            {
57                m_actions.assign (actions, actions + num_actions);
58                m_signal_handled.assign (num_actions, false);
59            }
60        }
61
62        ~ResumeActionList()
63        {
64        }
65
66        bool
67        IsEmpty() const
68        {
69            return m_actions.empty();
70        }
71
72        void
73        Append (const ResumeAction &action)
74        {
75            m_actions.push_back (action);
76            m_signal_handled.push_back (false);
77        }
78
79        void
80        AppendAction (lldb::tid_t tid,
81                      lldb::StateType state,
82                      int signal = 0)
83        {
84            ResumeAction action = { tid, state, signal };
85            Append (action);
86        }
87
88        void
89        AppendResumeAll ()
90        {
91            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
92        }
93
94        void
95        AppendSuspendAll ()
96        {
97            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
98        }
99
100        void
101        AppendStepAll ()
102        {
103            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
104        }
105
106        const ResumeAction *
107        GetActionForThread (lldb::tid_t tid, bool default_ok) const
108        {
109            const size_t num_actions = m_actions.size();
110            for (size_t i=0; i<num_actions; ++i)
111            {
112                if (m_actions[i].tid == tid)
113                    return &m_actions[i];
114            }
115            if (default_ok && tid != LLDB_INVALID_THREAD_ID)
116                return GetActionForThread (LLDB_INVALID_THREAD_ID, false);
117            return NULL;
118        }
119
120        size_t
121        NumActionsWithState (lldb::StateType state) const
122        {
123            size_t count = 0;
124            const size_t num_actions = m_actions.size();
125            for (size_t i=0; i<num_actions; ++i)
126            {
127                if (m_actions[i].state == state)
128                    ++count;
129            }
130            return count;
131        }
132
133        bool
134        SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal)
135        {
136            if (GetActionForThread (LLDB_INVALID_THREAD_ID, true) == NULL)
137            {
138                // There isn't a default action so we do need to set it.
139                ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal };
140                m_actions.push_back (default_action);
141                m_signal_handled.push_back (false);
142                return true; // Return true as we did add the default action
143            }
144            return false;
145        }
146
147        void
148        SetSignalHandledForThread (lldb::tid_t tid) const
149        {
150            if (tid != LLDB_INVALID_THREAD_ID)
151            {
152                const size_t num_actions = m_actions.size();
153                for (size_t i=0; i<num_actions; ++i)
154                {
155                    if (m_actions[i].tid == tid)
156                        m_signal_handled[i] = true;
157                }
158            }
159        }
160
161        const ResumeAction *
162        GetFirst() const
163        {
164            return m_actions.data();
165        }
166
167        size_t
168        GetSize () const
169        {
170            return m_actions.size();
171        }
172
173        void
174        Clear()
175        {
176            m_actions.clear();
177            m_signal_handled.clear();
178        }
179
180    protected:
181        std::vector<ResumeAction> m_actions;
182        mutable std::vector<bool> m_signal_handled;
183    };
184
185    struct ThreadStopInfo
186    {
187        lldb::StopReason reason;
188        union
189        {
190            // eStopReasonSignal
191            struct
192            {
193                uint32_t signo;
194            } signal;
195
196            // eStopReasonException
197            struct
198            {
199                uint64_t type;
200                uint32_t data_count;
201                lldb::addr_t data[2];
202            } exception;
203        } details;
204    };
205}
206#endif // #ifndef liblldb_Debug_h_
207