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