summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenji Huang <wenji.huang@oracle.com>2009-10-14 10:26:03 +0800
committerWenji Huang <wenji.huang@oracle.com>2009-10-14 10:26:03 +0800
commit8c41e846e74026844d4b3e43778e53160f7dc27c (patch)
treeba2daa7a5fef99d3275b1f47047fc5935fda32d5
parent6928ee0a21a1832c9845c125b0998d45b801af81 (diff)
parent1c1f1a255cd969934bb7ce1678f4a411337be6f9 (diff)
downloadsystemtap-steved-8c41e846e74026844d4b3e43778e53160f7dc27c.tar.gz
systemtap-steved-8c41e846e74026844d4b3e43778e53160f7dc27c.tar.xz
systemtap-steved-8c41e846e74026844d4b3e43778e53160f7dc27c.zip
Merge branch 'master' of ssh://wenji@sources.redhat.com/git/systemtap
-rw-r--r--elaborate.cxx30
-rw-r--r--parse.cxx16
-rw-r--r--runtime/stat-common.c109
-rw-r--r--staptree.cxx66
-rw-r--r--staptree.h14
-rw-r--r--tapset-mark.cxx8
-rw-r--r--tapset-utrace.cxx8
-rw-r--r--tapset/syscalls2.stp8
-rw-r--r--tapsets.cxx17
-rwxr-xr-xtestsuite/buildok/print_histograms.stp4
-rw-r--r--translate.cxx22
11 files changed, 138 insertions, 164 deletions
diff --git a/elaborate.cxx b/elaborate.cxx
index 1d7f1e0b..2446e4f8 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1283,19 +1283,16 @@ void add_global_var_display (systemtap_session& s)
if (tapset_global)
continue;
- print_format* pf = new print_format;
- probe* p = new probe;
- probe_point* pl = new probe_point;
probe_point::component* c = new probe_point::component("end");
- token* print_tok = new token;
+ probe_point* pl = new probe_point;
+ pl->components.push_back (c);
+
vector<derived_probe*> dps;
block *b = new block;
- pl->components.push_back (c);
+ probe* p = new probe;
p->tok = l->tok;
p->locations.push_back (pl);
- print_tok->type = tok_identifier;
- print_tok->content = "printf";
// Create a symbol
symbol* g_sym = new symbol;
@@ -1304,13 +1301,12 @@ void add_global_var_display (systemtap_session& s)
g_sym->type = l->type;
g_sym->referent = l;
- pf->print_to_stream = true;
- pf->print_with_format = true;
- pf->print_with_delim = false;
- pf->print_with_newline = false;
- pf->print_char = false;
+ token* print_tok = new token;
+ print_tok->type = tok_identifier;
+ print_tok->content = "printf";
+
+ print_format* pf = print_format::create(print_tok);
pf->raw_components += l->name;
- pf->tok = print_tok;
if (l->index_types.size() == 0) // Scalar
{
@@ -1358,15 +1354,9 @@ void add_global_var_display (systemtap_session& s)
be->right = new literal_number(0);
/* Create printf @count=0x0 in else block */
- print_format* pf_0 = new print_format;
- pf_0->print_to_stream = true;
- pf_0->print_with_format = true;
- pf_0->print_with_delim = false;
- pf_0->print_with_newline = false;
- pf_0->print_char = false;
+ print_format* pf_0 = print_format::create(print_tok);
pf_0->raw_components += l->name;
pf_0->raw_components += " @count=0x0\\n";
- pf_0->tok = print_tok;
pf_0->components = print_format::string_to_components(pf_0->raw_components);
expr_statement* feb_else = new expr_statement;
feb_else->value = pf_0;
diff --git a/parse.cxx b/parse.cxx
index 5b3506f8..cfefa12d 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -2352,8 +2352,6 @@ parser::parse_symbol ()
// now scrutinize this identifier for the various magic forms of identifier
// (printf, @stat_op, and $var...)
- bool pf_stream, pf_format, pf_delim, pf_newline, pf_char;
-
if (name == "@cast")
{
// type-punning time
@@ -2410,19 +2408,11 @@ parser::parse_symbol ()
return sop;
}
- else if (print_format::parse_print(name,
- pf_stream, pf_format, pf_delim, pf_newline, pf_char))
+ else if (print_format *fmt = print_format::create(t))
{
- print_format *fmt = new print_format;
- fmt->tok = t;
- fmt->print_to_stream = pf_stream;
- fmt->print_with_format = pf_format;
- fmt->print_with_delim = pf_delim;
- fmt->print_with_newline = pf_newline;
- fmt->print_char = pf_char;
-
expect_op("(");
- if ((name == "print" || name == "println") &&
+ if ((name == "print" || name == "println" ||
+ name == "sprint" || name == "sprintln") &&
(peek_kw("@hist_linear") || peek_kw("@hist_log")))
{
// We have a special case where we recognize
diff --git a/runtime/stat-common.c b/runtime/stat-common.c
index 7dabe708..e6fd3a11 100644
--- a/runtime/stat-common.c
+++ b/runtime/stat-common.c
@@ -53,14 +53,6 @@ static int needed_space(int64_t v)
return space;
}
-static void reprint (int num, char *s)
-{
- while (num > 0) {
- _stp_print(s);
- num--;
- }
-}
-
/* Given a bucket number for a log histogram, return the value. */
static int64_t _stp_bucket_to_val(int num)
{
@@ -138,12 +130,17 @@ static int _stp_val_to_bucket(int64_t val)
#endif
-static void _stp_stat_print_histogram (Hist st, stat *sd)
+static void _stp_stat_print_histogram_buf(char *buf, size_t size, Hist st, stat *sd)
{
int scale, i, j, val_space, cnt_space;
int low_bucket = -1, high_bucket = 0, over = 0, under = 0;
- int64_t val, v, max = 0;
- int eliding = 0;
+ int64_t val, v, valmax = 0;
+ int eliding = 0;
+ char *cur_buf = buf, *fake = buf;
+ char **bufptr = (buf == NULL ? &fake : &cur_buf);
+
+#define HIST_PRINTF(fmt, args...) \
+ (*bufptr += _stp_snprintf(cur_buf, buf + size - cur_buf, fmt, ## args))
if (st->type != HIST_LOG && st->type != HIST_LINEAR)
return;
@@ -155,8 +152,8 @@ static void _stp_stat_print_histogram (Hist st, stat *sd)
low_bucket = i;
if (sd->histogram[i] > 0)
high_bucket = i;
- if (sd->histogram[i] > max)
- max = sd->histogram[i];
+ if (sd->histogram[i] > valmax)
+ valmax = sd->histogram[i];
}
/* Touch up the bucket margin to show up to two zero-slots on
@@ -185,53 +182,45 @@ static void _stp_stat_print_histogram (Hist st, stat *sd)
if (high_bucket == st->buckets-1)
over = 1;
}
-
- if (max <= HIST_WIDTH)
+
+ if (valmax <= HIST_WIDTH)
scale = 1;
else {
- int64_t tmp = max;
- int rem = do_div (tmp, HIST_WIDTH);
+ int64_t tmp = valmax;
+ int rem = do_div(tmp, HIST_WIDTH);
scale = tmp;
if (rem) scale++;
}
/* count space */
- cnt_space = needed_space (max);
+ cnt_space = needed_space(valmax);
/* Compute value space */
if (st->type == HIST_LINEAR) {
- i = needed_space (st->start) + under;
- val_space = needed_space (st->start + st->interval * high_bucket) + over;
+ val_space = max(needed_space(st->start) + under,
+ needed_space(st->start + st->interval * high_bucket) + over);
} else {
- i = needed_space(_stp_bucket_to_val(high_bucket));
- val_space = needed_space(_stp_bucket_to_val(low_bucket));
+ val_space = max(needed_space(_stp_bucket_to_val(high_bucket)),
+ needed_space(_stp_bucket_to_val(low_bucket)));
}
- if (i > val_space)
- val_space = i;
-
+ val_space = max(val_space, 5 /* = sizeof("value") */);
/* print header */
- j = 0;
- if (val_space > 5) /* 5 = sizeof("value") */
- j = val_space - 5;
- else
- val_space = 5;
- for ( i = 0; i < j; i++)
- _stp_print(" ");
- _stp_print("value |");
- reprint (HIST_WIDTH, "-");
- _stp_print(" count\n");
-
- eliding=0;
- for (i = low_bucket; i <= high_bucket; i++) {
- int over_under = 0;
+ HIST_PRINTF("%*s |", val_space, "value");
+ for (j = 0; j < HIST_WIDTH; ++j)
+ HIST_PRINTF("-");
+ HIST_PRINTF(" count\n");
+
+ eliding = 0;
+ for (i = low_bucket; i <= high_bucket; i++) {
+ const char *val_prefix = "";
/* Elide consecutive zero buckets. Specifically, skip
this row if it is zero and some of its nearest
neighbours are also zero. Don't elide zero buckets
if HIST_ELISION is negative */
if ((long)HIST_ELISION >= 0) {
- int k, elide=1;
+ int k, elide = 1;
/* Can't elide more than the total # of buckets */
int max_elide = min_t(long, HIST_ELISION, st->buckets);
int min_bucket = low_bucket;
@@ -254,8 +243,7 @@ static void _stp_stat_print_histogram (Hist st, stat *sd)
about to print a new one. So let's print a mark on
the vertical axis to represent the missing rows. */
if (eliding) {
- reprint (val_space, " ");
- _stp_print(" ~\n");
+ HIST_PRINTF("%*s ~\n", val_space, "");
eliding = 0;
}
}
@@ -264,38 +252,33 @@ static void _stp_stat_print_histogram (Hist st, stat *sd)
if (i == 0) {
/* underflow */
val = st->start;
- over_under = 1;
+ val_prefix = "<";
} else if (i == st->buckets-1) {
/* overflow */
val = st->start + (i - 2) * st->interval;
- over_under = 1;
- } else
+ val_prefix = ">";
+ } else
val = st->start + (i - 1) * st->interval;
} else
val = _stp_bucket_to_val(i);
- reprint (val_space - needed_space(val) - over_under, " ");
+ HIST_PRINTF("%*s%lld |", val_space - needed_space(val), val_prefix, val);
- if (over_under) {
- if (i == 0)
- _stp_printf("<%lld", val);
- else if (i == st->buckets-1)
- _stp_printf(">%lld", val);
- else
- _stp_printf("%lld", val);
- } else
- _stp_printf("%lld", val);
- _stp_print(" |");
-
/* v = s->histogram[i] / scale; */
v = sd->histogram[i];
- do_div (v, scale);
-
- reprint (v, "@");
- reprint (HIST_WIDTH - v + 1 + cnt_space - needed_space(sd->histogram[i]), " ");
- _stp_printf ("%lld\n", sd->histogram[i]);
+ do_div(v, scale);
+
+ for (j = 0; j < v; ++j)
+ HIST_PRINTF("@");
+ HIST_PRINTF("%*lld\n", HIST_WIDTH - v + 1 + cnt_space, sd->histogram[i]);
}
- _stp_print_char('\n');
+ HIST_PRINTF("\n");
+#undef HIST_PRINTF
+}
+
+static void _stp_stat_print_histogram(Hist st, stat *sd)
+{
+ _stp_stat_print_histogram_buf(NULL, 0, st, sd);
_stp_print_flush();
}
diff --git a/staptree.cxx b/staptree.cxx
index 090f0bd3..bc552454 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -405,52 +405,56 @@ void functioncall::print (ostream& o) const
}
-bool
-print_format::parse_print(const std::string &name,
- bool &stream, bool &format, bool &delim, bool &newline, bool &_char)
+print_format*
+print_format::create(const token *t)
{
- const char *n = name.c_str();
+ bool stream, format, delim, newline, _char;
+ const char *n = t->content.c_str();
stream = true;
format = delim = newline = _char = false;
if (strcmp(n, "print_char") == 0)
+ _char = true;
+ else
{
- _char = true;
- return true;
- }
-
- if (*n == 's')
- {
- stream = false;
- ++n;
- }
+ if (*n == 's')
+ {
+ stream = false;
+ ++n;
+ }
- if (0 != strncmp(n, "print", 5))
- return false;
- n += 5;
+ if (0 != strncmp(n, "print", 5))
+ return NULL;
+ n += 5;
- if (*n == 'f')
- {
- format = true;
- ++n;
- }
- else
- {
- if (*n == 'd')
- {
- delim = true;
+ if (*n == 'f')
+ {
+ format = true;
++n;
}
+ else
+ {
+ if (*n == 'd')
+ {
+ delim = true;
+ ++n;
+ }
- if (*n == 'l' && *(n+1) == 'n')
- {
- newline = true;
- n += 2;
+ if (*n == 'l' && *(n+1) == 'n')
+ {
+ newline = true;
+ n += 2;
+ }
}
+
+ if (*n != '\0')
+ return NULL;
}
- return (*n == '\0');
+ print_format *pf = new print_format(stream, format, delim, newline, _char);
+ pf->tok = t;
+ return pf;
}
diff --git a/staptree.h b/staptree.h
index de148ce0..791b56f4 100644
--- a/staptree.h
+++ b/staptree.h
@@ -373,10 +373,6 @@ struct print_format: public expression
}
};
- print_format()
- : hist(NULL)
- {}
-
std::string raw_components;
std::vector<format_component> components;
format_component delimiter;
@@ -385,11 +381,17 @@ struct print_format: public expression
static std::string components_to_string(std::vector<format_component> const & components);
static std::vector<format_component> string_to_components(std::string const & str);
- static bool parse_print(const std::string &name, bool &stream,
- bool &format, bool &delim, bool &newline, bool &_char);
+ static print_format* create(const token *t);
void print (std::ostream& o) const;
void visit (visitor* u);
+
+private:
+ print_format(bool stream, bool format, bool delim, bool newline, bool _char):
+ print_to_stream(stream), print_with_format(format),
+ print_with_delim(delim), print_with_newline(newline),
+ print_char(_char), hist(NULL)
+ {}
};
diff --git a/tapset-mark.cxx b/tapset-mark.cxx
index b70098e3..fc9cb274 100644
--- a/tapset-mark.cxx
+++ b/tapset-mark.cxx
@@ -142,15 +142,9 @@ mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
else if (e->base_name == "$$vars" || e->base_name == "$$parms")
{
//copy from tracepoint
- print_format* pf = new print_format;
token* pf_tok = new token(*e->tok);
pf_tok->content = "sprintf";
- pf->tok = pf_tok;
- pf->print_to_stream = false;
- pf->print_with_format = true;
- pf->print_with_delim = false;
- pf->print_with_newline = false;
- pf->print_char = false;
+ print_format* pf = print_format::create(pf_tok);
for (unsigned i = 0; i < mark_args.size(); ++i)
{
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index b731293c..abc9759f 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -448,15 +448,9 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
if (e->base_name == "$$parms")
{
// copy from tracepoint
- print_format* pf = new print_format;
token* pf_tok = new token(*e->tok);
pf_tok->content = "sprintf";
- pf->tok = pf_tok;
- pf->print_to_stream = false;
- pf->print_with_format = true;
- pf->print_with_delim = false;
- pf->print_with_newline = false;
- pf->print_char = false;
+ print_format* pf = print_format::create(pf_tok);
target_symbol_seen = true;
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index 5e97aef5..47aba9b4 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -61,14 +61,21 @@ probe syscall.compat_nanosleep.return = kernel.function("compat_sys_nanosleep").
# long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg,
# union compat_nfsctl_res __user *res)
#
+%( CONFIG_NFSD == "[ym]" || CONFIG_COMPAT == "y" %?
probe syscall.nfsservctl = kernel.function("sys_nfsservctl").call ?,
kernel.function("compat_sys_nfsservctl").call ?
{
name = "nfsservctl"
cmd = $cmd
+%( CONFIG_NFSD == "[ym]" %?
argp_uaddr = $arg
resp_uaddr = $res
argstr = sprintf("%s, %p, %p", _nfsctl_cmd_str($cmd), $arg, $res)
+%:
+ argp_uaddr = $notused
+ resp_uaddr = $notused2
+ argstr = sprintf("/* NI_SYSCALL */ %s, %p, %p", _nfsctl_cmd_str($cmd), $notused, $notused2)
+%)
}
probe syscall.nfsservctl.return = kernel.function("sys_nfsservctl").return ?,
kernel.function("compat_sys_nfsservctl").return ?
@@ -76,6 +83,7 @@ probe syscall.nfsservctl.return = kernel.function("sys_nfsservctl").return ?,
name = "nfsservctl"
retstr = returnstr(1)
}
+%)
# nice _______________________________________________________
# long sys_nice(int increment)
diff --git a/tapsets.cxx b/tapsets.cxx
index 5182bdd4..ba6f4ee4 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2135,7 +2135,6 @@ dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
return;
target_symbol *tsym = new target_symbol;
- print_format* pf = new print_format;
// Convert $$parms to sprintf of a list of parms and active local vars
// which we recursively evaluate
@@ -2148,12 +2147,7 @@ dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
pf_tok->type = tok_identifier;
pf_tok->content = "sprint";
- pf->tok = pf_tok;
- pf->print_to_stream = false;
- pf->print_with_format = true;
- pf->print_with_delim = false;
- pf->print_with_newline = false;
- pf->print_char = false;
+ print_format* pf = print_format::create(pf_tok);
if (q.has_return && (e->base_name == "$$return"))
{
@@ -5618,8 +5612,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
}
else if (e->base_name == "$$vars" || e->base_name == "$$parms")
{
- print_format* pf = new print_format;
-
// Convert $$vars to sprintf of a list of vars which we recursively evaluate
// NB: we synthesize a new token here rather than reusing
// e->tok, because print_format::print likes to use
@@ -5627,12 +5619,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
token* pf_tok = new token(*e->tok);
pf_tok->content = "sprintf";
- pf->tok = pf_tok;
- pf->print_to_stream = false;
- pf->print_with_format = true;
- pf->print_with_delim = false;
- pf->print_with_newline = false;
- pf->print_char = false;
+ print_format* pf = print_format::create(pf_tok);
for (unsigned i = 0; i < args.size(); ++i)
{
diff --git a/testsuite/buildok/print_histograms.stp b/testsuite/buildok/print_histograms.stp
index 945606a0..3e5dc88f 100755
--- a/testsuite/buildok/print_histograms.stp
+++ b/testsuite/buildok/print_histograms.stp
@@ -26,5 +26,9 @@ probe end
print(@hist_linear(bar, 1000, 10000, 1000))
println(@hist_log(foo))
println(@hist_linear(bar, 1000, 10000, 1000))
+ print(sprint(@hist_log(foo)))
+ print(sprint(@hist_linear(bar, 1000, 10000, 1000)))
+ print(sprintln(@hist_log(foo)))
+ print(sprintln(@hist_linear(bar, 1000, 10000, 1000)))
}
diff --git a/translate.cxx b/translate.cxx
index 1278a8d5..bc5d6158 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4083,6 +4083,14 @@ c_tmpcounter::visit_print_format (print_format* e)
arr->indexes[i]->visit(this);
}
}
+
+ // And the result for sprint[ln](@hist_*)
+ if (!e->print_to_stream)
+ {
+ exp_type ty = pe_string;
+ tmpvar res = parent->gensym(ty);
+ res.declare(*parent);
+ }
}
else
{
@@ -4145,8 +4153,18 @@ c_unparser::visit_print_format (print_format* e)
o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
o->newline() << "goto out;";
o->newline(-1) << "} else";
- o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");";
- o->indent(-1);
+ if (e->print_to_stream)
+ {
+ o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");";
+ o->indent(-1);
+ }
+ else
+ {
+ exp_type ty = pe_string;
+ tmpvar res = gensym (ty);
+ o->newline(1) << "_stp_stat_print_histogram_buf (" << res.value() << ", MAXSTRINGLEN, " << v->hist() << ", " << agg.value() << ");";
+ o->newline(-1) << res.value() << ";";
+ }
}
delete v;