TestCase.cpp revision e62d448f4b663edfac26b9071323606b1b5fdc1d
1//
2//  TestCase.cpp
3//  PerfTestDriver
4//
5//  Created by Enrico Granata on 3/7/13.
6//  Copyright (c) 2013 Apple Inc. All rights reserved.
7//
8
9#include "TestCase.h"
10#include "Xcode.h"
11
12using namespace lldb_perf;
13
14TestCase::TestCase () :
15    m_debugger(),
16    m_target(),
17    m_process(),
18    m_thread(),
19    m_listener(),
20    m_verbose(false),
21    m_step(0)
22{
23    SBDebugger::Initialize();
24	SBHostOS::ThreadCreated ("<lldb-tester.app.main>");
25	m_debugger = SBDebugger::Create(false);
26	m_listener = m_debugger.GetListener();
27}
28
29bool
30TestCase::Setup (int argc, const char** argv)
31{
32    return false;
33}
34
35bool
36TestCase::Launch (lldb::SBLaunchInfo &launch_info)
37{
38    lldb::SBError error;
39	m_process = m_target.Launch (launch_info, error);
40    if (!error.Success())
41        fprintf (stderr, "error: %s\n", error.GetCString());
42    if (m_process.IsValid())
43    {
44        m_process.GetBroadcaster().AddListener(m_listener, SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
45        return true;
46    }
47    return false;
48}
49
50void
51TestCase::SetVerbose (bool b)
52{
53    m_verbose = b;
54}
55
56bool
57TestCase::GetVerbose ()
58{
59    return m_verbose;
60}
61
62void
63TestCase::Loop ()
64{
65	SBEvent evt;
66	while (true)
67	{
68		m_listener.WaitForEvent (UINT32_MAX,evt);
69		StateType state = SBProcess::GetStateFromEvent (evt);
70		if (m_verbose)
71			printf("event = %s\n",SBDebugger::StateAsCString(state));
72		if (SBProcess::GetRestartedFromEvent(evt))
73			continue;
74		switch (state)
75		{
76			case eStateInvalid:
77			case eStateDetached:
78			case eStateCrashed:
79			case eStateUnloaded:
80				break;
81			case eStateExited:
82				return;
83			case eStateConnected:
84			case eStateAttaching:
85			case eStateLaunching:
86			case eStateRunning:
87			case eStateStepping:
88				continue;
89			case eStateStopped:
90			case eStateSuspended:
91			{
92				bool fatal = false;
93                bool selected_thread = false;
94				for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
95				{
96					SBThread thread(m_process.GetThreadAtIndex(thread_index));
97					SBFrame frame(thread.GetFrameAtIndex(0));
98                    bool select_thread = false;
99					StopReason stop_reason = thread.GetStopReason();
100					if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
101					switch (stop_reason)
102					{
103				        case eStopReasonNone:
104                            if (m_verbose) printf("none\n");
105                            break;
106
107				        case eStopReasonTrace:
108                            select_thread = true;
109                            if (m_verbose) printf("trace\n");
110                            break;
111
112				        case eStopReasonPlanComplete:
113                            select_thread = true;
114                            if (m_verbose) printf("plan complete\n");
115                            break;
116				        case eStopReasonThreadExiting:
117                            if (m_verbose) printf("thread exiting\n");
118                            break;
119				        case eStopReasonExec:
120                            if (m_verbose) printf("exec\n");
121                            break;
122						case eStopReasonInvalid:
123                            if (m_verbose) printf("invalid\n");
124                            break;
125			        	case eStopReasonException:
126                            select_thread = true;
127                            if (m_verbose) printf("exception\n");
128                            fatal = true;
129                            break;
130				        case eStopReasonBreakpoint:
131                            select_thread = true;
132                            if (m_verbose) printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
133                            break;
134				        case eStopReasonWatchpoint:
135                            select_thread = true;
136                            if (m_verbose) printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
137                            break;
138				        case eStopReasonSignal:
139                            select_thread = true;
140                            if (m_verbose) printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
141                            break;
142					}
143                    if (select_thread && !selected_thread)
144                    {
145                        m_thread = thread;
146                        selected_thread = m_process.SetSelectedThread(thread);
147                    }
148				}
149				if (fatal)
150				{
151					if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
152					exit(1);
153				}
154				if (m_verbose)
155					printf("RUNNING STEP %d\n",m_step);
156                ActionWanted action;
157				TestStep(m_step, action);
158				m_step++;
159                SBError err;
160				switch (action.type)
161				{
162					case ActionWanted::Type::eContinue:
163                        err = m_process.Continue();
164						break;
165                    case ActionWanted::Type::eStepOut:
166                        if (action.thread.IsValid() == false)
167                        {
168                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
169                            if (m_verbose) printf("[finish invalid] I am gonna die at step %d\n",m_step);
170                            exit(501);
171                        }
172                        m_process.SetSelectedThread(action.thread);
173                        action.thread.StepOut();
174						break;
175					case ActionWanted::Type::eNext:
176                        if (action.thread.IsValid() == false)
177                        {
178                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
179                            if (m_verbose) printf("[next invalid] I am gonna die at step %d\n",m_step);
180                            exit(500);
181                        }
182                        m_process.SetSelectedThread(action.thread);
183                        action.thread.StepOver();
184						break;
185					case ActionWanted::Type::eKill:
186						if (m_verbose) printf("I want to die\n");
187						m_process.Kill();
188						return;
189				}
190			}
191		}
192	}
193	if (GetVerbose()) printf("I am gonna die at step %d\n",m_step);
194}
195
196void
197TestCase::Run (TestCase& test, int argc, const char** argv)
198{
199    if (test.Setup(argc, argv))
200    {
201        test.Loop();
202        test.Results();
203    }
204}
205