One Level Up
Top Level
runtime/lib_kdebug.c - ktap
Global variables defined
Functions defined
Source code
- #include <linux/module.h>
- #include <linux/ctype.h>
- #include <linux/slab.h>
- #include <linux/version.h>
- #include <linux/ftrace_event.h>
- #include "../include/ktap_types.h"
- #include "ktap.h"
- #include "kp_obj.h"
- #include "kp_str.h"
- #include "kp_transport.h"
- #include "kp_vm.h"
- #include "kp_events.h"
- static int kplib_kdebug_trace_by_id(ktap_state_t *ks)
- {
- unsigned long uaddr = kp_arg_checknumber(ks, 1);
- ktap_func_t *fn = kp_arg_checkfunction(ks, 2);
- struct task_struct *task = G(ks)->trace_task;
- ktap_eventdesc_t eventsdesc;
- char *filter = NULL;
- int *id_arr;
- int ret, i;
- if (G(ks)->mainthread != ks) {
- kp_error(ks,
- "kdebug.trace_by_id only can be called in mainthread\n");
- return -1;
- }
-
- if (G(ks)->state != KTAP_RUNNING) {
- kp_error(ks,
- "kdebug.trace_by_id only can be called in RUNNING state\n");
- return -1;
- }
-
- ret = copy_from_user(&eventsdesc, (void *)uaddr,
- sizeof(ktap_eventdesc_t));
- if (ret < 0)
- return -1;
- if (eventsdesc.filter) {
- int len;
- len = strlen_user(eventsdesc.filter);
- if (len > 0x1000)
- return -1;
- filter = kmalloc(len + 1, GFP_KERNEL);
- if (!filter)
- return -1;
-
- if (strncpy_from_user(filter, eventsdesc.filter, len) < 0) {
- kfree(filter);
- return -1;
- }
- }
- id_arr = kmalloc(eventsdesc.nr * sizeof(int), GFP_KERNEL);
- if (!id_arr) {
- kfree(filter);
- return -1;
- }
-
- ret = copy_from_user(id_arr, eventsdesc.id_arr,
- eventsdesc.nr * sizeof(int));
- if (ret < 0) {
- kfree(filter);
- kfree(id_arr);
- return -1;
- }
- fn = clvalue(kp_arg(ks, 2));
- for (i = 0; i < eventsdesc.nr; i++) {
- struct perf_event_attr attr;
- cond_resched();
- if (signal_pending(current)) {
- flush_signals(current);
- kfree(filter);
- kfree(id_arr);
- return -1;
- }
- memset(&attr, 0, sizeof(attr));
- attr.type = PERF_TYPE_TRACEPOINT;
- attr.config = id_arr[i];
- attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
- PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD;
- attr.sample_period = 1;
- attr.size = sizeof(attr);
- attr.disabled = 0;
-
- ret = kp_event_create(ks, &attr, task, filter, fn);
- if (ret < 0)
- break;
- }
- kfree(filter);
- kfree(id_arr);
- return 0;
- }
- static int kplib_kdebug_trace_end(ktap_state_t *ks)
- {
-
- G(ks)->trace_end_closure = kp_arg_checkfunction(ks, 1);
- return 0;
- }
- #if 0
- #endif
- static int kplib_kdebug_kprobe(ktap_state_t *ks)
- {
- const char *event_name = kp_arg_checkstring(ks, 1);
- ktap_func_t *fn = kp_arg_checkfunction(ks, 2);
- if (G(ks)->mainthread != ks) {
- kp_error(ks,
- "kdebug.kprobe only can be called in mainthread\n");
- return -1;
- }
-
- if (G(ks)->state != KTAP_RUNNING) {
- kp_error(ks,
- "kdebug.kprobe only can be called in RUNNING state\n");
- return -1;
- }
- return kp_event_create_kprobe(ks, event_name, fn);
- }
- static const ktap_libfunc_t kdebug_lib_funcs[] = {
- {"trace_by_id", kplib_kdebug_trace_by_id},
- {"trace_end", kplib_kdebug_trace_end},
- #if 0
- #endif
- {"kprobe", kplib_kdebug_kprobe},
- {NULL}
- };
- int kp_lib_init_kdebug(ktap_state_t *ks)
- {
- return kp_vm_register_lib(ks, "kdebug", kdebug_lib_funcs);
- }
One Level Up
Top Level