summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2010-02-25 16:29:50 -0600
committerDavid Smith <dsmith@redhat.com>2010-02-25 16:29:50 -0600
commit38975255091d0c6bc33ae3c6907bb7886b70598d (patch)
treeb92dae620c94754b2828b7d92a51c29684a00085
parente3d5f49468872aeec7f1f05a8afe40677859cf0f (diff)
downloadsystemtap-steved-38975255091d0c6bc33ae3c6907bb7886b70598d.tar.gz
systemtap-steved-38975255091d0c6bc33ae3c6907bb7886b70598d.tar.xz
systemtap-steved-38975255091d0c6bc33ae3c6907bb7886b70598d.zip
Fixed pr 10690 by adding '.maxsize(NNN)' procfs read probe parameter.
* tapset-procfs.cxx (procfs_derived_probe::procfs_derived_probe): Added 'maxsize_val' initialization. (procfs_derived_probe::join_group): Updated '_stp_procfs_data' definition and added STP_PROCFS_BUFSIZE. (procfs_derived_probe_group::emit_module_decls): Emits structure to contain procfs file buffers. Initializes '.bufsize' structure member. (procfs_var_expanding_visitor::visit_target_symbol): Uses 'bufsize' for maximum buffer size instead of using MAXSTRINGLEN. (procfs_builder::build): Looks for '.maxsize(NNN)' parameter. (register_tapset_procfs): Added '.maxsize(NNN)' parameter binding. * runtime/procfs-probes.c (stap_procfs_probe): Converted 'buffer' to a pointer and added 'bufsize' member. * testsuite/semko/procfs13.stp: New testcase. * testsuite/semko/procfs14.stp: Ditto. * testsuite/semko/procfs15.stp: Ditto. * testsuite/systemtap.base/procfs_maxsize.exp: Ditto. * testsuite/systemtap.base/procfs.exp: Minor fix. * stapprobes.3stap.in: Added '.maxsize(NNN)' documentation. * stap.1.in: Added STP_PROCFS_BUFSIZE documentation.
-rw-r--r--runtime/procfs-probes.c9
-rw-r--r--stap.1.in9
-rw-r--r--stapprobes.3stap.in30
-rw-r--r--tapset-procfs.cxx117
-rwxr-xr-xtestsuite/semko/procfs13.stp4
-rwxr-xr-xtestsuite/semko/procfs14.stp4
-rwxr-xr-xtestsuite/semko/procfs15.stp4
-rw-r--r--testsuite/systemtap.base/procfs.exp2
-rw-r--r--testsuite/systemtap.base/procfs_maxsize.exp288
9 files changed, 439 insertions, 28 deletions
diff --git a/runtime/procfs-probes.c b/runtime/procfs-probes.c
index 73aa7e5f..8f9ff113 100644
--- a/runtime/procfs-probes.c
+++ b/runtime/procfs-probes.c
@@ -9,7 +9,8 @@
// translation process. It really should go here.
struct _stp_procfs_data {
char *buffer;
- unsigned long count;
+ size_t bufsize;
+ size_t count;
};
#endif
@@ -20,10 +21,8 @@ struct stap_procfs_probe {
const char *write_pp;
void (*write_ph) (struct context*);
- // FIXME: Eventually, this could get bigger than MAXSTRINGLEN
- // when we support 'probe procfs("file").read.maxbuf(8192)'
- // (bug 10690).
- string_t buffer;
+ char *buffer;
+ const size_t bufsize;
size_t count;
int needs_fill;
diff --git a/stap.1.in b/stap.1.in
index 1d9acadb..6ef39ba5 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -1132,7 +1132,14 @@ should use, default unlimited. The memory size includes the size of
the module itself, plus any additional allocations. This only tracks
direct allocations by the systemtap runtime. This does not track
indirect allocations (as done by kprobes/uprobes/etc. internals).
-
+.TP
+STP_PROCFS_BUFSIZE
+Size of procfs probe read buffers (in bytes). Defaults to
+.IR MAXSTRINGLEN .
+This value can be overridden on a per-procfs file basis using the
+procfs read probe
+.I .maxsize(MAXSIZE)
+parameter.
.PP
With scripts that contain probes on any interrupt path, it is possible that
those interrupts may occur in the middle of another probe handler. The probe
diff --git a/stapprobes.3stap.in b/stapprobes.3stap.in
index 23de56b0..dbd77ce4 100644
--- a/stapprobes.3stap.in
+++ b/stapprobes.3stap.in
@@ -549,13 +549,15 @@ These probe points allow procfs "files" in
is the name of the systemtap module). The
.I proc
filesystem is a pseudo-filesystem which is used an an interface to
-kernel data structures. There are four probe point variants supported
+kernel data structures. There are several probe point variants supported
by the translator:
.SAMPLE
procfs("PATH").read
+procfs("PATH").read.maxsize(MAXSIZE)
procfs("PATH").write
procfs.read
+procfs.read.maxsize(MAXSIZE)
procfs.write
.ESAMPLE
@@ -590,6 +592,32 @@ like this:
.SAMPLE
procfs("PATH").write { printf("user wrote: %s", $value) }
.ESAMPLE
+.PP
+.I MAXSIZE
+is the size of the procfs read buffer. Specifying
+.I MAXSIZE
+allows larger procfs output. If no
+.I MAXSIZE
+is specified, the procfs read buffer defaults to
+.I STP_PROCFS_BUFSIZE
+(which defaults to
+.IR MAXSTRINGLEN ,
+the maximum length of a string).
+If setting the procfs read buffers for more than one file is needed,
+it may be easiest to override the
+.I STP_PROCFS_BUFSIZE
+definition.
+Here's an example of using
+.IR MAXSIZE :
+
+.SAMPLE
+procfs.read.maxsize(1024) {
+ $value = "long string..."
+ $value .= "another long string..."
+ $value .= "another long string..."
+ $value .= "another long string..."
+}
+.ESAMPLE
.SS MARKERS
diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx
index 517a4a22..1ac67e53 100644
--- a/tapset-procfs.cxx
+++ b/tapset-procfs.cxx
@@ -25,6 +25,7 @@ using namespace __gnu_cxx;
static const string TOK_PROCFS("procfs");
static const string TOK_READ("read");
static const string TOK_WRITE("write");
+static const string TOK_MAXSIZE("maxsize");
// ------------------------------------------------------------------------
@@ -37,8 +38,9 @@ struct procfs_derived_probe: public derived_probe
string path;
bool write;
bool target_symbol_seen;
+ int64_t maxsize_val;
- procfs_derived_probe (systemtap_session &, probe* p, probe_point* l, string ps, bool w);
+ procfs_derived_probe (systemtap_session &, probe* p, probe_point* l, string ps, bool w, int64_t m);
void join_group (systemtap_session& s);
};
@@ -87,8 +89,10 @@ struct procfs_var_expanding_visitor: public var_expanding_visitor
procfs_derived_probe::procfs_derived_probe (systemtap_session &s, probe* p,
- probe_point* l, string ps, bool w):
- derived_probe(p, l), path(ps), write(w), target_symbol_seen(false)
+ probe_point* l, string ps, bool w,
+ int64_t m):
+ derived_probe(p, l), path(ps), write(w), target_symbol_seen(false),
+ maxsize_val(m)
{
// Expand local variables in the probe body
procfs_var_expanding_visitor v (s, name, path, write);
@@ -109,8 +113,12 @@ procfs_derived_probe::join_group (systemtap_session& s)
ec->tok = NULL;
ec->code = string("struct _stp_procfs_data {\n")
+ string(" char *buffer;\n")
- + string(" unsigned long count;\n")
- + string("};\n");
+ + string(" size_t bufsize;\n")
+ + string(" size_t count;\n")
+ + string("};\n")
+ + string("#ifndef STP_PROCFS_BUFSIZE\n")
+ + string("#define STP_PROCFS_BUFSIZE MAXSTRINGLEN\n")
+ + string("#endif\n");
s.embeds.push_back(ec);
}
s.procfs_derived_probes->enroll (this);
@@ -141,15 +149,15 @@ procfs_derived_probe_group::enroll (procfs_derived_probe* p)
}
if (p->write)
- {
- pset->write_probe = p;
- has_write_probes = true;
- }
+ {
+ pset->write_probe = p;
+ has_write_probes = true;
+ }
else
- {
- pset->read_probe = p;
- has_read_probes = true;
- }
+ {
+ pset->read_probe = p;
+ has_read_probes = true;
+ }
}
@@ -163,13 +171,43 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "#include \"procfs.c\"";
s.op->newline() << "#include \"procfs-probes.c\"";
+ // Emit the procfs probe buffer structure
+ s.op->newline() << "static struct stap_procfs_probe_buffer {";
+ s.op->indent(1);
+ for (p_b_p_iterator it = probes_by_path.begin(); it != probes_by_path.end();
+ it++)
+ {
+ procfs_probe_set *pset = it->second;
+
+ if (pset->read_probe != NULL)
+ {
+ if (pset->read_probe->maxsize_val == 0)
+ {
+ s.op->newline() << "char " << pset->read_probe->name
+ << "[STP_PROCFS_BUFSIZE];";
+ }
+ else
+ {
+ s.op->newline() << "char " << pset->read_probe->name
+ << "[" << pset->read_probe->maxsize_val
+ << "];";
+ }
+ }
+ else
+ {
+ s.op->newline() << "char " << pset->write_probe->name
+ << "[MAXSTRINGLEN];";
+ }
+ }
+ s.op->newline(-1) << "} stap_procfs_probe_buffers;";
+
// Emit the procfs probe data list
s.op->newline() << "static struct stap_procfs_probe stap_procfs_probes[] = {";
s.op->indent(1);
for (p_b_p_iterator it = probes_by_path.begin(); it != probes_by_path.end();
it++)
- {
+ {
procfs_probe_set *pset = it->second;
s.op->newline() << "{";
@@ -193,15 +231,33 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->line() << " .write_pp="
<< lex_cast_qstring (*pset->write_probe->sole_location())
<< ",";
- s.op->line() << " .write_ph=&" << pset->write_probe->name;
+ s.op->line() << " .write_ph=&" << pset->write_probe->name << ",";
}
else
{
s.op->line() << " .write_pp=NULL,";
- s.op->line() << " .write_ph=NULL";
+ s.op->line() << " .write_ph=NULL,";
}
+
+ if (pset->read_probe != NULL)
+ {
+ s.op->line() << " .buffer=stap_procfs_probe_buffers."
+ << pset->read_probe->name << ",";
+ if (pset->read_probe->maxsize_val == 0)
+ s.op->line() << " .bufsize=STP_PROCFS_BUFSIZE,";
+ else
+ s.op->line() << " .bufsize="
+ << pset->read_probe->maxsize_val << ",";
+ }
+ else
+ {
+ s.op->line() << " .buffer=stap_procfs_probe_buffers."
+ << pset->write_probe->name << ",";
+ s.op->line() << " .bufsize=MAXSTRINGLEN,";
+ }
+
s.op->line() << " },";
- }
+ }
s.op->newline(-1) << "};";
// Output routine to fill in the buffer with our data. Note that we
@@ -218,6 +274,7 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "spp->read_pp");
s.op->newline() << "pdata.buffer = spp->buffer;";
+ s.op->newline() << "pdata.bufsize = spp->bufsize;";
s.op->newline() << "if (c->data == NULL)";
s.op->newline(1) << "c->data = &pdata;";
s.op->newline(-1) << "else {";
@@ -260,9 +317,17 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "spp->write_pp");
+ // We've got 2 problems here. The data count could be greater
+ // than MAXSTRINGLEN or greater than the bufsize (if the same
+ // procfs file had a size less than MAXSTRINGLEN).
s.op->newline() << "if (count >= MAXSTRINGLEN)";
s.op->newline(1) << "count = MAXSTRINGLEN - 1;";
s.op->indent(-1);
+ s.op->newline() << "pdata.bufsize = spp->bufsize;";
+ s.op->newline() << "if (count >= pdata.bufsize)";
+ s.op->newline(1) << "count = pdata.bufsize - 1;";
+ s.op->indent(-1);
+
s.op->newline() << "pdata.buffer = (char *)buf;";
s.op->newline() << "pdata.count = count;";
@@ -400,14 +465,14 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e)
{
fname = "_procfs_value_set";
ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n")
- + string(" strlcpy(data->buffer, THIS->value, MAXSTRINGLEN);\n")
+ + string(" strlcpy(data->buffer, THIS->value, data->bufsize);\n")
+ string(" data->count = strlen(data->buffer);\n");
}
else if (*op == ".=")
{
fname = "_procfs_value_append";
ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n")
- + string(" strlcat(data->buffer, THIS->value, MAXSTRINGLEN);\n")
+ + string(" strlcat(data->buffer, THIS->value, data->bufsize);\n")
+ string(" data->count = strlen(data->buffer);\n");
}
else
@@ -482,6 +547,14 @@ procfs_builder::build(systemtap_session & sess,
bool has_procfs = get_param(parameters, TOK_PROCFS, path);
bool has_read = (parameters.find(TOK_READ) != parameters.end());
bool has_write = (parameters.find(TOK_WRITE) != parameters.end());
+ int64_t maxsize_val = 0;
+
+ // Validate '.maxsize(NNN)', if it exists.
+ if (get_param(parameters, TOK_MAXSIZE, maxsize_val))
+ {
+ if (maxsize_val <= 0)
+ throw semantic_error ("maxsize must be greater than 0");
+ }
// If no procfs path, default to "command". The runtime will do
// this for us, but if we don't do it here, we'll think the
@@ -529,7 +602,8 @@ procfs_builder::build(systemtap_session & sess,
throw semantic_error ("need read/write component", location->components.front()->tok);
finished_results.push_back(new procfs_derived_probe(sess, base, location,
- path, has_write));
+ path, has_write,
+ maxsize_val));
}
@@ -540,7 +614,10 @@ register_tapset_procfs(systemtap_session& s)
derived_probe_builder *builder = new procfs_builder();
root->bind(TOK_PROCFS)->bind(TOK_READ)->bind(builder);
+ root->bind(TOK_PROCFS)->bind(TOK_READ)->bind_num(TOK_MAXSIZE)->bind(builder);
root->bind_str(TOK_PROCFS)->bind(TOK_READ)->bind(builder);
+ root->bind_str(TOK_PROCFS)->bind(TOK_READ)->bind_num(TOK_MAXSIZE)->bind(builder);
+
root->bind(TOK_PROCFS)->bind(TOK_WRITE)->bind(builder);
root->bind_str(TOK_PROCFS)->bind(TOK_WRITE)->bind(builder);
}
diff --git a/testsuite/semko/procfs13.stp b/testsuite/semko/procfs13.stp
new file mode 100755
index 00000000..8b5b64f1
--- /dev/null
+++ b/testsuite/semko/procfs13.stp
@@ -0,0 +1,4 @@
+#! stap -p2
+
+# no maxsize value
+probe procfs.read.maxsize { $value = "foo" }
diff --git a/testsuite/semko/procfs14.stp b/testsuite/semko/procfs14.stp
new file mode 100755
index 00000000..7dd75284
--- /dev/null
+++ b/testsuite/semko/procfs14.stp
@@ -0,0 +1,4 @@
+#! stap -p2
+
+# use -1 as a maxsize value
+probe procfs.read.maxsize(-1) { $value = "foo" }
diff --git a/testsuite/semko/procfs15.stp b/testsuite/semko/procfs15.stp
new file mode 100755
index 00000000..06594c50
--- /dev/null
+++ b/testsuite/semko/procfs15.stp
@@ -0,0 +1,4 @@
+#! stap -p2
+
+# use -1 as a maxsize value
+probe procfs("foo").read.maxsize(-1) { $value = "foo" }
diff --git a/testsuite/systemtap.base/procfs.exp b/testsuite/systemtap.base/procfs.exp
index 182f1e2e..327ce9ed 100644
--- a/testsuite/systemtap.base/procfs.exp
+++ b/testsuite/systemtap.base/procfs.exp
@@ -27,7 +27,7 @@ proc proc_write_value { test path value} {
}
proc proc_read_write {} {
- set test "PROCFS"
+ global test
set path "/proc/systemtap/$test/command"
# read the initial value, which should be '100'
diff --git a/testsuite/systemtap.base/procfs_maxsize.exp b/testsuite/systemtap.base/procfs_maxsize.exp
new file mode 100644
index 00000000..a4493f8f
--- /dev/null
+++ b/testsuite/systemtap.base/procfs_maxsize.exp
@@ -0,0 +1,288 @@
+# Handle varying sizes of procfs buffers.
+
+set test "PROCFS_BUFFER"
+if {![installtest_p]} { untested $test; return }
+
+proc proc_read_value { test path} {
+ set value "<unknown>"
+ if [catch {open $path RDONLY} channel] {
+ fail "$test $channel"
+ } else {
+ set value [read -nonewline $channel]
+ close $channel
+ pass "$test read $value"
+ }
+ return $value
+}
+
+proc proc_write_value { test path value } {
+ if [catch {open $path WRONLY} channel] {
+ fail "$test $channel"
+ } else {
+ puts -nonewline $channel $value
+ close $channel
+ pass "$test wrote $value"
+ }
+}
+
+proc proc_read_write_counted { test maxsize } {
+ set path "/proc/systemtap/$test/command"
+ set fullstring "abcdefghijklmnoABCDEFGHIJKLMNOpqrstuvwxyz123456789"
+
+ # Read the file
+ set value [proc_read_value $test $path]
+
+ set value2 [string range $fullstring 0 [expr $maxsize - 2]]
+ if { $value == $value2 } {
+ pass "$test received correct initial value"
+ } else {
+ fail "$test received incorrect initial value: $value ($value2)"
+ }
+
+ # Write a new value.
+ proc_write_value $test $path $fullstring
+
+ return 0;
+}
+
+# Expect 32 byte return from reading procfs file.
+proc proc_read_write_32 {} {
+ global test
+ proc_read_write_counted $test 32
+}
+
+# Expect 16 byte return from reading procfs file.
+proc proc_read_write_16 {} {
+ global test
+ proc_read_write_counted $test 16
+}
+
+set script1 {
+ global values[10]
+ global idx = 0
+
+ probe procfs.read {
+ $value = "abcdefghijklmno"
+ $value .= "ABCDEFGHIJKLMNO"
+ $value .= "pqrstuvwxyz1234"
+ }
+ probe procfs.write {
+ values[idx] = $value
+ idx++
+ }
+
+ probe begin {
+ printf("systemtap starting probe\n")
+ }
+ probe end {
+ printf("systemtap ending probe\n")
+ for (i = 0; i < idx; i++) {
+ printf("value%d=%s\n", i, values[i])
+ }
+ }
+}
+
+# Output strings in 16 and 32 byte chunks.
+set output_string_16 "value0=abcdefghijklmno\r\nvalue1=ABCDEFGHIJKLMNO\r\nvalue2=pqrstuvwxyz1234\r\nvalue3=56789\r\n"
+set output_string_32 "value0=abcdefghijklmnoABCDEFGHIJKLMNOp\r\nvalue1=qrstuvwxyz123456789\r\n"
+
+# By default, setting MAXSTRINGLEN should set the size of
+# procfs read and write buffers.
+set test "PROCFS_BUFFER1"
+stap_run $test proc_read_write_32 $output_string_32 -DMAXSTRINGLEN=32 -e $script1 -m $test
+exec /bin/rm -f ${test}.ko
+
+# Try with MAXSTRINGLEN=32 and STP_PROCFS_BUFSIZE=16
+set test "PROCFS_BUFFER2"
+stap_run $test proc_read_write_16 $output_string_16 -DMAXSTRINGLEN=32 -DSTP_PROCFS_BUFSIZE=16 -e $script1 -m $test
+exec /bin/rm -f ${test}.ko
+
+# Try with MAXSTRINGLEN=16 and STP_PROCFS_BUFSIZE=32. Note that in
+# this case, even though the procfs buffer is 32 bytes in size, since
+# strings can only hold 16 bytes, the expected output is the same as
+# in the previous test.
+set test "PROCFS_BUFFER3"
+stap_run $test proc_read_write_32 $output_string_16 -DMAXSTRINGLEN=16 -DSTP_PROCFS_BUFSIZE=32 -e $script1 -m $test
+exec /bin/rm -f ${test}.ko
+
+# script2 has a '.maxsize(32). override
+set script2 {
+ global values[10]
+ global idx = 0
+
+ probe procfs.read.maxsize(32) {
+ $value = "abcdefghijklmno"
+ $value .= "ABCDEFGHIJKLMNO"
+ $value .= "pqrstuvwxyz1234"
+ }
+ probe procfs.write {
+ values[idx] = $value
+ idx++
+ }
+
+ probe begin {
+ printf("systemtap starting probe\n")
+ }
+ probe end {
+ printf("systemtap ending probe\n")
+ for (i = 0; i < idx; i++) {
+ printf("value%d=%s\n", i, values[i])
+ }
+ }
+}
+
+# By default, setting MAXSTRINGLEN should set the size of
+# procfs read and write buffers. But script2 has a '.maxsize(32)'
+# override.
+set test "PROCFS_BUFFER4"
+stap_run $test proc_read_write_32 $output_string_16 -DMAXSTRINGLEN=16 -e $script2 -m $test
+exec /bin/rm -f ${test}.ko
+
+# The script2 '.maxsize(32)' override should override even setting
+# STP_PROCFS_BUFSIZE.
+set test "PROCFS_BUFFER5"
+stap_run $test proc_read_write_32 $output_string_16 -DMAXSTRINGLEN=16 -DSTP_PROCFS_BUFSIZE=64 -e $script2 -m $test
+exec /bin/rm -f ${test}.ko
+
+# script3 has a maxsize override and a default size file
+set script3 {
+ global values[10]
+ global idx = 0
+
+ probe procfs("default").read {
+ $value = "abcdefghijklmno"
+ $value .= "ABCDEFGHIJKLMNO"
+ $value .= "pqrstuvwxyz1234"
+ }
+ probe procfs.read.maxsize(32) {
+ $value = "abcdefghijklmno"
+ $value .= "ABCDEFGHIJKLMNO"
+ $value .= "pqrstuvwxyz1234"
+ }
+ probe procfs.write {
+ values[idx] = $value
+ idx++
+ }
+
+ probe begin {
+ printf("systemtap starting probe\n")
+ }
+ probe end {
+ printf("systemtap ending probe\n")
+ for (i = 0; i < idx; i++) {
+ printf("value%d=%s\n", i, values[i])
+ }
+ }
+}
+
+proc proc_read_write_default_32 {} {
+ global test
+
+ set path "/proc/systemtap/$test/default"
+ set value2 "abcdefghijklmno"
+
+ # Read the file
+ set value [proc_read_value $test $path]
+ if { $value == $value2 } {
+ pass "$test received correct initial value"
+ } else {
+ fail "$test received incorrect initial value: $value ($value2)"
+ }
+
+ proc_read_write_counted $test 32
+}
+
+set test "PROCFS_BUFFER6"
+stap_run $test proc_read_write_default_32 $output_string_16 -DMAXSTRINGLEN=16 -e $script3 -m $test
+exec /bin/rm -f ${test}.ko
+
+set script4 {
+ global large_strings[10]
+
+ # Put more data than we can really handle into $value
+ probe procfs.read.maxsize(2048) {
+ $value = large_strings[0]
+ for (i = 1; i < 10; i+=1) {
+ $value .= large_strings[i]
+ }
+ }
+
+ probe begin {
+ # build up several maximum length strings
+ max = 512
+ for (i = 0; i < max/64; i+=1) {
+ for (j = 0; j < 10; j++) {
+ if (i < (max/64 - 1)) {
+ large_strings[j] .= sprintf("%3d:12345678901234567890123456789012345678901234567890123456789\n",
+ i + (j * (max/64)))
+ }
+ else {
+ large_strings[j] .= sprintf("%3d:1234567890123456789012345678901234567890123456789012345678\n",
+ i + (j * (max/64)))
+ }
+ }
+ }
+ printf("systemtap starting probe\n")
+ }
+ probe end {
+ printf("systemtap ending probe\n")
+ }
+}
+
+proc proc_read_big {} {
+ global test
+ global test_string
+
+ set path "/proc/systemtap/$test/command"
+
+ # Read the file
+ set value [proc_read_value $test $path]
+
+ # set value2 [string range $fullstring 0 [expr $maxsize - 2]]
+ if { $value == $test_string } {
+ pass "$test received correct initial value"
+ } else {
+ fail "$test received incorrect initial value: $value ($test_string)"
+ }
+ return 0;
+}
+
+set test_string \
+" 0:12345678901234567890123456789012345678901234567890123456789
+ 1:12345678901234567890123456789012345678901234567890123456789
+ 2:12345678901234567890123456789012345678901234567890123456789
+ 3:12345678901234567890123456789012345678901234567890123456789
+ 4:12345678901234567890123456789012345678901234567890123456789
+ 5:12345678901234567890123456789012345678901234567890123456789
+ 6:12345678901234567890123456789012345678901234567890123456789
+ 7:1234567890123456789012345678901234567890123456789012345678
+ 8:12345678901234567890123456789012345678901234567890123456789
+ 9:12345678901234567890123456789012345678901234567890123456789
+ 10:12345678901234567890123456789012345678901234567890123456789
+ 11:12345678901234567890123456789012345678901234567890123456789
+ 12:12345678901234567890123456789012345678901234567890123456789
+ 13:12345678901234567890123456789012345678901234567890123456789
+ 14:12345678901234567890123456789012345678901234567890123456789
+ 15:1234567890123456789012345678901234567890123456789012345678
+ 16:12345678901234567890123456789012345678901234567890123456789
+ 17:12345678901234567890123456789012345678901234567890123456789
+ 18:12345678901234567890123456789012345678901234567890123456789
+ 19:12345678901234567890123456789012345678901234567890123456789
+ 20:12345678901234567890123456789012345678901234567890123456789
+ 21:12345678901234567890123456789012345678901234567890123456789
+ 22:12345678901234567890123456789012345678901234567890123456789
+ 23:1234567890123456789012345678901234567890123456789012345678
+ 24:12345678901234567890123456789012345678901234567890123456789
+ 25:12345678901234567890123456789012345678901234567890123456789
+ 26:12345678901234567890123456789012345678901234567890123456789
+ 27:12345678901234567890123456789012345678901234567890123456789
+ 28:12345678901234567890123456789012345678901234567890123456789
+ 29:12345678901234567890123456789012345678901234567890123456789
+ 30:12345678901234567890123456789012345678901234567890123456789
+ 31:1234567890123456789012345678901234567890123456789012345678
+ 32"
+
+# Test outputting 2K worth of data in one shot.
+set test "PROCFS_BUFFER7"
+stap_run $test proc_read_big "" -DMAXSTRINGLEN=512 -e $script4 -m $test
+exec /bin/rm -f ${test}.ko