| |
| // LLDB C++ API Test: verify the event description that is received by an |
| // SBListener object registered with a process with a breakpoint. |
| |
| #include <atomic> |
| #include <array> |
| #include <iostream> |
| #include <string> |
| #include <thread> |
| |
| %include_SB_APIs% |
| |
| #include "common.h" |
| |
| using namespace lldb; |
| using namespace std; |
| |
| // listener thread control |
| extern atomic<bool> g_done; |
| extern SBListener g_listener; |
| |
| multithreaded_queue<string> g_event_descriptions; |
| string g_error_desc; |
| |
| void listener_func() { |
| while (!g_done) { |
| SBEvent event; |
| bool got_event = g_listener.WaitForEvent(1, event); |
| |
| if (got_event) { |
| if (!event.IsValid()) |
| throw Exception("event is not valid in listener thread"); |
| |
| SBStream description; |
| event.GetDescription(description); |
| string str(description.GetData()); |
| g_event_descriptions.push(str); |
| } |
| } |
| } |
| |
| bool check_state(string &state, string &desc, bool got_description) |
| { |
| g_error_desc.clear(); |
| |
| if(!got_description) |
| { |
| g_error_desc.append("Did not get expected event description"); |
| return false; |
| } |
| |
| if (desc.find("state-changed") == desc.npos) |
| g_error_desc.append("Event description incorrect: missing 'state-changed' "); |
| |
| if (desc.find("pid = ") == desc.npos) |
| g_error_desc.append("Event description incorrect: missing process pid "); |
| |
| string state_search_str = "state = " + state; |
| if (desc.find(state_search_str) == desc.npos) |
| { |
| string errString = ("Event description incorrect: expected state " |
| + state |
| + " but desc was " |
| + desc); |
| g_error_desc.append(errString); |
| } |
| |
| if (g_error_desc.length() > 0) |
| return false; |
| |
| cout << "check_state: " << state << " OK\n"; |
| return true; |
| } |
| |
| void check_listener(SBDebugger &dbg) |
| { |
| bool got_description; |
| string state; |
| |
| // check for "launching" state, this may or may not be present |
| string desc = g_event_descriptions.pop(5, got_description); |
| state = "launching"; |
| if (check_state(state, desc, got_description)) |
| { |
| // found a 'launching' state, pop next one from queue |
| desc = g_event_descriptions.pop(5, got_description); |
| } |
| |
| state = "running"; |
| if( !check_state(state, desc, got_description) ) |
| throw Exception(g_error_desc); |
| |
| desc = g_event_descriptions.pop(5, got_description); |
| state = "stopped"; |
| if( !check_state(state, desc, got_description) ) |
| throw Exception(g_error_desc); |
| } |