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 ;
@@ -138,15 +140,31 @@ _display_source_line(LogExprNode *expr_node)
138
140
static gboolean
139
141
_cmd_help (Debugger * self , gint argc , gchar * argv [])
140
142
{
141
- printf ("syslog-ng interactive console, the following commands are available\n\n"
142
- " help, h, or ? Display this help\n"
143
- " info Display information about the current execution state\n"
144
- " continue or c Continue until the next breakpoint\n"
145
- " trace Display timing information as the message traverses the config\n"
146
- " print, p Print the current log message\n"
147
- " drop, d Drop the current message\n"
148
- " quit, q Tell syslog-ng to exit\n"
149
- );
143
+ if (self -> breakpoint_site )
144
+ {
145
+ printf ("syslog-ng interactive console\n"
146
+ "Stopped on a breakpoint.\n"
147
+ "The following commands are available:\n\n"
148
+ " help, h, ? Display this help\n"
149
+ " info, i Display information about the current execution state\n"
150
+ " continue, c Continue until the next breakpoint\n"
151
+ " display Set the displayed message template\n"
152
+ " trace, t Display timing information as the message traverses the config\n"
153
+ " print, p Print the current log message\n"
154
+ " drop, d Drop the current message\n"
155
+ " quit, q Tell syslog-ng to exit\n"
156
+ );
157
+ }
158
+ else
159
+ {
160
+ printf ("syslog-ng interactive console\n"
161
+ "Stopped on an interrupt.\n"
162
+ "The following commands are available:\n\n"
163
+ " help, h, ? Display this help\n"
164
+ " continue, c Continue until the next breakpoint\n"
165
+ " quit, q Tell syslog-ng to exit\n"
166
+ );
167
+ }
150
168
return TRUE;
151
169
}
152
170
@@ -210,7 +228,8 @@ static gboolean
210
228
_cmd_quit (Debugger * self , gint argc , gchar * argv [])
211
229
{
212
230
main_loop_exit (self -> main_loop );
213
- self -> breakpoint_site -> drop = TRUE;
231
+ if (self -> breakpoint_site )
232
+ self -> breakpoint_site -> drop = TRUE;
214
233
return FALSE;
215
234
}
216
235
@@ -245,22 +264,25 @@ struct
245
264
{
246
265
const gchar * name ;
247
266
DebuggerCommandFunc command ;
267
+ gboolean requires_breakpoint_site ;
248
268
} command_table [] =
249
269
{
250
270
{ "help" , _cmd_help },
251
271
{ "h" , _cmd_help },
252
272
{ "?" , _cmd_help },
253
273
{ "continue" , _cmd_continue },
254
274
{ "c" , _cmd_continue },
255
- { "print" , _cmd_print },
256
- { "p" , _cmd_print },
275
+ { "print" , _cmd_print , . requires_breakpoint_site = TRUE },
276
+ { "p" , _cmd_print , . requires_breakpoint_site = TRUE },
257
277
{ "display" , _cmd_display },
258
- { "drop" , _cmd_drop },
278
+ { "drop" , _cmd_drop , .requires_breakpoint_site = TRUE },
279
+ { "d" , _cmd_drop , .requires_breakpoint_site = TRUE },
259
280
{ "quit" , _cmd_quit },
260
281
{ "q" , _cmd_quit },
261
- { "trace" , _cmd_trace },
262
- { "info" , _cmd_info },
263
- { "i" , _cmd_info },
282
+ { "trace" , _cmd_trace , .requires_breakpoint_site = TRUE },
283
+ { "t" , _cmd_trace , .requires_breakpoint_site = TRUE },
284
+ { "info" , _cmd_info , .requires_breakpoint_site = TRUE },
285
+ { "i" , _cmd_info , .requires_breakpoint_site = TRUE },
264
286
{ NULL , NULL }
265
287
};
266
288
@@ -319,6 +341,7 @@ _handle_command(Debugger *self)
319
341
gint argc ;
320
342
gchar * * argv ;
321
343
GError * error = NULL ;
344
+ gboolean requires_breakpoint_site = TRUE;
322
345
DebuggerCommandFunc command = NULL ;
323
346
324
347
if (!g_shell_parse_argv (self -> command_buffer ? : "" , & argc , & argv , & error ))
@@ -333,6 +356,7 @@ _handle_command(Debugger *self)
333
356
if (strcmp (command_table [i ].name , argv [0 ]) == 0 )
334
357
{
335
358
command = command_table [i ].command ;
359
+ requires_breakpoint_site = command_table [i ].requires_breakpoint_site ;
336
360
break ;
337
361
}
338
362
}
@@ -341,6 +365,11 @@ _handle_command(Debugger *self)
341
365
printf ("Undefined command %s, try \"help\"\n" , argv [0 ]);
342
366
return TRUE;
343
367
}
368
+ else if (requires_breakpoint_site && self -> breakpoint_site == NULL )
369
+ {
370
+ printf ("Running in interrupt context, command %s requires pipeline context\n" , argv [0 ]);
371
+ return TRUE;
372
+ }
344
373
gboolean result = command (self , argc , argv );
345
374
g_strfreev (argv );
346
375
return result ;
@@ -350,11 +379,20 @@ static void
350
379
_handle_interactive_prompt (Debugger * self )
351
380
{
352
381
gchar buf [1024 ];
353
- LogPipe * current_pipe = self -> breakpoint_site -> pipe ;
382
+ LogPipe * current_pipe ;
383
+
384
+ if (self -> breakpoint_site )
385
+ {
386
+ current_pipe = self -> breakpoint_site -> pipe ;
354
387
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 );
388
+ printf ("Breakpoint hit %s\n" , log_expr_node_format_location (current_pipe -> expr_node , buf , sizeof (buf )));
389
+ _display_source_line (current_pipe -> expr_node );
390
+ _display_msg_with_template (self , self -> breakpoint_site -> msg , self -> display_template );
391
+ }
392
+ else
393
+ {
394
+ printf ("Stopping on interrupt, message related commands are unavailable...\n" );
395
+ }
358
396
while (1 )
359
397
{
360
398
_fetch_command (self );
@@ -374,22 +412,37 @@ _debugger_thread_func(Debugger *self)
374
412
while (1 )
375
413
{
376
414
self -> breakpoint_site = NULL ;
377
- if (!tracer_wait_for_breakpoint (self -> tracer , & self -> breakpoint_site ))
415
+ if (!tracer_wait_for_event (self -> tracer , & self -> breakpoint_site ))
378
416
break ;
379
417
380
418
_handle_interactive_prompt (self );
381
- tracer_resume_after_breakpoint (self -> tracer , self -> breakpoint_site );
419
+ tracer_resume_after_event (self -> tracer , self -> breakpoint_site );
382
420
}
383
421
scratch_buffers_explicit_gc ();
384
422
app_thread_stop ();
385
423
return NULL ;
386
424
}
387
425
426
+ static void
427
+ _interrupt (gpointer user_data )
428
+ {
429
+ Debugger * self = (Debugger * ) user_data ;
430
+
431
+ tracer_stop_on_interrupt (self -> tracer );
432
+ }
433
+
388
434
void
389
435
debugger_start_console (Debugger * self )
390
436
{
391
437
main_loop_assert_main_thread ();
392
438
439
+ IV_SIGNAL_INIT (& self -> sigint );
440
+ self -> sigint .signum = SIGINT ;
441
+ self -> sigint .flags = IV_SIGNAL_FLAG_EXCLUSIVE ;
442
+ self -> sigint .cookie = self ;
443
+ self -> sigint .handler = _interrupt ;
444
+ iv_signal_register (& self -> sigint );
445
+
393
446
self -> debugger_thread = g_thread_new (NULL , (GThreadFunc ) _debugger_thread_func , self );
394
447
}
395
448
@@ -429,6 +482,7 @@ debugger_exit(Debugger *self)
429
482
{
430
483
main_loop_assert_main_thread ();
431
484
485
+ iv_signal_unregister (& self -> sigint );
432
486
tracer_cancel (self -> tracer );
433
487
g_thread_join (self -> debugger_thread );
434
488
}
0 commit comments