blob: c4b01998c23d30a2602623794756297edefc1ff4 [file] [log] [blame]
Greg Clayton5dbe5d42013-03-21 03:39:51 +00001//===-- TestCase.cpp --------------------------------------------*- C++ -*-===//
Enrico Granataf58cece2013-03-08 20:29:13 +00002//
Greg Clayton5dbe5d42013-03-21 03:39:51 +00003// The LLVM Compiler Infrastructure
Enrico Granataf58cece2013-03-08 20:29:13 +00004//
Greg Clayton5dbe5d42013-03-21 03:39:51 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Enrico Granataf58cece2013-03-08 20:29:13 +00007//
Greg Clayton5dbe5d42013-03-21 03:39:51 +00008//===----------------------------------------------------------------------===//
Enrico Granataf58cece2013-03-08 20:29:13 +00009
10#include "TestCase.h"
Greg Clayton880afc52013-03-22 02:31:35 +000011#include "Results.h"
Enrico Granataf58cece2013-03-08 20:29:13 +000012#include "Xcode.h"
13
Greg Clayton7b8f7382013-03-18 22:34:00 +000014using namespace lldb_perf;
Enrico Granataf58cece2013-03-08 20:29:13 +000015
16TestCase::TestCase () :
Greg Claytone0b924e2013-03-19 04:41:22 +000017 m_debugger(),
18 m_target(),
19 m_process(),
20 m_thread(),
21 m_listener(),
Enrico Granatae16dfcd2013-03-20 22:42:34 +000022 m_verbose(false),
23 m_step(0)
Enrico Granataf58cece2013-03-08 20:29:13 +000024{
Enrico Granata86910572013-03-14 19:00:42 +000025 SBDebugger::Initialize();
Enrico Granataf58cece2013-03-08 20:29:13 +000026 SBHostOS::ThreadCreated ("<lldb-tester.app.main>");
27 m_debugger = SBDebugger::Create(false);
28 m_listener = m_debugger.GetListener();
29}
30
Enrico Granata8fab9fd2013-04-01 18:02:25 +000031static std::string
32GetShortOptionString (struct option *long_options)
Greg Claytone0b924e2013-03-19 04:41:22 +000033{
Enrico Granata8fab9fd2013-04-01 18:02:25 +000034 std::string option_string;
35 for (int i = 0; long_options[i].name != NULL; ++i)
36 {
37 if (long_options[i].flag == NULL)
38 {
39 option_string.push_back ((char) long_options[i].val);
40 switch (long_options[i].has_arg)
41 {
42 default:
43 case no_argument:
44 break;
45 case required_argument:
46 option_string.push_back (':');
47 break;
48 case optional_argument:
49 option_string.append (2, ':');
50 break;
51 }
52 }
53 }
54 return option_string;
55}
56
57bool
58TestCase::Setup (int& argc, const char**& argv)
59{
60 bool done = false;
61
62 struct option* long_options = GetLongOptions();
63
64 if (long_options)
65 {
66 std::string short_option_string (GetShortOptionString(long_options));
67
68 #if __GLIBC__
69 optind = 0;
70 #else
71 optreset = 1;
72 optind = 1;
73 #endif
74 while (!done)
75 {
76 int long_options_index = -1;
77 const int short_option = ::getopt_long_only (argc,
78 const_cast<char **>(argv),
79 short_option_string.c_str(),
80 long_options,
81 &long_options_index);
82
83 switch (short_option)
84 {
85 case 0:
86 // Already handled
87 break;
88
89 case -1:
90 done = true;
91 break;
92
93 default:
94 done = !ParseOption(short_option, optarg);
95 break;
96 }
97 }
98 argc -= optind;
99 argv += optind;
100 }
101
Greg Claytone0b924e2013-03-19 04:41:22 +0000102 return false;
103}
Enrico Granata86910572013-03-14 19:00:42 +0000104
Enrico Granataf58cece2013-03-08 20:29:13 +0000105bool
Greg Claytone0b924e2013-03-19 04:41:22 +0000106TestCase::Launch (lldb::SBLaunchInfo &launch_info)
Enrico Granataf58cece2013-03-08 20:29:13 +0000107{
Greg Claytone0b924e2013-03-19 04:41:22 +0000108 lldb::SBError error;
109 m_process = m_target.Launch (launch_info, error);
110 if (!error.Success())
111 fprintf (stderr, "error: %s\n", error.GetCString());
112 if (m_process.IsValid())
113 {
114 m_process.GetBroadcaster().AddListener(m_listener, SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
115 return true;
116 }
117 return false;
Enrico Granataf58cece2013-03-08 20:29:13 +0000118}
119
120void
121TestCase::SetVerbose (bool b)
122{
123 m_verbose = b;
124}
125
126bool
127TestCase::GetVerbose ()
128{
129 return m_verbose;
130}
131
132void
133TestCase::Loop ()
134{
Enrico Granataf58cece2013-03-08 20:29:13 +0000135 while (true)
136 {
Greg Clayton880afc52013-03-22 02:31:35 +0000137 bool call_test_step = false;
138 if (m_process.IsValid())
139 {
140 SBEvent evt;
141 m_listener.WaitForEvent (UINT32_MAX, evt);
142 StateType state = SBProcess::GetStateFromEvent (evt);
143 if (m_verbose)
144 printf("event = %s\n",SBDebugger::StateAsCString(state));
145 if (SBProcess::GetRestartedFromEvent(evt))
146 continue;
147 switch (state)
148 {
149 case eStateInvalid:
150 case eStateDetached:
151 case eStateCrashed:
152 case eStateUnloaded:
153 break;
154 case eStateExited:
155 return;
156 case eStateConnected:
157 case eStateAttaching:
158 case eStateLaunching:
159 case eStateRunning:
160 case eStateStepping:
161 continue;
162 case eStateStopped:
163 case eStateSuspended:
164 {
165 call_test_step = true;
166 bool fatal = false;
167 bool selected_thread = false;
168 for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
Greg Claytone0b924e2013-03-19 04:41:22 +0000169 {
Greg Clayton880afc52013-03-22 02:31:35 +0000170 SBThread thread(m_process.GetThreadAtIndex(thread_index));
171 SBFrame frame(thread.GetFrameAtIndex(0));
172 bool select_thread = false;
173 StopReason stop_reason = thread.GetStopReason();
174 if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
175 switch (stop_reason)
176 {
177 case eStopReasonNone:
178 if (m_verbose)
179 printf("none\n");
180 break;
181
182 case eStopReasonTrace:
183 select_thread = true;
184 if (m_verbose)
185 printf("trace\n");
186 break;
187
188 case eStopReasonPlanComplete:
189 select_thread = true;
190 if (m_verbose)
191 printf("plan complete\n");
192 break;
193 case eStopReasonThreadExiting:
194 if (m_verbose)
195 printf("thread exiting\n");
196 break;
197 case eStopReasonExec:
198 if (m_verbose)
199 printf("exec\n");
200 break;
201 case eStopReasonInvalid:
202 if (m_verbose)
203 printf("invalid\n");
204 break;
205 case eStopReasonException:
206 select_thread = true;
207 if (m_verbose)
208 printf("exception\n");
209 fatal = true;
210 break;
211 case eStopReasonBreakpoint:
212 select_thread = true;
213 if (m_verbose)
214 printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
215 break;
216 case eStopReasonWatchpoint:
217 select_thread = true;
218 if (m_verbose)
219 printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
220 break;
221 case eStopReasonSignal:
222 select_thread = true;
223 if (m_verbose)
224 printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
225 break;
226 }
227 if (select_thread && !selected_thread)
228 {
229 m_thread = thread;
230 selected_thread = m_process.SetSelectedThread(thread);
231 }
Greg Claytone0b924e2013-03-19 04:41:22 +0000232 }
Greg Clayton880afc52013-03-22 02:31:35 +0000233 if (fatal)
234 {
235 if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
236 exit(1);
237 }
238 }
239 break;
Enrico Granataf58cece2013-03-08 20:29:13 +0000240 }
241 }
Greg Clayton880afc52013-03-22 02:31:35 +0000242 else
243 {
244 call_test_step = true;
245 }
246
247 if (call_test_step)
248 {
249 if (m_verbose)
250 printf("RUNNING STEP %d\n",m_step);
251 ActionWanted action;
252 TestStep(m_step, action);
253 m_step++;
254 SBError err;
255 switch (action.type)
256 {
257 case ActionWanted::Type::eContinue:
258 err = m_process.Continue();
259 break;
260 case ActionWanted::Type::eStepOut:
261 if (action.thread.IsValid() == false)
262 {
263 if (m_verbose)
264 {
265 Xcode::RunCommand(m_debugger,"bt all",true);
266 printf("error: invalid thread for step out on step %d\n", m_step);
267 }
268 exit(501);
269 }
270 m_process.SetSelectedThread(action.thread);
271 action.thread.StepOut();
272 break;
273 case ActionWanted::Type::eStepOver:
274 if (action.thread.IsValid() == false)
275 {
276 if (m_verbose)
277 {
278 Xcode::RunCommand(m_debugger,"bt all",true);
279 printf("error: invalid thread for step over %d\n",m_step);
280 }
281 exit(500);
282 }
283 m_process.SetSelectedThread(action.thread);
284 action.thread.StepOver();
285 break;
286 case ActionWanted::Type::eKill:
287 if (m_verbose)
288 printf("kill\n");
289 m_process.Kill();
290 return;
291 }
292 }
293
Enrico Granataf58cece2013-03-08 20:29:13 +0000294 }
Greg Clayton880afc52013-03-22 02:31:35 +0000295
Enrico Granatae16dfcd2013-03-20 22:42:34 +0000296 if (GetVerbose()) printf("I am gonna die at step %d\n",m_step);
Enrico Granataf58cece2013-03-08 20:29:13 +0000297}
298
299void
300TestCase::Run (TestCase& test, int argc, const char** argv)
301{
Greg Claytone0b924e2013-03-19 04:41:22 +0000302 if (test.Setup(argc, argv))
303 {
304 test.Loop();
Greg Clayton880afc52013-03-22 02:31:35 +0000305 Results results;
306 test.WriteResults(results);
Greg Claytone0b924e2013-03-19 04:41:22 +0000307 }
Enrico Granataf58cece2013-03-08 20:29:13 +0000308}
Greg Clayton880afc52013-03-22 02:31:35 +0000309