31
31
#include "compat/time.h"
32
32
#include "scratch-buffers.h"
33
33
34
+ #include <iv_signal.h>
34
35
#include <stdio.h>
35
36
#include <unistd.h>
36
37
37
38
struct _Debugger
38
39
{
39
40
Tracer * tracer ;
41
+ struct iv_signal sigint ;
40
42
MainLoop * main_loop ;
41
43
GlobalConfig * cfg ;
42
44
gchar * command_buffer ;
@@ -210,7 +212,8 @@ static gboolean
210
212
_cmd_quit (Debugger * self , gint argc , gchar * argv [])
211
213
{
212
214
main_loop_exit (self -> main_loop );
213
- self -> breakpoint_site -> drop = TRUE;
215
+ if (self -> breakpoint_site )
216
+ self -> breakpoint_site -> drop = TRUE;
214
217
return FALSE;
215
218
}
216
219
@@ -245,22 +248,23 @@ struct
245
248
{
246
249
const gchar * name ;
247
250
DebuggerCommandFunc command ;
251
+ gboolean requires_breakpoint_site ;
248
252
} command_table [] =
249
253
{
250
254
{ "help" , _cmd_help },
251
255
{ "h" , _cmd_help },
252
256
{ "?" , _cmd_help },
253
257
{ "continue" , _cmd_continue },
254
258
{ "c" , _cmd_continue },
255
- { "print" , _cmd_print },
256
- { "p" , _cmd_print },
259
+ { "print" , _cmd_print , . requires_breakpoint_site = TRUE },
260
+ { "p" , _cmd_print , . requires_breakpoint_site = TRUE },
257
261
{ "display" , _cmd_display },
258
- { "drop" , _cmd_drop },
262
+ { "drop" , _cmd_drop , . requires_breakpoint_site = TRUE },
259
263
{ "quit" , _cmd_quit },
260
264
{ "q" , _cmd_quit },
261
- { "trace" , _cmd_trace },
262
- { "info" , _cmd_info },
263
- { "i" , _cmd_info },
265
+ { "trace" , _cmd_trace , . requires_breakpoint_site = TRUE },
266
+ { "info" , _cmd_info , . requires_breakpoint_site = TRUE },
267
+ { "i" , _cmd_info , . requires_breakpoint_site = TRUE },
264
268
{ NULL , NULL }
265
269
};
266
270
@@ -319,6 +323,7 @@ _handle_command(Debugger *self)
319
323
gint argc ;
320
324
gchar * * argv ;
321
325
GError * error = NULL ;
326
+ gboolean requires_breakpoint_site = TRUE;
322
327
DebuggerCommandFunc command = NULL ;
323
328
324
329
if (!g_shell_parse_argv (self -> command_buffer ? : "" , & argc , & argv , & error ))
@@ -333,6 +338,7 @@ _handle_command(Debugger *self)
333
338
if (strcmp (command_table [i ].name , argv [0 ]) == 0 )
334
339
{
335
340
command = command_table [i ].command ;
341
+ requires_breakpoint_site = command_table [i ].requires_breakpoint_site ;
336
342
break ;
337
343
}
338
344
}
@@ -341,6 +347,11 @@ _handle_command(Debugger *self)
341
347
printf ("Undefined command %s, try \"help\"\n" , argv [0 ]);
342
348
return TRUE;
343
349
}
350
+ else if (requires_breakpoint_site && self -> breakpoint_site == NULL )
351
+ {
352
+ printf ("Running in interrupt context, command %s requires pipeline context\n" , argv [0 ]);
353
+ return TRUE;
354
+ }
344
355
gboolean result = command (self , argc , argv );
345
356
g_strfreev (argv );
346
357
return result ;
@@ -350,11 +361,20 @@ static void
350
361
_handle_interactive_prompt (Debugger * self )
351
362
{
352
363
gchar buf [1024 ];
353
- LogPipe * current_pipe = self -> breakpoint_site -> pipe ;
364
+ LogPipe * current_pipe ;
354
365
355
- printf ("Breakpoint hit %s\n" , log_expr_node_format_location (current_pipe -> expr_node , buf , sizeof (buf )));
356
- _display_source_line (current_pipe -> expr_node );
357
- _display_msg_with_template (self , self -> breakpoint_site -> msg , self -> display_template );
366
+ if (self -> breakpoint_site )
367
+ {
368
+ current_pipe = self -> breakpoint_site -> pipe ;
369
+
370
+ printf ("Breakpoint hit %s\n" , log_expr_node_format_location (current_pipe -> expr_node , buf , sizeof (buf )));
371
+ _display_source_line (current_pipe -> expr_node );
372
+ _display_msg_with_template (self , self -> breakpoint_site -> msg , self -> display_template );
373
+ }
374
+ else
375
+ {
376
+ printf ("Stopping on interrupt, message related commands are unavailable...\n" );
377
+ }
358
378
while (1 )
359
379
{
360
380
_fetch_command (self );
@@ -374,22 +394,37 @@ _debugger_thread_func(Debugger *self)
374
394
while (1 )
375
395
{
376
396
self -> breakpoint_site = NULL ;
377
- if (!tracer_wait_for_breakpoint (self -> tracer , & self -> breakpoint_site ))
397
+ if (!tracer_wait_for_event (self -> tracer , & self -> breakpoint_site ))
378
398
break ;
379
399
380
400
_handle_interactive_prompt (self );
381
- tracer_resume_after_breakpoint (self -> tracer , self -> breakpoint_site );
401
+ tracer_resume_after_event (self -> tracer , self -> breakpoint_site );
382
402
}
383
403
scratch_buffers_explicit_gc ();
384
404
app_thread_stop ();
385
405
return NULL ;
386
406
}
387
407
408
+ static void
409
+ _interrupt (gpointer user_data )
410
+ {
411
+ Debugger * self = (Debugger * ) user_data ;
412
+
413
+ tracer_stop_on_interrupt (self -> tracer );
414
+ }
415
+
388
416
void
389
417
debugger_start_console (Debugger * self )
390
418
{
391
419
main_loop_assert_main_thread ();
392
420
421
+ IV_SIGNAL_INIT (& self -> sigint );
422
+ self -> sigint .signum = SIGINT ;
423
+ self -> sigint .flags = IV_SIGNAL_FLAG_EXCLUSIVE ;
424
+ self -> sigint .cookie = self ;
425
+ self -> sigint .handler = _interrupt ;
426
+ iv_signal_register (& self -> sigint );
427
+
393
428
self -> debugger_thread = g_thread_new (NULL , (GThreadFunc ) _debugger_thread_func , self );
394
429
}
395
430
@@ -429,6 +464,7 @@ debugger_exit(Debugger *self)
429
464
{
430
465
main_loop_assert_main_thread ();
431
466
467
+ iv_signal_unregister (& self -> sigint );
432
468
tracer_cancel (self -> tracer );
433
469
g_thread_join (self -> debugger_thread );
434
470
}
0 commit comments