dwarves/ctracer.c

798 lines
22 KiB
C
Raw Normal View History

/*
Copyright (C) 2006 Mandriva Conectiva S.A.
Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@mandriva.com>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
*/
#include <argp.h>
#include <limits.h>
#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "dwarves.h"
/*
* List of compilation units being looked for functions with
* pointers to the specified struct.
*/
static struct cus *methods_cus;
/**
* Compilation units with the definitions for the kprobes functions and struct
* definitions for the, can point to methods_cus if those definitions are
* available there (example: when using 'ctracer vmlinux sk_buff', vmlinux
* will have the sk_buff "methods" and the kprobes "classes" and "methods".
*/
static struct cus *kprobes_cus;
/**
* Mini class, the subset of the traced class that is collected at the probes
*/
static struct class *mini_class;
/*
* Directory where to generate source files
*/
static const char *src_dir = ".";
/*
* Where to print the ctracer_methods.c file
*/
static FILE *fp_methods;
/*
* List of definitions and forward declarations already emitted for
* methods_cus and kprobes_cus, to avoid duplication.
*/
static LIST_HEAD(cus__definitions);
static LIST_HEAD(cus__fwd_decls);
/*
* List of jprobes and kretprobes already emitted, this is a hack to cope with
* name space collisions, a better solution would be to in these cases to use the
* compilation unit name (net/ipv4/tcp.o, for instance) as a prefix when a
* static function has the same name in multiple compilation units (aka object
* files).
*/
static void *jprobes_emitted;
static void *kretprobes_emitted;
static int methods__compare(const void *a, const void *b)
{
return strcmp(a, b);
}
/*
* Add a method to jprobes_emitted or kretprobes_emitted, see comment above.
*/
static int methods__add(void **table, const char *str)
{
char **s = tsearch(str, table, methods__compare);
if (s != NULL) {
if (*s == str) {
char *dup = strdup(str);
if (dup != NULL)
*s = dup;
else {
tdelete(str, table, methods__compare);
return -1;
}
} else
return -1;
} else
return -1;
return 0;
}
static void method__add(struct cu *cu, struct function *function)
{
list_add(&function->tool_node, &cu->tool_list);
}
/*
* We want just the DW_TAG_subprogram tags that have as one of its parameters
* a pointer to the specified "class" (a struct, unions can be added later).
*/
static struct tag *function__filter(struct tag *tag, struct cu *cu, void *cookie)
{
struct function *function;
if (tag->tag != DW_TAG_subprogram)
return NULL;
function = tag__function(tag);
if (function__inlined(function) ||
function->abstract_origin != 0 ||
!ftype__has_parm_of_type(&function->proto, cookie, cu))
return NULL;
return tag;
}
/*
* Add the function to the list of methods since it matches function__filter
* criteria.
*/
static int find_methods_iterator(struct tag *tag, struct cu *cu,
void *cookie __unused)
{
struct function *function = tag__function(tag);
method__add(cu, function);
return 0;
}
/*
* Iterate thru all the tags in the compilation unit, looking just for the
* DW_TAG_subprogram tags that have as one of its parameters a pointer to
* the specified "class" (struct).
*/
static int cu_find_methods_iterator(struct cu *cu, void *cookie)
{
struct tag *target = cu__find_struct_by_name(cu, cookie);
if (target == NULL)
return 0;
return cu__for_each_tag(cu, find_methods_iterator, target, function__filter);
}
static void class__remove_member(struct class *self, const struct cu *cu,
struct class_member *member)
{
const size_t size = class_member__size(member, cu);
/*
* Is this the first member?
*/
if (member->tag.node.prev == &self->type.members) {
self->type.size -= size;
class__subtract_offsets_from(self, cu, member, size);
} else {
struct class_member *from_prev =
list_entry(member->tag.node.prev,
struct class_member, tag.node);
if (member->hole + size >= cu->addr_size) {
self->type.size -= size + member->hole;
class__subtract_offsets_from(self, cu, member,
size + member->hole);
} else
from_prev->hole += size + member->hole;
}
if (member->hole != 0)
self->nr_holes--;
list_del(&member->tag.node);
class_member__delete(member);
}
static size_t class__find_biggest_member_name(const struct class *self)
{
struct class_member *pos;
size_t biggest_name_len = 0;
list_for_each_entry(pos, &self->type.members, tag.node) {
const size_t len = strlen(pos->name);
if (len > biggest_name_len)
biggest_name_len = len;
}
return biggest_name_len;
}
static void class__emit_class_state_collector(const struct class *self,
const struct class *clone)
{
struct class_member *pos;
int len = class__find_biggest_member_name(clone);
fprintf(fp_methods,
"void ctracer__class_state(const void *from, void *to)\n"
"{\n"
"\tconst struct %s *obj = from;\n"
"\tstruct %s *mini_obj = to;\n\n",
class__name(self), class__name(clone));
list_for_each_entry(pos, &clone->type.members, tag.node) {
fprintf(fp_methods, "\tmini_obj->%-*s = obj->%s;\n",
len, pos->name, pos->name);
}
fputs("}\n\n", fp_methods);
}
static struct class *class__clone_base_types(const struct tag *tag_self,
const struct cu *cu,
const char *new_class_name)
{
struct class *self = tag__class(tag_self);
struct class_member *pos, *next;
struct class *clone = class__clone(self, new_class_name);
if (clone == NULL)
return NULL;
class__find_holes(clone, cu);
list_for_each_entry_safe(pos, next, &clone->type.members, tag.node) {
struct tag *member_type = cu__find_tag_by_id(cu, pos->tag.type);
if (member_type->tag != DW_TAG_base_type)
class__remove_member(clone, cu, pos);
}
class__reorganize(clone, cu, 0, NULL);
return clone;
}
/**
* Converter to the legacy ostra tables, will be much improved in the future.
*/
static void emit_struct_member_table_entry(FILE *fp,
int field, const char *name,
int traced, const char *hooks)
{
fprintf(fp, "%u:%s:", field, name);
if (traced)
fprintf(fp, "yes:%%object->%s:u:%s:none\n", name, hooks);
else
fprintf(fp, "no:None:None:%s:dev_null\n", hooks);
}
/**
* Generates a converter to the ostra lebacy tables format, needef by
* ostra-cg to preprocess the raw data collected from the debugfs/relay
* channel.
*/
static int class__emit_ostra_converter(const struct tag *tag_self,
const struct cu *cu)
{
const struct class *self = tag__class(tag_self);
struct class_member *pos;
struct type *type = &mini_class->type;
int field = 0, first = 1;
char filename[128];
char parm_list[1024];
char *p = parm_list;
size_t n;
size_t plen = sizeof(parm_list);
FILE *fp_fields, *fp_converter;
snprintf(filename, sizeof(filename), "%s/%s.fields",
src_dir, class__name(self));
fp_fields = fopen(filename, "w");
if (fp_fields == NULL) {
fprintf(stderr, "ctracer: couldn't create %s\n", filename);
exit(EXIT_FAILURE);
}
snprintf(filename, sizeof(filename), "%s/ctracer2ostra.c", src_dir);
fp_converter = fopen(filename, "w");
if (fp_converter == NULL) {
fprintf(stderr, "ctracer: couldn't create %s\n", filename);
exit(EXIT_FAILURE);
}
fputs("#include <stdio.h>\n"
"#include <string.h>\n"
"#include \"ctracer_relay.h\"\n\n", fp_converter);
class__fprintf(mini_class, cu, NULL, fp_converter);
emit_struct_member_table_entry(fp_fields, field++, "action", 0,
"entry,exit");
emit_struct_member_table_entry(fp_fields, field++, "function_id", 0,
"entry,exit");
emit_struct_member_table_entry(fp_fields, field++, "object", 1,
"entry,exit");
fputs("\n"
"int main(void)\n"
"{\n"
"\twhile (1) {\n"
"\t\tstruct trace_entry hdr;\n"
"\t\tstruct ctracer__mini_sock obj;\n"
"\n"
"\t\tif (read(0, &hdr, sizeof(hdr)) != sizeof(hdr))\n"
"\t\t\tbreak;\n"
"\n"
"\t\tfprintf(stdout, \"%u.%06u %c:%llu:%p\",\n"
"\t\t\thdr.sec, hdr.usec,\n"
"\t\t\thdr.probe_type ? 'o' : 'i',\n"
"\t\t\thdr.function_id,\n"
"\t\t\thdr.object);\n"
"\n"
"\t\tif (hdr.probe_type) {\n"
"\t\t\tfputc('\\n', stdout);\n"
"\t\t\tcontinue;\n"
"\t\t}\n"
"\n"
"\t\tif (read(0, &obj, sizeof(obj)) != sizeof(obj))\n"
"\t\t\tbreak;\n"
"\t\tfprintf(stdout,\n"
"\t\t\t\":",
fp_converter);
list_for_each_entry(pos, &type->members, tag.node) {
if (first)
first = 0;
else {
fputc(':', fp_converter);
n = snprintf(p, plen, ",\n\t\t\t ");
plen -= n; p += n;
}
fprintf(fp_converter, "%%u");
n = snprintf(p, plen, "obj.%s", pos->name);
plen -= n; p += n;
emit_struct_member_table_entry(fp_fields, field++,
pos->name, 1, "entry");
}
fprintf(fp_converter,
"\\n\",\n\t\t\t %s);\n"
"\t}\n"
"\treturn 0;\n"
"}\n", parm_list);
fclose(fp_fields);
fclose(fp_converter);
return 0;
}
static int class__emit_subset(const struct tag *tag_self, const struct cu *cu)
{
struct class *self = tag__class(tag_self);
int err = -1;
char mini_class_name[128];
snprintf(mini_class_name, sizeof(mini_class_name), "ctracer__mini_%s",
class__name(self));
mini_class = class__clone_base_types(tag_self, cu, mini_class_name);
if (mini_class == NULL)
goto out;
class__fprintf(mini_class, cu, NULL, fp_methods);
fputc('\n', fp_methods);
class__emit_class_state_collector(self, mini_class);
err = 0;
out:
return err;
}
/*
* Emit the kprobes routine for one of the selected "methods", later we'll
* put this into the 'kprobes' table, in cu_emit_kprobes_table_iterator.
*
* This marks the function entry, function__emit_kretprobes will emit the
* probe for the function exit.
*/
static int function__emit_kprobes(struct function *self, const struct cu *cu,
const struct tag *target)
{
char jprobe_name[256];
struct parameter *pos;
const char *name = function__name(self, cu);
fputs("static ", fp_methods);
snprintf(jprobe_name, sizeof(jprobe_name), "jprobe_entry__%s", name);
ftype__fprintf(&self->proto, cu, jprobe_name, 0, 0, 0, fp_methods);
fputs("\n{\n", fp_methods);
list_for_each_entry(pos, &self->proto.parms, tag.node) {
struct tag *type = cu__find_tag_by_id(cu, pos->tag.type);
if (type->tag != DW_TAG_pointer_type)
continue;
type = cu__find_tag_by_id(cu, type->type);
if (type == NULL || type->id != target->id)
continue;
fprintf(fp_methods,
"\tctracer__method_entry(%#llx, %s, %zd);\n",
(unsigned long long)self->proto.tag.id, pos->name,
class__size(mini_class));
break;
}
fprintf(fp_methods, "\tjprobe_return();\n"
"\t/* NOTREACHED */%s\n}\n\n",
self->proto.tag.type != 0 ? "\n\treturn 0;" : "");
fprintf(fp_methods, "static struct jprobe jprobe__%s = {\n"
"\t.kp = { .symbol_name = \"%s\", },\n"
"\t.entry = (kprobe_opcode_t *)jprobe_entry__%s,\n"
"};\n\n", name, name, name);
return 0;
}
/*
* Iterate thru the list of methods previously collected by
* cu_find_methods_iterator, emitting the probes for function entry.
*/
static int cu_emit_kprobes_iterator(struct cu *cu, void *cookie)
{
struct tag *target = cu__find_struct_by_name(cu, cookie);
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node) {
if (methods__add(&jprobes_emitted, function__name(pos, cu)) != 0)
continue;
pos->priv = (void *)1; /* Mark as visited, for the table iterator */
cus__emit_ftype_definitions(methods_cus, cu,
&pos->proto, fp_methods);
function__emit_kprobes(pos, cu, target);
}
return 0;
}
/*
* Iterate thru the list of methods previously collected by
* cu_find_methods_iterator, creating the 'kprobes' table, that will
* be used at the module init routine to register the kprobes for function
* entry, and at module exit time to unregister the kprobes.
*/
static int cu_emit_kprobes_table_iterator(struct cu *cu, void *cookie __unused)
{
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node)
if (pos->priv != NULL) {
const char *name = function__name(pos, cu);
fprintf(fp_methods, "\t&jprobe__%s,\n", name);
fprintf(cookie, "%llu:%s\n",
(unsigned long long)pos->proto.tag.id, name);
}
return 0;
}
/*
* Emit the kprobes routine for one of the selected "methods", later we'll
* put this into the 'kprobes' table, in cu_emit_kprobes_table_iterator.
*
* This marks the function exit.
*
* We still need to get the pointer to the "class instance", i.e. the pointer
* to the specified struct, this will be done using the "data pouch" mentioned
* in the kprobes mailing list, where we at the entry kprobes we store the
* pointer to be used here, or possibly using plain kprobes at the function
* entry and using DW_AT_location to discover where in the stack or in a
* processor register were the parameters for the function.
*/
static void function__emit_kretprobes(struct function *self,
const struct cu *cu)
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
{
const char *name = function__name(self, cu);
fprintf(fp_methods,
"static int kretprobe_handler__%s(struct kretprobe_instance *ri, "
"struct pt_regs *regs)\n"
"{\n"
"\tctracer__method_exit(%#llx);\n"
"\treturn 0;\n"
"}\n\n", name, (unsigned long long)self->proto.tag.id);
fprintf(fp_methods,
"static struct kretprobe kretprobe__%s = {\n"
"\t.kp = { .symbol_name = \"%s\", },\n"
"\t.handler = (kretprobe_handler_t)kretprobe_handler__%s,\n"
"};\n\n", name, name, name);
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
}
/*
* Iterate thru the list of methods previously collected by
* cu_find_methods_iterator, emitting the probes for function exit.
*/
static int cu_emit_kretprobes_iterator(struct cu *cu, void *cookie __unused)
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
{
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node) {
if (methods__add(&kretprobes_emitted,
function__name(pos, cu)) != 0)
continue;
pos->priv = (void *)1; /* Mark as visited, for the table iterator */
function__emit_kretprobes(pos, cu);
}
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
return 0;
}
/*
* Iterate thru the list of methods previously collected by
* cu_find_methods_iterator, creating the 'kretprobes' table, that will
* be used at the module init routine to register the kprobes for function
* entry, and at module exit time to unregister the kretprobes.
*/
static int cu_emit_kretprobes_table_iterator(struct cu *cu,
void *cookie __unused)
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
{
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node)
if (pos->priv != NULL)
fprintf(fp_methods, "\t&kretprobe__%s,\n",
function__name(pos, cu));
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
return 0;
}
/*
* Emit a definition for the specified function, looking for it in the
* tags previously collected, cus__emit_ftype_definitions will look at the
* function return type and recursively emit all the definitions needed,
* ditto for all the function parameters, emitting just a forward declaration
* if the parameter is just a pointer, or all of the enums, struct, unions,
* etc that are required for the resulting C source code to be built.
*/
static void emit_function_defs(const char *fn)
{
struct cu *cu;
struct tag *f = cus__find_function_by_name(kprobes_cus, &cu, fn);
if (f != NULL) {
cus__emit_ftype_definitions(kprobes_cus, cu,
&tag__function(f)->proto,
fp_methods);
tag__fprintf(f, cu, NULL, fp_methods);
fputs(";\n", fp_methods);
}
}
/*
* Emit a struct definition, looking at all the function members and recursively
* emitting its type definitions (enums, structs, unions, etc).
*/
static void emit_struct_defs(const char *name)
{
struct cu *cu;
struct tag *c = cus__find_struct_by_name(kprobes_cus, &cu, name);
if (c != NULL) {
cus__emit_type_definitions(kprobes_cus, cu, c, fp_methods);
type__emit(c, cu, NULL, NULL, fp_methods);
}
}
/*
* Emit a forward declaration ("struct foo;" or "union bar").
*/
static void emit_class_fwd_decl(const char *name)
{
struct cu *cu;
struct tag *c = cus__find_struct_by_name(kprobes_cus, &cu, name);
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
if (c != NULL)
cus__emit_fwd_decl(kprobes_cus, tag__type(c), fp_methods);
}
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
/*
* Emit the definitions used in the resulting kernel module C source code,
* we do this to avoid using #includes, that would emit definitions for
* things we emit, causing redefinitions.
*/
static void emit_module_preamble(void)
{
fputs("#include \"ctracer_relay.h\"\n", fp_methods);
emit_struct_defs("jprobe");
emit_struct_defs("kretprobe");
emit_class_fwd_decl("pt_regs");
emit_class_fwd_decl("kretprobe_instance");
[CTRACER]: Emit kretprobes too Now we get this using 'ctracer vmlinux sk_buff', for just one ping packet: [14402.349410] -> ne2k_pci_block_input: skb=cea97c00 [14402.351310] <- ne2k_pci_block_input [14402.352712] -> eth_type_trans: skb=cea97c00 [14402.353909] <- eth_type_trans [14402.354721] -> netif_rx: skb=cea97c00 [14402.355682] <- netif_rx [14402.356691] -> netif_receive_skb: skb=cea97c00 [14402.358007] -> arp_rcv: skb=cea97c00 [14402.359023] -> arp_process: skb=cea97c00 [14402.360152] -> ip_route_input: skb=cea97c00 [14402.361980] <- ip_route_input [14402.369199] -> eth_header: skb=cea97b40 [14402.370336] <- eth_header [14402.371159] -> arp_xmit: skb=cea97b40 [14402.372580] -> dev_queue_xmit: skb=cea97b40 [14402.373742] -> pfifo_fast_enqueue: skb=cea97b40 [14402.374849] <- pfifo_fast_enqueue [14402.375827] -> dev_hard_start_xmit: skb=cea97b40 [14402.377021] -> ei_start_xmit: skb=cea97b40 [14402.378759] -> kfree_skb: skb=cea97b40 [14402.379783] -> __kfree_skb: skb=cea97b40 [14402.380854] -> kfree_skbmem: skb=cea97b40 [14402.382675] -> ne2k_pci_block_input: skb=cea97a80 [14402.383816] <- ne2k_pci_block_input [14402.384656] -> eth_type_trans: skb=cea97a80 [14402.385632] <- eth_type_trans [14402.386366] -> netif_rx: skb=cea97a80 [14402.387220] <- netif_rx [14402.387949] -> skb_release_data: skb=cea97b40 [14402.389069] <- skb_release_data [14402.389856] <- kfree_skbmem [14402.390715] <- __kfree_skb [14402.391761] <- kfree_skb [14402.392875] <- ei_start_xmit [14402.393594] <- dev_hard_start_xmit [14402.394459] <- dev_queue_xmit [14402.395169] <- arp_xmit [14402.395852] -> kfree_skb: skb=cea97c00 [14402.396764] -> __kfree_skb: skb=cea97c00 [14402.397717] -> kfree_skbmem: skb=cea97c00 [14402.398677] -> skb_release_data: skb=cea97c00 [14402.399909] <- skb_release_data [14402.400637] <- kfree_skbmem [14402.401267] <- __kfree_skb [14402.401875] <- kfree_skb [14402.402489] <- arp_process [14402.403156] <- arp_rcv [14402.403757] <- netif_receive_skb [14402.404674] -> netif_receive_skb: skb=cea97a80 [14402.405789] -> ip_rcv: skb=cea97a80 [14402.406837] -> ip_route_input: skb=cea97a80 [14402.407845] <- ip_route_input [14402.408654] -> ip_local_deliver: skb=cea97a80 [14402.410031] -> icmp_rcv: skb=cea97a80 [14402.411105] -> __skb_checksum_complete: skb=cea97a80 [14402.412397] <- __skb_checksum_complete [14402.413512] -> icmp_echo: skb=cea97a80 [14402.414584] -> icmp_reply: skb=cea97a80 [14402.415665] -> ip_options_echo: skb=cea97a80 [14402.416827] <- ip_options_echo [14402.418188] -> dummy_xfrm_decode_session: skb=cea97a80 [14402.419426] <- dummy_xfrm_decode_session [14402.422520] -> icmp_glue_bits: skb=cea97c00 [14402.424001] <- icmp_glue_bits [14402.426607] -> ip_output: skb=cea97c00 [14402.428314] -> neigh_resolve_output: skb=cea97c00 [14402.429559] -> __neigh_event_send: skb=cea97c00 [14402.430747] <- __neigh_event_send [14402.432143] -> eth_header: skb=cea97c00 [14402.433059] <- eth_header [14402.433754] -> dev_queue_xmit: skb=cea97c00 [14402.434763] -> pfifo_fast_enqueue: skb=cea97c00 [14402.435782] <- pfifo_fast_enqueue [14402.437177] -> dev_hard_start_xmit: skb=cea97c00 [14402.438281] -> ei_start_xmit: skb=cea97c00 [14402.439634] -> kfree_skb: skb=cea97c00 [14402.440543] -> __kfree_skb: skb=cea97c00 [14402.441530] -> sock_wfree: skb=cea97c00 [14402.442730] <- sock_wfree [14402.443433] -> kfree_skbmem: skb=cea97c00 [14402.444383] -> skb_release_data: skb=cea97c00 [14402.445628] <- skb_release_data [14402.446370] <- kfree_skbmem [14402.447004] <- __kfree_skb [14402.447613] <- kfree_skb [14402.448207] <- ei_start_xmit [14402.448862] <- dev_hard_start_xmit [14402.449627] <- dev_queue_xmit [14402.450328] <- neigh_resolve_output [14402.451159] <- ip_output [14402.451987] <- icmp_reply [14402.452639] <- icmp_echo [14402.453326] -> kfree_skb: skb=cea97a80 [14402.454220] -> __kfree_skb: skb=cea97a80 [14402.601772] -> kfree_skbmem: skb=cea97a80 [14402.602809] -> skb_release_data: skb=cea97a80 [14402.603762] <- skb_release_data [14402.604479] <- kfree_skbmem [14402.605072] <- __kfree_skb [14402.605646] <- kfree_skb [14402.606392] <- icmp_rcv [14402.606996] <- ip_local_deliver [14402.607694] <- ip_rcv [14402.608236] <- netif_receive_skb [14408.809296] -> arp_solicit: skb=00000000 [14408.811051] -> eth_header: skb=cea97a80 [14408.811977] <- eth_header [14408.812845] -> arp_xmit: skb=cea97a80 [14408.813765] -> dev_queue_xmit: skb=cea97a80 [14408.814760] -> pfifo_fast_enqueue: skb=cea97a80 [14408.815763] <- pfifo_fast_enqueue [14408.816657] -> dev_hard_start_xmit: skb=cea97a80 [14408.817730] -> ei_start_xmit: skb=cea97a80 [14408.818989] -> kfree_skb: skb=cea97a80 [14408.819892] -> __kfree_skb: skb=cea97a80 [14408.821529] -> ne2k_pci_block_input: skb=cea97c00 [14408.822605] <- ne2k_pci_block_input [14408.823442] -> eth_type_trans: skb=cea97c00 [14408.824454] <- eth_type_trans [14408.825198] -> netif_rx: skb=cea97c00 [14408.826049] <- netif_rx [14408.826732] -> kfree_skbmem: skb=cea97a80 [14408.827681] -> skb_release_data: skb=cea97a80 [14408.828755] <- skb_release_data [14408.829482] <- kfree_skbmem [14408.830111] <- __kfree_skb [14408.830720] <- kfree_skb [14408.831312] <- ei_start_xmit [14408.835039] <- dev_hard_start_xmit [14408.835864] <- dev_queue_xmit [14408.836495] <- arp_xmit [14408.837114] <- arp_solicit [14408.837889] -> netif_receive_skb: skb=cea97c00 [14408.838897] -> arp_rcv: skb=cea97c00 [14408.839933] -> arp_process: skb=cea97c00 [14408.841326] -> kfree_skb: skb=cea97c00 [14408.842194] -> __kfree_skb: skb=cea97c00 [14408.843070] -> kfree_skbmem: skb=cea97c00 [14408.844025] -> skb_release_data: skb=cea97c00 [14408.844932] <- skb_release_data [14408.845595] <- kfree_skbmem [14408.846181] <- __kfree_skb [14408.846749] <- kfree_skb [14408.847299] <- arp_process [14408.847944] <- arp_rcv [14408.848473] <- netif_receive_skb Now we're getting to the point where a better, non printk based relaying module is in demand, will look at blktrace relayfs stuff. Getting access to the traced parameter at kretprobes time is badly needed, so that we can correlate the exit calls with the entry ones. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> [14385.224958] ctracer: registered 331 entry probes [14385.248000] ctracer: registered 331 exit probes
2006-12-24 02:42:39 +01:00
emit_function_defs("printk");
emit_function_defs("jprobe_return");
}
static const struct argp_option ctracer__options[] = {
{
.key = 'd',
.name = "src_dir",
.arg = "SRC_DIR",
.doc = "generate source files in this directory",
},
{
.key = 'D',
.name = "dir",
.arg = "DIR",
.doc = "load files in this directory",
},
{
.key = 'g',
.name = "glob",
.arg = "GLOB",
.doc = "file mask to load",
},
{
.key = 'k',
.name = "kprobes",
.arg = "FILE",
.doc = "kprobes object file",
},
{
.key = 'r',
.name = "recursive",
.doc = "recursively load files",
},
{
.name = NULL,
}
};
static const char *dirname, *glob, *kprobes_filename;
static char *class_name;
static int recursive;
static error_t ctracer__options_parser(int key, char *arg,
struct argp_state *state __unused)
{
switch (key) {
case 'd': src_dir = arg; break;
case 'D': dirname = arg; break;
case 'g': glob = arg; break;
case 'k': kprobes_filename = arg; break;
case 'r': recursive = 1; break;
default: return ARGP_ERR_UNKNOWN;
}
return 0;
}
static const char ctracer__args_doc[] = "[FILE] [CLASS]";
static struct argp ctracer__argp = {
.options = ctracer__options,
.parser = ctracer__options_parser,
.args_doc = ctracer__args_doc,
};
int main(int argc, char *argv[])
{
int remaining, err;
struct tag *class;
struct cu *cu;
const char *filename;
char functions_filename[PATH_MAX];
char methods_filename[PATH_MAX];
FILE *fp;
argp_parse(&ctracer__argp, argc, argv, 0, &remaining, NULL);
if (remaining < argc) {
switch (argc - remaining) {
case 1: if (kprobes_filename == NULL)
goto failure;
class_name = argv[remaining++]; break;
case 2: filename = argv[remaining++];
class_name = argv[remaining++]; break;
default: goto failure;
}
} else {
failure:
argp_help(&ctracer__argp, stderr, ARGP_HELP_SEE, "ctracer");
return EXIT_FAILURE;
}
/*
* Initialize libdwarves, for now just to get the machine L1 cacheline
* size, in the future may do more stuff.
*/
dwarves__init(0);
/*
* Create the methods_cus (Compilation Units) object where we will
* load the objects where we'll look for functions pointers to the
* specified class, i.e. to find its "methods", where we'll insert
* the entry and exit hooks.
*/
methods_cus = cus__new(&cus__definitions, &cus__fwd_decls);
if (methods_cus == NULL) {
out_enomem:
fputs("ctracer: insufficient memory\n", stderr);
return EXIT_FAILURE;
}
/*
* If --kprobes was specified load the binary with the definitions
* for the kprobes structs and functions used in the generated kernel
* module C source file.
*/
if (kprobes_filename != NULL) {
kprobes_cus = cus__new(&cus__definitions, &cus__fwd_decls);
if (kprobes_cus == NULL)
goto out_enomem;
err = cus__load(kprobes_cus, kprobes_filename);
if (err != 0) {
filename = kprobes_filename;
goto out_dwarf_err;
}
} else {
/*
* Or use the methods_cus specified for the methods as the
* source for the kprobes structs and functions definitions.
*/
kprobes_cus = methods_cus;
}
/*
* if --dir/-D was specified, recursively traverse the path looking for
* object files (compilation units) that match the glob specified (*.ko)
* for kernel modules, but could be "*.o" in the future when we support
* uprobes for user space tracing.
*/
if (dirname != NULL && cus__load_dir(methods_cus, dirname, glob,
recursive) != 0) {
fprintf(stderr, "ctracer: couldn't load DWARF info "
"from %s dir with glob %s\n",
dirname, glob);
return EXIT_FAILURE;
}
/*
* If a filename was specified, for instance "vmlinux", load it too.
*/
if (filename != NULL) {
err = cus__load(methods_cus, filename);
if (err != 0) {
out_dwarf_err:
cus__print_error_msg("ctracer", filename, err);
return EXIT_FAILURE;
}
}
/*
* See if the specified struct exists:
*/
class = cus__find_struct_by_name(methods_cus, &cu, class_name);
if (class == NULL) {
fprintf(stderr, "ctracer: struct %s not found!\n", class_name);
return EXIT_FAILURE;
}
snprintf(functions_filename, sizeof(functions_filename),
"%s/%s.functions", src_dir, class__name(tag__class(class)));
fp = fopen(functions_filename, "w");
if (fp == NULL) {
fprintf(stderr, "ctracer: couldn't create %s\n",
functions_filename);
exit(EXIT_FAILURE);
}
snprintf(methods_filename, sizeof(methods_filename),
"%s/ctracer_methods.c", src_dir);
fp_methods = fopen(methods_filename, "w");
if (fp_methods == NULL) {
fprintf(stderr, "ctracer: couldn't create %s\n",
methods_filename);
exit(EXIT_FAILURE);
}
emit_module_preamble();
cus__emit_type_definitions(methods_cus, cu, class, fp_methods);
type__emit(class, cu, NULL, NULL, fp_methods);
class__emit_subset(class, cu);
class__emit_ostra_converter(class, cu);
cus__for_each_cu(methods_cus, cu_find_methods_iterator,
class_name, NULL);
cus__for_each_cu(methods_cus, cu_emit_kprobes_iterator,
class_name, NULL);
cus__for_each_cu(methods_cus, cu_emit_kretprobes_iterator,
NULL, NULL);
fputs("struct jprobe *ctracer__jprobes[] = {", fp_methods);
cus__for_each_cu(methods_cus, cu_emit_kprobes_table_iterator,
fp, NULL);
/* Emit the sentinel */
fputs("\t(void *)0,\n};\n", fp_methods);
fclose(fp);
fputs("struct kretprobe *ctracer__kretprobes[] = {", fp_methods);
cus__for_each_cu(methods_cus, cu_emit_kretprobes_table_iterator,
NULL, NULL);
/* Emit the sentinel */
fputs("\t(void *)0,\n};\n", fp_methods);
return EXIT_SUCCESS;
}