summaryrefslogtreecommitdiffhomepage
path: root/dev/DebuggerKit/src/POSIXMachContractCLI.cc
blob: 5edd65e3e8637cf90e56440cc12a60b110016926 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/***
  DebuggerKit
  (C) 2025 Amlal El Mahrouss
  File: POSIXMachContract.cc
  Purpose: OS X/Darwin Debugger
*/

#ifdef DK_MACH_DEBUGGER

#include <CompilerKit/Defines.h>
#include <DebuggerKit/POSIXMachContract.h>
#include <ThirdParty/Dialogs.h>
#include <DebuggerKit/CommonCLI.inl>

/// @internal
/// @brief Handles CTRL-C signal on debugger.
static void dbgi_ctrlc_handler(std::int32_t _) {
  if (!kPID) {
    return;
  }

  kDebugger.Break();

  pfd::notify("Debugger Event", "Breakpoint hit!");

  kKeepRunning = false;
}

NECTI_MODULE(DebuggerMachPOSIX) {
  pfd::notify("Debugger Event",
              "Userland Debugger\n(C) 2025 Amlal El Mahrouss, Licensed under Apache 2.0.");

  if (argc >= 3 && std::string(argv[1]) == "-p" && argv[2] != nullptr) {
    kPath = argv[2];
    kDebugger.SetPath(kPath);

    kStdOut << "[+] Image set to: " << kPath << "\n";
  } else {
    kStdOut << "usage: " << argv[0] << " -p <path>\n";
    kStdOut << "example: " << argv[0] << " -p /path/to/program\n";

    return EXIT_FAILURE;
  }

  CompilerKit::install_signal(SIGINT, dbgi_ctrlc_handler);

  while (YES) {
    if (kKeepRunning) {
      continue;
    }

    std::string cmd;
    if (!std::getline(std::cin, cmd)) break;

    if (cmd == "c" || cmd == "cont" || cmd == "continue") {
      if (kDebugger.Continue()) {
        kKeepRunning = true;

        kStdOut << "[+] Continuing...\n";

        pfd::notify("Debugger Event", "Continuing...");
      }
    }

    if (cmd == "d" || cmd == "detach") kDebugger.Detach();

    if (cmd == "start") {
      kStdOut << "[?] Enter a argument to use: ";
      std::getline(std::cin, cmd);

      kDebugger.Attach(kPath, cmd, kPID);
    }

    if (cmd == "exit") {
      if (kPID > 0) kDebugger.Detach();

      break;
    }

    if (cmd == "break" || cmd == "b") {
      kStdOut << "[?] Enter a symbol to break on: ";

      std::getline(std::cin, cmd);

      if (kDebugger.BreakAt(cmd)) {
        pfd::notify("Debugger Event", "Add BreakAt at: " + cmd);
      }
    }
  }

  return EXIT_SUCCESS;
}

#endif