This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Customization of LKET
- From: Li Guanglei <guanglei at cn dot ibm dot com>
- To: "systemtap at sourceware dot org" <systemtap at sourceware dot org>
- Cc: Jose Santos <jrs at us dot ibm dot com>
- Date: Tue, 30 May 2006 22:39:09 +0800
- Subject: Customization of LKET
- Organization: IBM CSTL
Hi folks,
I had a talk with Jose last week and we think it would be useful to
make the user able to append extra data on the trace at script level.
Of course the user could modify the tapsets in tapset/LKET to let
_lket_trace() log more data. But it's not a convenient way. It's
obvious that a function like printf() at script level is better, i.e:
probe addevent.pagefault
{
lket_trace_extra("%4b", $numa_node)
}
lket_trace_extra is defined as:
#define _lket_trace_extra(fmt, args...) do {\
_stp_printf("%1b%2n%0s"fmt, LKET_PKT_USER, fmt, args);\
} while(0)
I modified systemtap to make it able to support lket_trace_extra at
script level. In fact, lket_trace_extra has the same signature as
printf, the difference is that printf will be turned into
_stp_printf() in pass 3 while lket_trace_extra will be turned into
_lket_trace_extra(). Attached is a draft patch against 0527 snapshot
for this.
But there is a trouble here. Now we use epilogue mode alias to
support backtrace. For these aliases, it will always put
_lket_trace_extra() before the original lket_trace, e.g:
probe addevent.scsi.ioentry
{
lket_trace_extra(...)
}
will be expanded as:
probe module("scsi_mod").function("scsi_prep_fn")
{
...
lket_trace_extra(...)
log_scsi_ioentry(HOOKID_SCSI_IOENTRY, _dwarf_tvar_get_q_3(), ...
}
You can see that lket_trace_extra() is put before log_scsi_ioentry().
So I think we should reconsider the current way of logging backtrace
I suggest we should not use epilogue mode alias for backtrace logging.
So there seem to me two alternatives. The first one is to log
backtrace in lket_trace_extra, i.e:
probe addevent.pagefault
{
lket_trace_extra("%4b%0s", $numa_node, backtrace())
}
But there is trouble that MAXSTRINGLEN is defined as 128 so backtrace
string will be truncated. Simply raising MAXSTRINGLEN will cause a lot
of waste of memory.
So I think we could use the second way. We defined a new function that
dedicated for backtrace:
function lket_backtrace () %{
if (CONTEXT->regs) {
String str = _stp_string_init (0);
_stp_stack_sprint (str, CONTEXT->regs, 0);
_stp_printf("%1b%2n%0s", LKET_PKT_BT, _stp_string_ptr(str));
}
%}
Then the user could:
probe addevent.pagefault
{
lket_backtrace()
lket_trace_extra("%4b%0s", $numa_node, backtrace())
}
Then he can add as more extra data by lket_trace_extra() as he like
and the post-processing app(lket-b2a) could recognize the format of
these extra data.
Do you have any comments about this?
Thanks.
--- src/parse.cxx 2006-05-25 17:39:37.000000000 -0400
+++ src.mod/parse.cxx 2006-05-30 07:12:50.000000000 -0400
@@ -2082,12 +2082,22 @@ parser::parse_symbol ()
else if (name.size() > 0 && (name == "print"
|| name == "sprint"
|| name == "printf"
- || name == "sprintf"))
+ || name == "sprintf"
+ || name == "lket_trace_extra"))
+
{
print_format *fmt = new print_format;
fmt->tok = t;
fmt->print_with_format = (name[name.size() - 1] == 'f');
fmt->print_to_stream = (name[0] == 'p');
+
+ if(name == "lket_trace_extra")
+ {
+ fmt->print_with_format = 1;
+ fmt->print_to_stream = 1;
+ fmt->lket_trace_extra = 1;
+ }
+
expect_op("(");
if (fmt->print_with_format)
{
--- src/staptree.h 2006-05-18 19:11:22.000000000 -0400
+++ src.mod/staptree.h 2006-05-30 07:13:20.000000000 -0400
@@ -261,6 +261,7 @@ struct print_format: public expression
{
bool print_with_format;
bool print_to_stream;
+ bool lket_trace_extra;
enum format_flag
{
--- src/translate.cxx 2006-05-24 22:03:01.000000000 -0400
+++ src.mod/translate.cxx 2006-05-30 07:14:25.000000000 -0400
@@ -3591,7 +3591,10 @@ c_unparser::visit_print_format (print_fo
if (e->print_to_stream)
{
o->newline() << res.qname() << " = 0;";
- o->newline() << "_stp_printf (";
+ if( e->lket_trace_extra)
+ o->newline() << "_lket_trace_extra (";
+ else
+ o->newline() << "_stp_printf (";
}
else
o->newline() << "_stp_snprintf (" << res.qname() << ", MAXSTRINGLEN, ";