1d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
2d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea// LLDB C++ API Test: verify the event description as obtained by calling
3d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea// SBEvent::GetCStringFromEvent that is received by an
4d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea// SBListener object registered with a process with a breakpoint.
5d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
6d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include <atomic>
7d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include <iostream>
8d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include <string>
9d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include <thread>
10d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
11d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include "lldb-headers.h"
12d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
13d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea#include "common.h"
14d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
15d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleausing namespace lldb;
16d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleausing namespace std;
17d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
18d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea// listener thread control
19d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleaextern atomic<bool> g_done;
20d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
21d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleamultithreaded_queue<string> g_thread_descriptions;
22d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleamultithreaded_queue<string> g_frame_functions;
23d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
24d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleaextern SBListener g_listener;
25d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
26d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleavoid listener_func() {
27d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  while (!g_done) {
28d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    SBEvent event;
29d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    bool got_event = g_listener.WaitForEvent(1, event);
30d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    if (got_event) {
31d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      if (!event.IsValid())
32d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        throw Exception("event is not valid in listener thread");
33d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
34d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      // send process description
35d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      SBProcess process = SBProcess::GetProcessFromEvent(event);
36d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      SBStream description;
37d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
38d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      for (int i = 0; i < process.GetNumThreads(); ++i) {
39d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        // send each thread description
40d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        description.Clear();
41d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        SBThread thread = process.GetThreadAtIndex(i);
42d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        thread.GetDescription(description);
43d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        g_thread_descriptions.push(description.GetData());
44d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
45d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        // send each frame function name
46d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        uint32_t num_frames = thread.GetNumFrames();
47d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        for(int j = 0; j < num_frames; ++j) {
48d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea          const char* function_name = thread.GetFrameAtIndex(j).GetFunction().GetName();
49d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea          if (function_name)
50d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea            g_frame_functions.push(function_name);
51d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea        }
52d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea      }
53d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    }
54d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  }
55d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea}
56d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
57d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Maleavoid check_listener(SBDebugger &dbg) {
58d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  // check thread description
59d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  bool got_description = false;
60d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  string desc = g_thread_descriptions.pop(5, got_description);
61d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  if (!got_description)
62d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    throw Exception("Expected at least one thread description string");
63d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea
64d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  // check at least one frame has a function name
65d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  desc = g_frame_functions.pop(5, got_description);
66d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea  if (!got_description)
67d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea    throw Exception("Expected at least one frame function name string");
68d2771ed2249c645019b7b1e46bdd677d2ed1cfe1Daniel Malea}
69