]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/lldb-mi/MICmdCmdThread.cpp
Vendor import of stripped lldb trunk r256633:
[FreeBSD/FreeBSD.git] / tools / lldb-mi / MICmdCmdThread.cpp
1 //===-- MICmdCmdThread.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 // Overview:    CMICmdCmdThreadInfo     implementation.
11
12 // Third Party Headers:
13 #include "lldb/API/SBBreakpointLocation.h"
14 #include "lldb/API/SBThread.h"
15
16 // In-house headers:
17 #include "MICmdCmdThread.h"
18 #include "MICmnMIResultRecord.h"
19 #include "MICmnMIValueConst.h"
20 #include "MICmnLLDBDebugger.h"
21 #include "MICmnLLDBDebugSessionInfo.h"
22 #include "MICmdArgValNumber.h"
23
24 //++ ------------------------------------------------------------------------------------
25 // Details: CMICmdCmdThreadInfo constructor.
26 // Type:    Method.
27 // Args:    None.
28 // Return:  None.
29 // Throws:  None.
30 //--
31 CMICmdCmdThreadInfo::CMICmdCmdThreadInfo()
32     : m_bSingleThread(false)
33     , m_bThreadInvalid(true)
34     , m_constStrArgNamedThreadId("thread-id")
35 {
36     // Command factory matches this name with that received from the stdin stream
37     m_strMiCmd = "thread-info";
38
39     // Required by the CMICmdFactory when registering *this command
40     m_pSelfCreatorFn = &CMICmdCmdThreadInfo::CreateSelf;
41 }
42
43 //++ ------------------------------------------------------------------------------------
44 // Details: CMICmdCmdThreadInfo destructor.
45 // Type:    Overrideable.
46 // Args:    None.
47 // Return:  None.
48 // Throws:  None.
49 //--
50 CMICmdCmdThreadInfo::~CMICmdCmdThreadInfo()
51 {
52     m_vecMIValueTuple.clear();
53 }
54
55 //++ ------------------------------------------------------------------------------------
56 // Details: The invoker requires this function. The parses the command line options
57 //          arguments to extract values for each of those arguments.
58 // Type:    Overridden.
59 // Args:    None.
60 // Return:  MIstatus::success - Functional succeeded.
61 //          MIstatus::failure - Functional failed.
62 // Throws:  None.
63 //--
64 bool
65 CMICmdCmdThreadInfo::ParseArgs()
66 {
67     m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedThreadId, false, true));
68     return ParseValidateCmdOptions();
69 }
70
71 //++ ------------------------------------------------------------------------------------
72 // Details: The invoker requires this function. The command does work in this function.
73 //          The command is likely to communicate with the LLDB SBDebugger in here.
74 // Type:    Overridden.
75 // Args:    None.
76 // Return:  MIstatus::success - Functional succeeded.
77 //          MIstatus::failure - Functional failed.
78 // Throws:  None.
79 //--
80 bool
81 CMICmdCmdThreadInfo::Execute()
82 {
83     CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId);
84     MIuint nThreadId = 0;
85     if (pArgThreadId->GetFound() && pArgThreadId->GetValid())
86     {
87         m_bSingleThread = true;
88         nThreadId = static_cast<MIuint>(pArgThreadId->GetValue());
89     }
90
91     CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
92     lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
93     lldb::SBThread thread = sbProcess.GetSelectedThread();
94
95     if (m_bSingleThread)
96     {
97         thread = sbProcess.GetThreadByIndexID(nThreadId);
98         m_bThreadInvalid = !thread.IsValid();
99         if (m_bThreadInvalid)
100             return MIstatus::success;
101
102         CMICmnMIValueTuple miTuple;
103         if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
104             return MIstatus::failure;
105
106         m_miValueTupleThread = miTuple;
107
108         return MIstatus::success;
109     }
110
111     // Multiple threads
112     m_vecMIValueTuple.clear();
113     const MIuint nThreads = sbProcess.GetNumThreads();
114     for (MIuint i = 0; i < nThreads; i++)
115     {
116         lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
117         if (thread.IsValid())
118         {
119             CMICmnMIValueTuple miTuple;
120             if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
121                 return MIstatus::failure;
122
123             m_vecMIValueTuple.push_back(miTuple);
124         }
125     }
126
127     return MIstatus::success;
128 }
129
130 //++ ------------------------------------------------------------------------------------
131 // Details: The invoker requires this function. The command prepares a MI Record Result
132 //          for the work carried out in the Execute().
133 // Type:    Overridden.
134 // Args:    None.
135 // Return:  MIstatus::success - Functional succeeded.
136 //          MIstatus::failure - Functional failed.
137 // Throws:  None.
138 //--
139 bool
140 CMICmdCmdThreadInfo::Acknowledge()
141 {
142     if (m_bSingleThread)
143     {
144         if (m_bThreadInvalid)
145         {
146             const CMICmnMIValueConst miValueConst("invalid thread id");
147             const CMICmnMIValueResult miValueResult("msg", miValueConst);
148             const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
149             m_miResultRecord = miRecordResult;
150             return MIstatus::success;
151         }
152
153         // MI print "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
154         const CMICmnMIValueList miValueList(m_miValueTupleThread);
155         const CMICmnMIValueResult miValueResult("threads", miValueList);
156         const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
157         m_miResultRecord = miRecordResult;
158         return MIstatus::success;
159     }
160
161     // Build up a list of thread information from tuples
162     VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
163     if (it == m_vecMIValueTuple.end())
164     {
165         const CMICmnMIValueConst miValueConst("[]");
166         const CMICmnMIValueResult miValueResult("threads", miValueConst);
167         const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
168         m_miResultRecord = miRecordResult;
169         return MIstatus::success;
170     }
171     CMICmnMIValueList miValueList(*it);
172     ++it;
173     while (it != m_vecMIValueTuple.end())
174     {
175         const CMICmnMIValueTuple &rTuple(*it);
176         miValueList.Add(rTuple);
177
178         // Next
179         ++it;
180     }
181
182     const CMICmnMIValueResult miValueResult("threads", miValueList);
183     const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
184     m_miResultRecord = miRecordResult;
185
186     return MIstatus::success;
187 }
188
189 //++ ------------------------------------------------------------------------------------
190 // Details: Required by the CMICmdFactory when registering *this command. The factory
191 //          calls this function to create an instance of *this command.
192 // Type:    Static method.
193 // Args:    None.
194 // Return:  CMICmdBase * - Pointer to a new command.
195 // Throws:  None.
196 //--
197 CMICmdBase *
198 CMICmdCmdThreadInfo::CreateSelf()
199 {
200     return new CMICmdCmdThreadInfo();
201 }