blob: 542e712570bcb8c4fbf9d7806f1fe35e7d09ec36 [file] [log] [blame]
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#include <errno.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "trace-cmd.h"
#define PLUGIN_DIR ".trace-cmd/plugins"
void parse_cmdlines(char *file, int size __unused)
{
char *comm;
char *line;
char *next = NULL;
int pid;
line = strtok_r(file, "\n", &next);
while (line) {
sscanf(line, "%d %as", &pid,
(float *)(void *)&comm); /* workaround gcc warning */
pevent_register_comm(comm, pid);
line = strtok_r(NULL, "\n", &next);
}
}
void parse_proc_kallsyms(char *file, unsigned int size __unused)
{
unsigned long long addr;
char *func;
char *line;
char *next = NULL;
char *addr_str;
char *mod;
char ch;
int ret;
line = strtok_r(file, "\n", &next);
while (line) {
mod = NULL;
ret = sscanf(line, "%as %c %as\t[%as",
(float *)(void *)&addr_str, /* workaround gcc warning */
&ch,
(float *)(void *)&func,
(float *)(void *)&mod);
addr = strtoull(addr_str, NULL, 16);
free(addr_str);
/* truncate the extra ']' */
if (mod)
mod[strlen(mod) - 1] = 0;
pevent_register_function(func, addr, mod);
line = strtok_r(NULL, "\n", &next);
}
}
void parse_ftrace_printk(char *file, unsigned int size __unused)
{
unsigned long long addr;
char *printk;
char *line;
char *next = NULL;
char *addr_str;
char *fmt;
line = strtok_r(file, "\n", &next);
while (line) {
addr_str = strtok_r(line, ":", &fmt);
addr = strtoull(addr_str, NULL, 16);
/* fmt still has a space, skip it */
printk = strdup(fmt+1);
line = strtok_r(NULL, "\n", &next);
}
}
static int load_plugin(const char *path, const char *file)
{
char *plugin;
void *handle;
pevent_plugin_load_func func;
int ret;
plugin = malloc_or_die(strlen(path) + strlen(file) + 2);
strcpy(plugin, path);
strcat(plugin, "/");
strcat(plugin, file);
handle = dlopen(plugin, RTLD_NOW);
if (!handle) {
warning("cound not load plugin '%s'\n%s\n",
plugin, dlerror());
return -1;
}
func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
if (!func) {
warning("cound not find func '%s' in plugin '%s'\n%s\n",
PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
return -1;
}
printf("registering plugin: %s\n", plugin);
ret = func();
/* dlclose ?? */
return ret;
}
int trace_load_plugins(void)
{
struct dirent *dent;
struct stat st;
DIR *dir;
char *home;
char *path;
int ret;
home = getenv("HOME");
if (!home)
return -1;
path = malloc_or_die(strlen(home) + strlen(PLUGIN_DIR) + 2);
strcpy(path, home);
strcat(path, "/");
strcat(path, PLUGIN_DIR);
ret = stat(path, &st);
if (ret < 0)
goto fail;
if (!S_ISDIR(st.st_mode))
goto fail;
dir = opendir(path);
if (!dir)
goto fail;
while ((dent = readdir(dir))) {
const char *name = dent->d_name;
if (strcmp(name, ".") == 0 ||
strcmp(name, "..") == 0)
continue;
load_plugin(path, name);
}
fail:
free(path);
return -1;
}