struct lttng_event_rule_syscall {
struct lttng_event_rule parent;
+ enum lttng_event_rule_syscall_emission_site_type emission_site_type;
char *pattern;
char *filter_expression;
};
struct lttng_event_rule_syscall_comm {
+ uint32_t emission_site_type;
/* Includes terminator `\0`. */
uint32_t pattern_len;
/* Includes terminator `\0`. */
struct lttng_payload_view *view,
struct lttng_event_rule **rule);
+LTTNG_HIDDEN
+const char *lttng_event_rule_syscall_emission_site_str(
+ enum lttng_event_rule_syscall_emission_site_type type);
#endif /* LTTNG_EVENT_RULE_SYSCALL_INTERNAL_H */
extern "C" {
#endif
+enum lttng_event_rule_syscall_emission_site_type {
+ LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT = 0,
+ LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY = 1,
+ LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT = 2,
+ LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN = -1,
+};
+
/*
* Create a newly allocated syscall event rule.
*
* The default pattern is '*'.
+ * The default emission site type is LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT.
*
* Returns a new event rule on success, NULL on failure. This event rule must be
* destroyed using lttng_event_rule_destroy().
*/
-extern struct lttng_event_rule *lttng_event_rule_syscall_create(void);
+extern struct lttng_event_rule *lttng_event_rule_syscall_create(enum
+ lttng_event_rule_syscall_emission_site_type emission_site_type);
/*
* Set the pattern of a syscall event rule.
extern enum lttng_event_rule_status lttng_event_rule_syscall_get_filter(
const struct lttng_event_rule *rule, const char **expression);
+/*
+ * Get the emission site type of a syscall event rule.
+ *
+ * Returns a enum lttng_event_rule_syscall_emission_site_type.
+ */
+extern enum lttng_event_rule_syscall_emission_site_type
+lttng_event_rule_syscall_get_emission_site_type(
+ const struct lttng_event_rule *rule);
+
#ifdef __cplusplus
}
#endif
const enum lttng_event_rule_status status =
lttng_event_rule_syscall_get_pattern(
rule, &name);
+ const enum lttng_event_rule_syscall_emission_site_type
+ emission_site_type =
+ lttng_event_rule_syscall_get_emission_site_type(rule);
+ enum lttng_kernel_syscall_entryexit entryexit;
assert(status == LTTNG_EVENT_RULE_STATUS_OK);
+ assert(emission_site_type != LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN);
+
+ switch(emission_site_type) {
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY:
+ entryexit = LTTNG_KERNEL_SYSCALL_ENTRY;
+ break;
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT:
+ entryexit = LTTNG_KERNEL_SYSCALL_EXIT;
+ break;
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT:
+ entryexit = LTTNG_KERNEL_SYSCALL_ENTRYEXIT;
+ break;
+ default:
+ abort();
+ break;
+ }
kernel_event_notifier->event.instrumentation =
LTTNG_KERNEL_SYSCALL;
kernel_event_notifier->event.u.syscall.abi =
LTTNG_KERNEL_SYSCALL_ABI_ALL;
kernel_event_notifier->event.u.syscall.entryexit =
- LTTNG_KERNEL_SYSCALL_ENTRY;
+ entryexit;
kernel_event_notifier->event.u.syscall.match =
LTTNG_KERNEL_SYSCALL_MATCH_NAME;
ret_code = LTTNG_OK;
#include <ctype.h>
#include <stdio.h>
+#include <string.h>
#include "../command.h"
#include "../loglevel.h"
if (strcmp(arg, "tracepoint") == 0 || strcmp(arg, "logging") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_TRACEPOINT;
- } else if (strcmp (arg, "kprobe") == 0 || strcmp(arg, "kernel-probe") == 0) {
+ } else if (strcmp(arg, "kprobe") == 0 ||
+ strcmp(arg, "kernel-probe") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE;
- } else if (strcmp (arg, "uprobe") == 0 || strcmp(arg, "userspace-probe") == 0) {
+ } else if (strcmp(arg, "uprobe") == 0 ||
+ strcmp(arg, "userspace-probe") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE;
- } else if (strcmp (arg, "function") == 0) {
+ } else if (strcmp(arg, "function") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION;
- } else if (strcmp (arg, "syscall") == 0) {
+ } else if (strncmp(arg, "syscall", strlen("syscall")) == 0) {
+ /*
+ * Matches the following:
+ * - syscall
+ * - syscall:entry
+ * - syscall:exit
+ * - syscall:entry+exit
+ * - syscall:*
+ *
+ * Validation for the right side is left to further usage sites.
+ */
*dest = LTTNG_EVENT_RULE_TYPE_SYSCALL;
} else {
ERR("Invalid `--type` value: %s", arg);
return ret;
}
+static bool parse_syscall_emission_site_from_type(const char *str,
+ enum lttng_event_rule_syscall_emission_site_type *type)
+{
+ bool ret = false;
+ if (strcmp(str, "syscall") == 0 ||
+ strcmp(str, "syscall:entry+exit") == 0) {
+ *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT;
+ } else if (strcmp(str, "syscall:entry") == 0) {
+ *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY;
+ } else if (strcmp(str, "syscall:exit") == 0) {
+ *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT;
+ } else {
+ goto error;
+ }
+
+ ret = true;
+
+error:
+ return ret;
+}
+
/* This is defined in enable_events.c. */
LTTNG_HIDDEN
int create_exclusion_list_and_validate(const char *event_name,
struct filter_parser_ctx *parser_ctx = NULL;
struct lttng_log_level_rule *log_level_rule = NULL;
+ /* Event rule type option */
+ char *event_rule_type_str = NULL;
+
/* Tracepoint and syscall options. */
char *name = NULL;
char *exclude_names = NULL;
goto error;
}
+ /* Save the string for later use. */
+ if (!assign_string(&event_rule_type_str,
+ item_opt->arg,
+ "--type/-t")) {
+ goto error;
+ }
+
break;
case OPT_LOCATION:
if (!assign_string(&location,
case LTTNG_EVENT_RULE_TYPE_SYSCALL:
{
enum lttng_event_rule_status event_rule_status;
+ enum lttng_event_rule_syscall_emission_site_type emission_site_type;
+
+ if (!parse_syscall_emission_site_from_type(
+ event_rule_type_str, &emission_site_type)) {
+ ERR("Failed to parse syscall type '%s'.", event_rule_type_str);
+ goto error;
+ }
- res.er = lttng_event_rule_syscall_create();
+ res.er = lttng_event_rule_syscall_create(emission_site_type);
if (!res.er) {
ERR("Failed to create syscall event rule.");
goto error;
free(log_level_str);
free(location);
free(event_name);
+ free(event_rule_type_str);
strutils_free_null_terminated_array_of_strings(exclusion_list);
lttng_kernel_probe_location_destroy(kernel_probe_location);
#include "lttng/condition/on-event-internal.h"
/* For lttng_domain_type_str(). */
#include "lttng/domain-internal.h"
+/* For lttng_event_rule_syscall_emission_site_str() */
+#include "lttng/event-rule/syscall-internal.h"
#include "../loglevel.h"
#include <lttng/lttng.h>
{
const char *pattern, *filter;
enum lttng_event_rule_status event_rule_status;
+ enum lttng_event_rule_syscall_emission_site_type emission_site_type;
assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
+ emission_site_type =
+ lttng_event_rule_syscall_get_emission_site_type(event_rule);
+
event_rule_status = lttng_event_rule_syscall_get_pattern(
event_rule, &pattern);
assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
- _MSG(" rule: %s (type: syscall", pattern);
+ _MSG(" rule: %s (type: syscall:%s", pattern,
+ lttng_event_rule_syscall_emission_site_str(
+ emission_site_type));
event_rule_status = lttng_event_rule_syscall_get_filter(
event_rule, &filter);
syscall_comm.pattern_len = pattern_len;
syscall_comm.filter_expression_len = filter_expression_len;
+ syscall_comm.emission_site_type = syscall->emission_site_type;
ret = lttng_dynamic_buffer_append(
&payload->buffer, &syscall_comm, sizeof(syscall_comm));
return hash;
}
-struct lttng_event_rule *lttng_event_rule_syscall_create(void)
+struct lttng_event_rule *lttng_event_rule_syscall_create(
+ enum lttng_event_rule_syscall_emission_site_type
+ emission_site_type)
{
struct lttng_event_rule *rule = NULL;
struct lttng_event_rule_syscall *syscall_rule;
enum lttng_event_rule_status status;
+ /* Validate the emission site type */
+ switch (emission_site_type) {
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT:
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY:
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT:
+ break;
+ default:
+ /* Invalid emission type */
+ goto end;
+ }
+
syscall_rule = zmalloc(sizeof(struct lttng_event_rule_syscall));
if (!syscall_rule) {
goto end;
rule = NULL;
}
+ /* Emission site type */
+ syscall_rule->emission_site_type = emission_site_type;
+
end:
return rule;
}
}
syscall_comm = (typeof(syscall_comm)) current_buffer_view.data;
- rule = lttng_event_rule_syscall_create();
+ rule = lttng_event_rule_syscall_create(syscall_comm->emission_site_type);
if (!rule) {
ERR("Failed to create event rule syscall");
ret = -1;
end:
return status;
}
+extern enum lttng_event_rule_syscall_emission_site_type
+lttng_event_rule_syscall_get_emission_site_type(
+ const struct lttng_event_rule *rule)
+{
+ enum lttng_event_rule_syscall_emission_site_type emission_site_type =
+ LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN;
+ struct lttng_event_rule_syscall *syscall;
+
+ if (!rule || !IS_SYSCALL_EVENT_RULE(rule)) {
+ goto end;
+ }
+
+ syscall = container_of(rule, struct lttng_event_rule_syscall, parent);
+ emission_site_type = syscall->emission_site_type;
+
+end:
+ return emission_site_type;
+}
+
+LTTNG_HIDDEN
+const char *lttng_event_rule_syscall_emission_site_str(
+ enum lttng_event_rule_syscall_emission_site_type type)
+{
+ switch (type) {
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY:
+ return "entry";
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT:
+ return "entry+exit";
+ case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT:
+ return "exit";
+ default:
+ return "???";
+ }
+}
lttng_session_daemon_notification_endpoint);
ok(notification_channel, "Notification channel object creation");
- event_rule = lttng_event_rule_syscall_create();
+ event_rule = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY);
ok(event_rule, "syscall event rule object creation");
event_rule_status = lttng_event_rule_syscall_set_pattern(
lttng_session_daemon_notification_endpoint);
ok(notification_channel, "Notification channel object creation");
- event_rule = lttng_event_rule_syscall_create();
+ event_rule = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY);
ok(event_rule, "syscall event rule object creation");
event_rule_status = lttng_event_rule_syscall_set_pattern(
# shellcheck source=../../../utils/utils.sh
source "$TESTDIR/utils/utils.sh"
-plan_tests 264
+plan_tests 276
FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}"
done
}
-skip $ist_root "non-root user: skipping syscall tests" 9 || {
+skip $ist_root "non-root user: skipping syscall tests" 18 || {
test_success "--condition event-rule-matches one syscall" \
--condition event-rule-matches --domain=kernel --type=syscall --name=open \
--action notify
test_success "--condition event-rule-matches one syscall with filter" \
--condition event-rule-matches --domain=kernel --type=syscall --filter 'a > 2' --name=open \
--action notify
+ test_success "--condition event-rule-matches one syscall:entry" \
+ --condition event-rule-matches --domain=kernel --type=syscall:entry --name=open \
+ --action notify
+ test_success "--condition event-rule-matches one syscall:exit" \
+ --condition event-rule-matches --domain=kernel --type=syscall:exit --name=open \
+ --action notify
+ test_success "--condition event-rule-matches one syscall:entry-exit" \
+ --condition event-rule-matches --domain=kernel --type=syscall:entry+exit --name=open \
+ --action notify
}
# `--action notify` successes
"Error: Unexpected argument 'open'" \
--condition event-rule-matches --domain=kernel --type=syscall open
+test_failure "--condition event-rule-matches: --type=syscall:nope" \
+ "Error: Failed to parse syscall type 'syscall:nope'." \
+ --condition event-rule-matches --domain=kernel --type=syscall:nope \
+ --name=open
+
test_failure "--condition event-rule-matches --capture: missing argument (end of arg list)" \
'Error: While parsing argument #2 (`--capture`): Missing required argument for option `--capture`' \
--action notify \
# shellcheck source=../../../utils/utils.sh
source "$TESTDIR/utils/utils.sh"
-NUM_TESTS=100
+NUM_TESTS=106
FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}"
diag "Listing on-event syscall"
lttng_add_trigger_ok "T0" --condition event-rule-matches --domain=kernel --type=syscall --name=open --action notify
- lttng_add_trigger_ok "T1" --condition event-rule-matches --domain=kernel --type=syscall --name=ptrace --filter 'a > 2' --action notify
+ lttng_add_trigger_ok "T1" --condition event-rule-matches --domain=kernel --type=syscall:entry --name=open --action notify
+ lttng_add_trigger_ok "T2" --condition event-rule-matches --domain=kernel --type=syscall:exit --name=open --action notify
+ lttng_add_trigger_ok "T3" --condition event-rule-matches --domain=kernel --type=syscall:entry+exit --name=open --action notify
+ lttng_add_trigger_ok "T4" --condition event-rule-matches --domain=kernel --type=syscall --name=ptrace --filter 'a > 2' --action notify
cat > "${tmp_expected_stdout}" <<- EOF
- name: T0
owner uid: ${uid}
condition: event rule hit
- rule: open (type: syscall)
+ rule: open (type: syscall:entry+exit)
actions:
notify
errors: none
- name: T1
owner uid: ${uid}
condition: event rule hit
- rule: ptrace (type: syscall, filter: a > 2)
+ rule: open (type: syscall:entry)
+ actions:
+ notify
+ errors: none
+ errors: none
+ - name: T2
+ owner uid: ${uid}
+ condition: event rule hit
+ rule: open (type: syscall:exit)
+ actions:
+ notify
+ errors: none
+ errors: none
+ - name: T3
+ owner uid: ${uid}
+ condition: event rule hit
+ rule: open (type: syscall:entry+exit)
+ actions:
+ notify
+ errors: none
+ errors: none
+ - name: T4
+ owner uid: ${uid}
+ condition: event rule hit
+ rule: ptrace (type: syscall:entry+exit, filter: a > 2)
actions:
notify
errors: none
lttng_remove_trigger_ok "T0"
lttng_remove_trigger_ok "T1"
+ lttng_remove_trigger_ok "T2"
+ lttng_remove_trigger_ok "T3"
+ lttng_remove_trigger_ok "T4"
}
test_session_consumed_size_condition ()
skip $ist_root "non-root user: skipping kprobe tests" 9 || test_on_event_probe
skip $ist_root "non-root user: skipping uprobe tests" 5 || test_on_event_userspace_probe_elf
skip $(($ist_root && $hast_sdt_binary)) "skipping userspace probe SDT tests" 5 || test_on_event_userspace_probe_sdt
-skip $ist_root "non-root user: skipping syscall tests" 7 || test_on_event_syscall
+skip $ist_root "non-root user: skipping syscall tests" 13 || test_on_event_syscall
test_session_consumed_size_condition
test_buffer_usage_conditions
test_session_rotation_conditions
lttng_payload_init(&payload);
- syscall = lttng_event_rule_syscall_create();
+ syscall = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY);
ok(syscall, "syscall object.");
status = lttng_event_rule_syscall_set_pattern(syscall, pattern);