Skip to content

Commit be37853

Browse files
author
kr-2003
committed
out-of-process JIT execution
1 parent a6a02dc commit be37853

File tree

4 files changed

+230
-347
lines changed

4 files changed

+230
-347
lines changed

include/xeus-cpp/xdebugger.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ namespace xcpp
6969
bool m_is_running;
7070
int m_tcp_socket;
7171
bool m_tcp_connected;
72-
std::string jit_process_pid;
72+
pid_t jit_process_pid;
7373
};
7474

7575
XEUS_CPP_API

include/xeus-cpp/xinterpreter.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace xcpp
4040
void publish_stdout(const std::string&);
4141
void publish_stderr(const std::string&);
4242

43-
static std::string get_current_pid();
43+
static pid_t get_current_pid();
4444

4545
private:
4646

src/xdebugger.cpp

Lines changed: 54 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -61,197 +61,97 @@ namespace xcpp
6161

6262
debugger::~debugger()
6363
{
64-
std::cout << "Stopping debugger..........." << std::endl;
6564
delete p_debuglldb_client;
6665
p_debuglldb_client = nullptr;
6766
}
6867

6968
bool debugger::start_lldb()
7069
{
71-
std::cout << "debugger::start_lldb" << std::endl;
72-
jit_process_pid = xcpp::interpreter::get_current_pid();
70+
jit_process_pid = interpreter::get_current_pid();
7371

74-
// Find a free port for LLDB-DAP
7572
m_lldb_port = xeus::find_free_port(100, 9999, 10099);
7673
if (m_lldb_port.empty())
7774
{
78-
std::cout << "Failed to find a free port for LLDB-DAP" << std::endl;
75+
std::cerr << "Failed to find a free port for LLDB-DAP" << std::endl;
7976
return false;
8077
}
8178

82-
// Log debugger configuration if XEUS_LOG is set
83-
if (std::getenv("XEUS_LOG") != nullptr)
79+
if (std::getenv("XEUS_LOG"))
8480
{
85-
std::ofstream out("xeus.log", std::ios_base::app);
86-
out << "===== DEBUGGER CONFIG =====" << std::endl;
87-
out << m_debugger_config.dump() << std::endl;
81+
std::ofstream log("xeus.log", std::ios::app);
82+
log << "===== DEBUGGER CONFIG =====\n";
83+
log << m_debugger_config.dump(4) << '\n';
8884
}
8985

90-
// Build C++ code to start LLDB-DAP process
91-
std::string code = "#include <iostream>\n";
92-
code += "#include <string>\n";
93-
code += "#include <vector>\n";
94-
code += "#include <cstdlib>\n";
95-
code += "#include <unistd.h>\n";
96-
code += "#include <sys/wait.h>\n";
97-
code += "#include <fcntl.h>\n";
98-
code += "using namespace std;\n\n";
99-
code += "int main() {\n";
86+
std::vector<std::string> lldb_args = {"lldb-dap", "--port", m_lldb_port};
10087

101-
// Construct LLDB-DAP command arguments
102-
code += " vector<string> lldb_args = {\"lldb-dap\", \"--port\", \"" + m_lldb_port + "\"};\n";
103-
// Add additional configuration from m_debugger_config
104-
auto it = m_debugger_config.find("lldb");
105-
if (it != m_debugger_config.end() && it->is_object())
106-
{
107-
if (it->contains("initCommands"))
108-
{
109-
std::cout << "Adding init commands to lldb-dap command" << std::endl;
110-
for (const auto& cmd : it->at("initCommands").get<std::vector<std::string>>())
111-
{
112-
std::cout << "Adding command: " << cmd << std::endl;
113-
// Escape quotes in the command for C++ string
114-
std::string escaped_cmd = cmd;
115-
size_t pos = 0;
116-
while ((pos = escaped_cmd.find("\"", pos)) != std::string::npos)
117-
{
118-
escaped_cmd.replace(pos, 1, "\\\"");
119-
pos += 2;
120-
}
121-
while ((pos = escaped_cmd.find("\\", pos)) != std::string::npos
122-
&& pos < escaped_cmd.length() - 1)
123-
{
124-
if (escaped_cmd[pos + 1] != '\"')
125-
{
126-
escaped_cmd.replace(pos, 1, "\\\\");
127-
pos += 2;
128-
}
129-
else
130-
{
131-
pos += 2;
132-
}
133-
}
134-
code += " lldb_args.push_back(\"--init-command\");\n";
135-
code += " lldb_args.push_back(\"" + escaped_cmd + "\");\n";
136-
}
137-
}
138-
}
139-
140-
// Set up log directory and file
14188
std::string log_dir = xeus::get_temp_directory_path() + "/xcpp_debug_logs_"
14289
+ std::to_string(xeus::get_current_pid());
14390
xeus::create_directory(log_dir);
14491
std::string log_file = log_dir + "/lldb-dap.log";
14592

146-
// Add code to start the subprocess with proper redirection
147-
code += " string log_file = \"" + log_file + "\";\n";
148-
code += " \n";
149-
code += " pid_t pid = fork();\n";
150-
code += " if (pid == 0) {\n";
151-
code += " // Child process - redirect stdout/stderr to log file\n";
152-
code += " int fd = open(log_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);\n";
153-
code += " if (fd != -1) {\n";
154-
code += " dup2(fd, STDOUT_FILENO);\n";
155-
code += " dup2(fd, STDERR_FILENO);\n";
156-
code += " close(fd);\n";
157-
code += " }\n";
158-
code += " \n";
159-
code += " // Redirect stdin to /dev/null\n";
160-
code += " int null_fd = open(\"/dev/null\", O_RDONLY);\n";
161-
code += " if (null_fd != -1) {\n";
162-
code += " dup2(null_fd, STDIN_FILENO);\n";
163-
code += " close(null_fd);\n";
164-
code += " }\n";
165-
code += " \n";
166-
code += " // Convert vector to char* array for execvp\n";
167-
code += " vector<char*> args;\n";
168-
code += " for (auto& arg : lldb_args) {\n";
169-
code += " args.push_back(const_cast<char*>(arg.c_str()));\n";
170-
code += " }\n";
171-
code += " args.push_back(nullptr);\n";
172-
code += " \n";
173-
code += " execvp(\"lldb-dap\", args.data());\n";
174-
code += " \n";
175-
code += " // If execvp fails\n";
176-
code += " cerr << \"Failed to execute lldb-dap\" << endl;\n";
177-
code += " exit(1);\n";
178-
code += " }\n";
179-
code += " else if (pid > 0) {\n";
180-
code += " // Parent process\n";
181-
code += " cout << \"LLDB-DAP process started, PID: \" << pid << endl;\n";
182-
code += " \n";
183-
code += " // Check if process is still running\n";
184-
code += " int status;\n";
185-
code += " if (waitpid(pid, &status, WNOHANG) != 0) {\n";
186-
code += " cerr << \"LLDB-DAP process exited early\" << endl;\n";
187-
code += " return 1;\n";
188-
code += " }\n";
189-
code += " \n";
190-
code += " cout << \"LLDB-DAP started successfully\" << endl;\n";
191-
code += " }\n";
192-
code += " else {\n";
193-
code += " cerr << \"fork() failed\" << endl;\n";
194-
code += " return 1;\n";
195-
code += " }\n";
196-
code += " \n";
197-
code += " return 0;\n";
198-
code += "}\n";
93+
pid_t pid = fork();
94+
if (pid == 0)
95+
{
96+
int fd = open(log_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
97+
if (fd != -1)
98+
{
99+
dup2(fd, STDOUT_FILENO);
100+
dup2(fd, STDERR_FILENO);
101+
close(fd);
102+
}
199103

200-
std::cout << "Starting LLDB-DAP with port: " << m_lldb_port << std::endl;
104+
int null_fd = open("/dev/null", O_RDONLY);
105+
if (null_fd != -1)
106+
{
107+
dup2(null_fd, STDIN_FILENO);
108+
close(null_fd);
109+
}
201110

202-
// Execute the C++ code via control messenger
203-
nl::json json_code;
204-
json_code["code"] = code;
205-
nl::json rep = xdebugger::get_control_messenger().send_to_shell(json_code);
206-
std::string status = rep["status"].get<std::string>();
111+
std::vector<char*> argv;
112+
for (auto& arg : lldb_args)
113+
{
114+
argv.push_back(const_cast<char*>(arg.c_str()));
115+
}
116+
argv.push_back(nullptr);
207117

208-
std::cout << "LLDB-DAP start response: " << rep.dump() << std::endl;
118+
execvp("lldb-dap", argv.data());
209119

210-
if (status != "ok")
120+
std::cerr << "Failed to execute lldb-dap" << std::endl;
121+
std::exit(1);
122+
}
123+
else if (pid > 0)
211124
{
212-
std::string ename = rep["ename"].get<std::string>();
213-
std::string evalue = rep["evalue"].get<std::string>();
214-
std::vector<std::string> traceback = rep["traceback"].get<std::vector<std::string>>();
215-
std::clog << "Exception raised when trying to start LLDB-DAP" << std::endl;
216-
for (std::size_t i = 0; i < traceback.size(); ++i)
125+
int status;
126+
if (waitpid(pid, &status, WNOHANG) != 0)
217127
{
218-
std::clog << traceback[i] << std::endl;
128+
std::cerr << "LLDB-DAP process exited prematurely." << std::endl;
129+
return false;
219130
}
220-
std::clog << ename << " - " << evalue << std::endl;
221-
return false;
131+
m_is_running = true;
132+
return true;
222133
}
223134
else
224135
{
225-
std::cout << xcpp::green_text("LLDB-DAP process started successfully") << std::endl;
136+
std::cerr << "fork() failed" << std::endl;
137+
return false;
226138
}
227-
228-
m_is_running = true;
229-
return status == "ok";
230139
}
231140

232141
bool debugger::start()
233142
{
234-
std::cout << "Starting debugger..." << std::endl;
235-
236-
// Start LLDB-DAP process
237143
static bool lldb_started = start_lldb();
238144
if (!lldb_started)
239145
{
240-
std::cout << "Failed to start LLDB-DAP" << std::endl;
146+
std::cerr << "Failed to start LLDB-DAP" << std::endl;
241147
return false;
242148
}
243-
// Bind xeus debugger sockets for Jupyter communication
149+
244150
std::string controller_end_point = xeus::get_controller_end_point("debugger");
245151
std::string controller_header_end_point = xeus::get_controller_end_point("debugger_header");
246152
std::string publisher_end_point = xeus::get_publisher_end_point();
247153
bind_sockets(controller_header_end_point, controller_end_point);
248154

249-
std::cout << "Debugger sockets bound to: " << controller_end_point << std::endl;
250-
std::cout << "Debugger header sockets bound to: " << controller_header_end_point << std::endl;
251-
std::cout << "Publisher sockets bound to: " << publisher_end_point << std::endl;
252-
std::cout << "LLDB-DAP host: " << m_lldb_host << ", port: " << m_lldb_port << std::endl;
253-
254-
// Start LLDB-DAP client thread (for ZMQ communication)
255155
std::string lldb_endpoint = "tcp://" + m_lldb_host + ":" + m_lldb_port;
256156
std::thread client(
257157
&xdebuglldb_client::start_debugger,
@@ -263,24 +163,28 @@ namespace xcpp
263163
);
264164
client.detach();
265165

266-
// Also test ZMQ path
267166
send_recv_request("REQ");
268167

269-
// std::cout << forward_message(init_request).dump() << std::endl;
270-
271-
// Create temporary folder for cell code
272168
std::string tmp_folder = get_tmp_prefix();
273169
xeus::create_directory(tmp_folder);
274170

275171
return true;
276172
}
277173

278-
// Dummy implementations for other methods
174+
nl::json debugger::attach_request(const nl::json& message)
175+
{
176+
// Placeholder DAP response
177+
nl::json attach_request =
178+
{{"seq", 2}, {"type", "request"}, {"command", "attach"}, {"arguments", {{"pid", jit_process_pid}}}};
179+
std::cout << "Sending attach request: " << attach_request.dump() << std::endl;
180+
nl::json reply = forward_message(attach_request);
181+
return reply;
182+
}
183+
279184
nl::json debugger::inspect_variables_request(const nl::json& message)
280185
{
281186
std::cout << "[debugger::inspect_variables_request] inspect_variables_request not implemented"
282187
<< std::endl;
283-
std::cout << message.dump() << std::endl;
284188
nl::json reply = {
285189
{"type", "response"},
286190
{"request_seq", message["seq"]},
@@ -300,8 +204,6 @@ namespace xcpp
300204

301205
nl::json debugger::stack_trace_request(const nl::json& message)
302206
{
303-
// Placeholder DAP response
304-
std::cout << "stack_trace_request not implemented" << std::endl;
305207
nl::json reply = {
306208
{"type", "response"},
307209
{"request_seq", message["seq"]},
@@ -313,29 +215,8 @@ namespace xcpp
313215
return reply;
314216
}
315217

316-
nl::json debugger::attach_request(const nl::json& message)
317-
{
318-
// Placeholder DAP response
319-
std::cout << "debugger::attach_request" << std::endl;
320-
std::cout << "Message: " << message.dump() << std::endl;
321-
nl::json attach_request = {
322-
{"seq", 2},
323-
{"type", "request"},
324-
{"command", "attach"},
325-
{"arguments", {
326-
{"pid", jit_process_pid}
327-
}}
328-
};
329-
std::cout << "Sending attach request: " << attach_request.dump() << std::endl;
330-
nl::json reply = forward_message(attach_request);
331-
std::cout << "Attach request sent: " << reply.dump() << std::endl;
332-
return reply;
333-
}
334-
335218
nl::json debugger::configuration_done_request(const nl::json& message)
336219
{
337-
// Minimal DAP response to allow DAP workflow to proceed
338-
std::cout << "configuration_done_request not implemented" << std::endl;
339220
nl::json reply = {
340221
{"type", "response"},
341222
{"request_seq", message["seq"]},
@@ -347,8 +228,6 @@ namespace xcpp
347228

348229
nl::json debugger::variables_request_impl(const nl::json& message)
349230
{
350-
// Placeholder DAP response
351-
std::cout << "variables_request_impl not implemented" << std::endl;
352231
nl::json reply = {
353232
{"type", "response"},
354233
{"request_seq", message["seq"]},
@@ -362,8 +241,6 @@ namespace xcpp
362241

363242
void debugger::stop()
364243
{
365-
// Placeholder: Log stop attempt
366-
std::cout << "Debugger stop called" << std::endl;
367244
std::string controller_end_point = xeus::get_controller_end_point("debugger");
368245
std::string controller_header_end_point = xeus::get_controller_end_point("debugger_header");
369246
unbind_sockets(controller_header_end_point, controller_end_point);
@@ -372,7 +249,6 @@ namespace xcpp
372249
xeus::xdebugger_info debugger::get_debugger_info() const
373250
{
374251
// Placeholder debugger info
375-
std::cout << "get_debugger_info called" << std::endl;
376252
return xeus::xdebugger_info(
377253
xeus::get_tmp_hash_seed(),
378254
get_tmp_prefix(),
@@ -386,7 +262,6 @@ namespace xcpp
386262
std::string debugger::get_cell_temporary_file(const std::string& code) const
387263
{
388264
// Placeholder: Return a dummy temporary file path
389-
std::cout << "get_cell_temporary_file called" << std::endl;
390265
std::string tmp_file = get_tmp_prefix() + "/cell_tmp.cpp";
391266
std::ofstream out(tmp_file);
392267
out << code;
@@ -402,12 +277,6 @@ namespace xcpp
402277
const nl::json& debugger_config
403278
)
404279
{
405-
std::cout << "Creating C++ debugger" << std::endl;
406-
std::cout << "Debugger config: " << debugger_config.dump() << std::endl;
407-
std::cout << "User name: " << user_name << std::endl;
408-
std::cout << "Session ID: " << session_id << std::endl;
409-
// std::cout << "Context: " << context.get_context_id() << std::endl;
410-
// std::cout << "Config: " << config.dump() << std::endl;
411280
return std::unique_ptr<xeus::xdebugger>(
412281
new debugger(context, config, user_name, session_id, debugger_config)
413282
);

0 commit comments

Comments
 (0)