@@ -61,197 +61,97 @@ namespace xcpp
61
61
62
62
debugger::~debugger ()
63
63
{
64
- std::cout << " Stopping debugger..........." << std::endl;
65
64
delete p_debuglldb_client;
66
65
p_debuglldb_client = nullptr ;
67
66
}
68
67
69
68
bool debugger::start_lldb ()
70
69
{
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 ();
73
71
74
- // Find a free port for LLDB-DAP
75
72
m_lldb_port = xeus::find_free_port (100 , 9999 , 10099 );
76
73
if (m_lldb_port.empty ())
77
74
{
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;
79
76
return false ;
80
77
}
81
78
82
- // Log debugger configuration if XEUS_LOG is set
83
- if (std::getenv (" XEUS_LOG" ) != nullptr )
79
+ if (std::getenv (" XEUS_LOG" ))
84
80
{
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 ' ;
88
84
}
89
85
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};
100
87
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
141
88
std::string log_dir = xeus::get_temp_directory_path () + " /xcpp_debug_logs_"
142
89
+ std::to_string (xeus::get_current_pid ());
143
90
xeus::create_directory (log_dir);
144
91
std::string log_file = log_dir + " /lldb-dap.log" ;
145
92
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
+ }
199
103
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
+ }
201
110
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 );
207
117
208
- std::cout << " LLDB-DAP start response: " << rep. dump () << std::endl ;
118
+ execvp ( " lldb-dap " , argv. data ()) ;
209
119
210
- if (status != " ok" )
120
+ std::cerr << " Failed to execute lldb-dap" << std::endl;
121
+ std::exit (1 );
122
+ }
123
+ else if (pid > 0 )
211
124
{
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 )
217
127
{
218
- std::clog << traceback[i] << std::endl;
128
+ std::cerr << " LLDB-DAP process exited prematurely." << std::endl;
129
+ return false ;
219
130
}
220
- std::clog << ename << " - " << evalue << std::endl ;
221
- return false ;
131
+ m_is_running = true ;
132
+ return true ;
222
133
}
223
134
else
224
135
{
225
- std::cout << xcpp::green_text (" LLDB-DAP process started successfully" ) << std::endl;
136
+ std::cerr << " fork() failed" << std::endl;
137
+ return false ;
226
138
}
227
-
228
- m_is_running = true ;
229
- return status == " ok" ;
230
139
}
231
140
232
141
bool debugger::start ()
233
142
{
234
- std::cout << " Starting debugger..." << std::endl;
235
-
236
- // Start LLDB-DAP process
237
143
static bool lldb_started = start_lldb ();
238
144
if (!lldb_started)
239
145
{
240
- std::cout << " Failed to start LLDB-DAP" << std::endl;
146
+ std::cerr << " Failed to start LLDB-DAP" << std::endl;
241
147
return false ;
242
148
}
243
- // Bind xeus debugger sockets for Jupyter communication
149
+
244
150
std::string controller_end_point = xeus::get_controller_end_point (" debugger" );
245
151
std::string controller_header_end_point = xeus::get_controller_end_point (" debugger_header" );
246
152
std::string publisher_end_point = xeus::get_publisher_end_point ();
247
153
bind_sockets (controller_header_end_point, controller_end_point);
248
154
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)
255
155
std::string lldb_endpoint = " tcp://" + m_lldb_host + " :" + m_lldb_port;
256
156
std::thread client (
257
157
&xdebuglldb_client::start_debugger,
@@ -263,24 +163,28 @@ namespace xcpp
263
163
);
264
164
client.detach ();
265
165
266
- // Also test ZMQ path
267
166
send_recv_request (" REQ" );
268
167
269
- // std::cout << forward_message(init_request).dump() << std::endl;
270
-
271
- // Create temporary folder for cell code
272
168
std::string tmp_folder = get_tmp_prefix ();
273
169
xeus::create_directory (tmp_folder);
274
170
275
171
return true ;
276
172
}
277
173
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
+
279
184
nl::json debugger::inspect_variables_request (const nl::json& message)
280
185
{
281
186
std::cout << " [debugger::inspect_variables_request] inspect_variables_request not implemented"
282
187
<< std::endl;
283
- std::cout << message.dump () << std::endl;
284
188
nl::json reply = {
285
189
{" type" , " response" },
286
190
{" request_seq" , message[" seq" ]},
@@ -300,8 +204,6 @@ namespace xcpp
300
204
301
205
nl::json debugger::stack_trace_request (const nl::json& message)
302
206
{
303
- // Placeholder DAP response
304
- std::cout << " stack_trace_request not implemented" << std::endl;
305
207
nl::json reply = {
306
208
{" type" , " response" },
307
209
{" request_seq" , message[" seq" ]},
@@ -313,29 +215,8 @@ namespace xcpp
313
215
return reply;
314
216
}
315
217
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
-
335
218
nl::json debugger::configuration_done_request (const nl::json& message)
336
219
{
337
- // Minimal DAP response to allow DAP workflow to proceed
338
- std::cout << " configuration_done_request not implemented" << std::endl;
339
220
nl::json reply = {
340
221
{" type" , " response" },
341
222
{" request_seq" , message[" seq" ]},
@@ -347,8 +228,6 @@ namespace xcpp
347
228
348
229
nl::json debugger::variables_request_impl (const nl::json& message)
349
230
{
350
- // Placeholder DAP response
351
- std::cout << " variables_request_impl not implemented" << std::endl;
352
231
nl::json reply = {
353
232
{" type" , " response" },
354
233
{" request_seq" , message[" seq" ]},
@@ -362,8 +241,6 @@ namespace xcpp
362
241
363
242
void debugger::stop ()
364
243
{
365
- // Placeholder: Log stop attempt
366
- std::cout << " Debugger stop called" << std::endl;
367
244
std::string controller_end_point = xeus::get_controller_end_point (" debugger" );
368
245
std::string controller_header_end_point = xeus::get_controller_end_point (" debugger_header" );
369
246
unbind_sockets (controller_header_end_point, controller_end_point);
@@ -372,7 +249,6 @@ namespace xcpp
372
249
xeus::xdebugger_info debugger::get_debugger_info () const
373
250
{
374
251
// Placeholder debugger info
375
- std::cout << " get_debugger_info called" << std::endl;
376
252
return xeus::xdebugger_info (
377
253
xeus::get_tmp_hash_seed (),
378
254
get_tmp_prefix (),
@@ -386,7 +262,6 @@ namespace xcpp
386
262
std::string debugger::get_cell_temporary_file (const std::string& code) const
387
263
{
388
264
// Placeholder: Return a dummy temporary file path
389
- std::cout << " get_cell_temporary_file called" << std::endl;
390
265
std::string tmp_file = get_tmp_prefix () + " /cell_tmp.cpp" ;
391
266
std::ofstream out (tmp_file);
392
267
out << code;
@@ -402,12 +277,6 @@ namespace xcpp
402
277
const nl::json& debugger_config
403
278
)
404
279
{
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;
411
280
return std::unique_ptr<xeus::xdebugger>(
412
281
new debugger (context, config, user_name, session_id, debugger_config)
413
282
);
0 commit comments