*/
#define _LGPL_SOURCE
-#include <stdbool.h>
+#include "kernel.hpp"
+#include "lttng-sessiond.hpp"
+#include "lttng-syscall.hpp"
+#include "utils.hpp"
#include <common/common.hpp>
#include <common/kernel-ctl/kernel-ctl.hpp>
+#include <common/urcu.hpp>
-#include "lttng-sessiond.hpp"
-#include "kernel.hpp"
-#include "lttng-syscall.hpp"
-#include "utils.hpp"
+#include <stdbool.h>
/* Global syscall table. */
struct syscall *syscall_table;
char name[SYSCALL_NAME_LEN];
#if (SYSCALL_NAME_LEN == 255)
-#define SYSCALL_NAME_LEN_SCANF_IS_A_BROKEN_API "254"
+#define SYSCALL_NAME_LEN_SCANF_IS_A_BROKEN_API "254"
#endif
DBG3("Syscall init system call table");
}
while (fscanf(fp,
- "syscall { index = %zu; \
+ "syscall { index = %zu; \
name = %" SYSCALL_NAME_LEN_SCANF_IS_A_BROKEN_API "[^;]; \
bitness = %u; };\n",
- &index, name, &bitness) == 3) {
+ &index,
+ name,
+ &bitness) == 3) {
at_least_one_syscall = true;
if (index >= nbmem) {
struct syscall *new_list;
/* Overflow, stop everything, something went really wrong. */
ERR("Syscall listing memory size overflow. Stopping");
free(syscall_table);
- syscall_table = NULL;
+ syscall_table = nullptr;
ret = -EINVAL;
goto error;
}
- DBG("Reallocating syscall table from %zu to %zu entries", nbmem,
- new_nbmem);
- new_list = (struct syscall *) realloc(syscall_table, new_nbmem * sizeof(*new_list));
+ DBG("Reallocating syscall table from %zu to %zu entries", nbmem, new_nbmem);
+ new_list = (struct syscall *) realloc(syscall_table,
+ new_nbmem * sizeof(*new_list));
if (!new_list) {
ret = -errno;
PERROR("syscall list realloc");
}
/* Zero out the new memory. */
- memset(new_list + nbmem, 0,
- (new_nbmem - nbmem) * sizeof(*new_list));
+ memset(new_list + nbmem, 0, (new_nbmem - nbmem) * sizeof(*new_list));
nbmem = new_nbmem;
syscall_table = new_list;
}
syscall_table[index].index = index;
syscall_table[index].bitness = bitness;
- if (lttng_strncpy(syscall_table[index].name, name,
- sizeof(syscall_table[index].name))) {
+ if (lttng_strncpy(
+ syscall_table[index].name, name, sizeof(syscall_table[index].name))) {
ret = -EINVAL;
free(syscall_table);
- syscall_table = NULL;
+ syscall_table = nullptr;
goto error;
}
/*
* syscall hashtable used to track duplicate between 32 and 64 bit arch.
*
* This empty the hash table and destroys it after. After this, the pointer is
- * unsuable. RCU read side lock MUST be acquired before calling this.
+ * unsuable. RCU read side lock MUST NOT be acquired before calling this.
*/
static void destroy_syscall_ht(struct lttng_ht *ht)
{
struct lttng_ht_iter iter;
struct syscall *ksyscall;
- ASSERT_RCU_READ_LOCKED();
-
DBG3("Destroying syscall hash table.");
if (!ht) {
return;
}
- cds_lfht_for_each_entry(ht->ht, &iter.iter, ksyscall, node.node) {
- int ret;
+ {
+ lttng::urcu::read_lock_guard read_lock;
+
+ cds_lfht_for_each_entry (ht->ht, &iter.iter, ksyscall, node.node) {
+ int ret;
- ret = lttng_ht_del(ht, &iter);
- LTTNG_ASSERT(!ret);
- free(ksyscall);
+ ret = lttng_ht_del(ht, &iter);
+ LTTNG_ASSERT(!ret);
+ free(ksyscall);
+ }
}
+
lttng_ht_destroy(ht);
}
/*
* Lookup a syscall in the given hash table by name.
*
+ * RCU read lock MUST be acquired by the callers of this function.
+ *
* Return syscall object if found or else NULL.
*/
static struct syscall *lookup_syscall(struct lttng_ht *ht, const char *name)
{
struct lttng_ht_node_str *node;
struct lttng_ht_iter iter;
- struct syscall *ksyscall = NULL;
+ struct syscall *ksyscall = nullptr;
LTTNG_ASSERT(ht);
LTTNG_ASSERT(name);
lttng_ht_lookup(ht, (void *) name, &iter);
node = lttng_ht_iter_get_node_str(&iter);
if (node) {
- ksyscall = caa_container_of(node, struct syscall, node);
+ ksyscall = lttng::utils::container_of(node, &syscall::node);
}
return ksyscall;
* syscall at index in the syscall table.
*/
static void update_event_syscall_bitness(struct lttng_event *events,
- unsigned int index, unsigned int syscall_index)
+ unsigned int index,
+ unsigned int syscall_index)
{
LTTNG_ASSERT(events);
if (syscall_table[index].bitness == 32) {
- events[syscall_index].flags = (lttng_event_flag) (events[syscall_index].flags | LTTNG_EVENT_FLAG_SYSCALL_32);
+ events[syscall_index].flags = (lttng_event_flag) (events[syscall_index].flags |
+ LTTNG_EVENT_FLAG_SYSCALL_32);
} else {
- events[syscall_index].flags = (lttng_event_flag) (events[syscall_index].flags | LTTNG_EVENT_FLAG_SYSCALL_64);
+ events[syscall_index].flags = (lttng_event_flag) (events[syscall_index].flags |
+ LTTNG_EVENT_FLAG_SYSCALL_64);
}
}
*
* Return 0 on success else -LTTNG_ERR_NOMEM.
*/
-static int add_syscall_to_ht(struct lttng_ht *ht, unsigned int index,
- unsigned int syscall_index)
+static int add_syscall_to_ht(struct lttng_ht *ht, unsigned int index, unsigned int syscall_index)
{
int ret;
struct syscall *ksyscall;
goto error;
}
- strncpy(ksyscall->name, syscall_table[index].name,
- sizeof(ksyscall->name));
+ strncpy(ksyscall->name, syscall_table[index].name, sizeof(ksyscall->name));
ksyscall->bitness = syscall_table[index].bitness;
ksyscall->index = syscall_index;
lttng_ht_node_init_str(&ksyscall->node, ksyscall->name);
ssize_t ret;
struct lttng_event *events;
/* Hash table used to filter duplicate out. */
- struct lttng_ht *syscalls_ht = NULL;
+ struct lttng_ht *syscalls_ht = nullptr;
LTTNG_ASSERT(_events);
DBG("Syscall table listing.");
- rcu_read_lock();
-
/*
* Allocate at least the number of total syscall we have even if some of
* them might not be valid. The count below will make sure to return the
}
for (i = 0; i < syscall_table_nb_entry; i++) {
- struct syscall *ksyscall;
-
/* Skip empty syscalls. */
if (*syscall_table[i].name == '\0') {
continue;
}
- ksyscall = lookup_syscall(syscalls_ht, syscall_table[i].name);
- if (ksyscall) {
- update_event_syscall_bitness(events, i, ksyscall->index);
- continue;
+ {
+ lttng::urcu::read_lock_guard read_lock;
+ struct syscall *ksyscall;
+
+ ksyscall = lookup_syscall(syscalls_ht, syscall_table[i].name);
+ if (ksyscall) {
+ update_event_syscall_bitness(events, i, ksyscall->index);
+ continue;
+ }
}
ret = add_syscall_to_ht(syscalls_ht, i, index);
}
/* Copy the event information in the event's array. */
- strncpy(events[index].name, syscall_table[i].name,
- sizeof(events[index].name));
+ strncpy(events[index].name, syscall_table[i].name, sizeof(events[index].name));
update_event_syscall_bitness(events, i, index);
events[index].type = LTTNG_EVENT_SYSCALL;
/* This makes the command line not print the enabled/disabled field. */
destroy_syscall_ht(syscalls_ht);
*_events = events;
- rcu_read_unlock();
return index;
error:
destroy_syscall_ht(syscalls_ht);
free(events);
- rcu_read_unlock();
return ret;
}