Skip to content

Commit

Permalink
debugger: implement printx command to evaluate filterx expressions
Browse files Browse the repository at this point in the history
Signed-off-by: Balazs Scheidler <balazs.scheidler@axoflow.com>
  • Loading branch information
bazsi committed Dec 10, 2024
1 parent fb10503 commit bcd453e
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/debugger/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ EXTRA_DIST += lib/debugger/CMakeLists.txt \
cmd-info.c \
cmd-list.c \
cmd-print.c \
cmd-printx.c \
cmd-quit.c \
cmd-step.c \
cmd-trace.c
Expand Down
1 change: 1 addition & 0 deletions lib/debugger/cmd-help.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ _cmd_help(Debugger *self, gint argc, gchar *argv[])
" display Set the displayed message template\n"
" trace, t Trace this message along the configuration\n"
" print, p Print the current log message\n"
" printx, px Print the value of a filterx expression\n"
" drop, d Drop the current message\n"
" quit, q Tell syslog-ng to exit\n"
);
Expand Down
103 changes: 103 additions & 0 deletions lib/debugger/cmd-printx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2024 Balázs Scheidler <balazs.scheidler@axoflow.com>
* Copyright (c) 2024 Axoflow
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/

#include "filterx/filterx-parser.h"

static void
_eval_filterx_expr(Debugger *self, GList *list_of_exprs, LogMessage *msg)
{
NVTable *payload = nv_table_ref(msg->payload);

gint expr_index = 1;
for (GList *l = list_of_exprs; l; l = l->next)
{
FilterXExpr *expr = (FilterXExpr *) l->data;
FilterXObject *res = filterx_expr_eval(expr);

if (!res)
{
printf("$%d = error(%s)\n", expr_index, filterx_eval_get_last_error());
filterx_eval_clear_errors();
goto fail;
}

GString *buf = scratch_buffers_alloc();
if (!filterx_object_repr(res, buf))
{
LogMessageValueType t;
if (!filterx_object_marshal(res, buf, &t))
g_assert_not_reached();
}
printf("$%d = %s\n", expr_index, buf->str);

filterx_object_unref(res);
expr_index++;
}

fail:
nv_table_unref(payload);
}

static void
_display_filterx_expr(Debugger *self, gint argc, gchar *argv[])
{
GList *list_of_exprs = NULL;
for (gint i = 0; i < argc; i++)
{
gchar *expr_text = g_strdup_printf("%s;", argv[i]);
CfgLexer *lexer = cfg_lexer_new_buffer(self->cfg, expr_text, strlen(expr_text));

GList *partial = NULL;
if (!cfg_run_parser(self->cfg, lexer, &filterx_parser, (gpointer *) &partial, NULL) ||
!partial)
{
printf("Error parsing filterx expression: %s\n", expr_text);
g_free(expr_text);
goto exit;
}
g_free(expr_text);
list_of_exprs = g_list_concat(list_of_exprs, partial);
}
_eval_filterx_expr(self,
list_of_exprs,
self->breakpoint_site->msg);

exit:
g_list_free_full(list_of_exprs, (GDestroyNotify) filterx_expr_unref);
}

static gboolean
_cmd_printx(Debugger *self, gint argc, gchar *argv[])
{
if (argc == 1)
{
gchar *vars[] = { "vars();", NULL };
_display_filterx_expr(self, 1, vars);
}
else
{
_display_filterx_expr(self, argc - 1, &argv[1]);
}
return TRUE;
}
47 changes: 47 additions & 0 deletions lib/debugger/debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ _set_mode(Debugger *self, DebuggerMode new_mode, gboolean trace_message)

#include "cmd-help.c"
#include "cmd-print.c"
#include "cmd-printx.c"
#include "cmd-display.c"
#include "cmd-drop.c"
#include "cmd-info.c"
Expand Down Expand Up @@ -175,6 +176,8 @@ struct
{ "f", _cmd_follow, .requires_breakpoint_site = TRUE },
{ "print", _cmd_print, .requires_breakpoint_site = TRUE },
{ "p", _cmd_print, .requires_breakpoint_site = TRUE },
{ "printx", _cmd_printx, .requires_breakpoint_site = TRUE },
{ "px", _cmd_printx, .requires_breakpoint_site = TRUE },
{ "list", _cmd_list, },
{ "l", _cmd_list, },
{ "display", _cmd_display },
Expand Down Expand Up @@ -231,6 +234,43 @@ _fetch_command(Debugger *self)
g_free(command);
}

static void
_setup_filterx_context(Debugger *self, FilterXEvalContext *context)
{
const LogPathOptions *path_options = self->breakpoint_site->path_options;
if (!path_options->filterx_context)
{
/* no parent context, let's use our own, changes to variables will be
* lost by the time we reach the very first filterx block, but we do
* allow setting variables in the context of the debugger */

filterx_eval_init_context(context, path_options->filterx_context);
context->msgs = &self->breakpoint_site->msg;
context->num_msg = 1;
}
else
{
filterx_eval_set_context(path_options->filterx_context);
}
}

static void
_clear_filterx_context(Debugger *self, FilterXEvalContext *context)
{
const LogPathOptions *path_options = self->breakpoint_site->path_options;
if (!path_options->filterx_context)
{
if (filterx_scope_is_dirty(context->scope))
{
printf("Dropping variables set from the debugger, as debugger was invoked before the filterx block\n");
}
filterx_eval_deinit_context(context);
}
else
filterx_eval_set_context(NULL);
}


static gboolean
_handle_command(Debugger *self)
{
Expand Down Expand Up @@ -290,6 +330,11 @@ _handle_interactive_prompt(Debugger *self)
_set_current_location(self, NULL);
printf(" Stopping on Interrupt...\n");
}

FilterXEvalContext temporary_context;
if (self->breakpoint_site)
_setup_filterx_context(self, &temporary_context);

while (1)
{
_fetch_command(self);
Expand All @@ -298,6 +343,8 @@ _handle_interactive_prompt(Debugger *self)
break;

}
if (self->breakpoint_site)
_clear_filterx_context(self, &temporary_context);
printf("(continuing)\n");
}

Expand Down

0 comments on commit bcd453e

Please sign in to comment.