[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
This commit is contained in:
Arnaldo Carvalho de Melo 2006-12-23 23:42:39 -02:00
parent ca50c1a52f
commit ff9c2b79cd
1 changed files with 66 additions and 5 deletions

View File

@ -87,7 +87,7 @@ static int function__emit_kprobes(const struct function *self,
continue;
printed = snprintf(bodyp, bodyl,
"\tprintk(\"%s: %s=%%p\\n\", %s);\n",
"\tprintk(\"-> %s: %s=%%p\\n\", %s);\n",
self->name, pos->name, pos->name);
bodyp += printed;
bodyl -= printed;
@ -124,6 +124,41 @@ static int cu_emit_kprobes_table_iterator(struct cu *cu, void *cookie)
return 0;
}
static int function__emit_kretprobes(const struct function *self)
{
printf("static int kretprobe_handler__%s(struct kretprobe_instance *ri, "
"struct pt_regs *regs)\n"
"{\n"
"\tprintk(\"<- %s\\n\");\n"
"\treturn 0;\n"
"}\n\n", self->name, self->name);
printf("static struct kretprobe kretprobe__%s = {\n"
"\t.kp = { .symbol_name = \"%s\", },\n"
"\t.handler = (kretprobe_handler_t)kretprobe_handler__%s,\n"
"\t.maxactive = -1,\n\n"
"};", self->name, self->name, self->name);
}
static int cu_emit_kretprobes_iterator(struct cu *cu, void *cookie)
{
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node)
function__emit_kretprobes(pos);
return 0;
}
static int cu_emit_kretprobes_table_iterator(struct cu *cu, void *cookie)
{
struct function *pos;
list_for_each_entry(pos, &cu->tool_list, tool_node)
printf("\t&kretprobe__%s,\n", pos->name);
return 0;
}
static void emit_function_defs(const char *fn)
{
struct function *f = cus__find_function_by_name(cus, fn);
@ -138,13 +173,26 @@ static void emit_function_defs(const char *fn)
static void emit_module_preamble(void)
{
struct class *c = cus__find_class_by_name(cus, "jprobe");
if (c != NULL)
cus__emit_struct_definitions(cus, c, NULL, NULL);
c = cus__find_class_by_name(cus, "kretprobe");
if (c != NULL)
cus__emit_struct_definitions(cus, c, NULL, NULL);
c = cus__find_class_by_name(cus, "pt_regs");
if (c != NULL)
cus__emit_fwd_decl(cus, c);
c = cus__find_class_by_name(cus, "kretprobe_instance");
if (c != NULL)
cus__emit_fwd_decl(cus, c);
emit_function_defs("printk");
emit_function_defs("register_jprobe");
emit_function_defs("unregister_jprobe");
emit_function_defs("register_kretprobe");
emit_function_defs("unregister_kretprobe");
emit_function_defs("jprobe_return");
}
@ -171,7 +219,7 @@ static void emit_module_init(void)
printf("static int __attribute__ "
"((__section__ (\".init.text\"))) jprobe_init(void)\n"
"{\n"
" unsigned int i = 0, n = 0;\n"
" unsigned int i = 0, nj = 0, nr = 0;\n"
" while (jprobes[i] != (void *)0) {\n"
" int err = register_jprobe(jprobes[i]);\n"
" if (err != 0)\n"
@ -179,10 +227,18 @@ static void emit_module_init(void)
"returned %%d\\n\",\n"
" jprobes[i]->kp.symbol_name, err);\n"
" else\n"
" ++n;\n"
" ++nj;\n"
" err = register_kretprobe(kretprobes[i]);\n"
" if (err != 0)\n"
" printk(\"register_kretprobe(%%s) failed, "
"returned %%d\\n\",\n"
" kretprobes[i]->kp.symbol_name, err);\n"
" else\n"
" ++nr;\n"
" ++i;\n"
" }\n\n"
" printk(\"ctracer: registered %%u probes\\n\", n);\n"
" printk(\"ctracer: registered %%u entry probes\\n\", nj);\n"
" printk(\"ctracer: registered %%u exit probes\\n\", nr);\n"
"\n"
" return 0;\n"
"}\n\n");
@ -197,6 +253,7 @@ static void emit_module_exit(void)
" int i = 0;\n"
" while (jprobes[i] != (void *)0) {\n"
" unregister_jprobe(jprobes[i]);\n"
" unregister_kretprobe(kretprobes[i]);\n"
" ++i;\n"
" }\n\n"
"}\n\n");
@ -255,9 +312,13 @@ int main(int argc, char *argv[])
emit_module_preamble();
cus__for_each_cu(cus, cu_find_methods_iterator, class_name, NULL);
cus__for_each_cu(cus, cu_emit_kprobes_iterator, class_name, NULL);
cus__for_each_cu(cus, cu_emit_kretprobes_iterator, NULL, NULL);
puts("static struct jprobe *jprobes[] = {");
cus__for_each_cu(cus, cu_emit_kprobes_table_iterator, NULL, NULL);
puts("\t(void *)0,\n};\n");
puts("static struct kretprobe *kretprobes[] = {");
cus__for_each_cu(cus, cu_emit_kretprobes_table_iterator, NULL, NULL);
puts("\t(void *)0,\n};\n\n");
emit_module_init();
emit_module_exit();
emit_module_license("GPL");