]> sourceware.org Git - systemtap.git/commitdiff
* kernel_{string,long,...,char} protected accessor functions
authorfche <fche>
Tue, 6 Feb 2007 20:23:25 +0000 (20:23 +0000)
committerfche <fche>
Tue, 6 Feb 2007 20:23:25 +0000 (20:23 +0000)
* test suites for all of 'em too
* even documentation
* mm, donuts

2007-02-06  Frank Ch. Eigler  <fche@elastic.org>

* stapfuncs.5.in: Add docs for kernel_{long,int,short,char} and
some user_string* variants.

2007-02-06  Frank Ch. Eigler  <fche@elastic.org>

* conversions.stp (kernel_long/int/short/char): New functions.

2007-02-06  Frank Ch. Eigler  <fche@elastic.org>

* buildok/conversions.stp: Build-test all conversions.stp functions.
* systemtap.stress/conversions.*: New test.

ChangeLog
stapfuncs.5.in
tapset/ChangeLog
tapset/conversions.stp
testsuite/ChangeLog
testsuite/buildok/conversions.stp [new file with mode: 0755]
testsuite/systemtap.stress/conversions.exp [new file with mode: 0644]
testsuite/systemtap.stress/conversions.stp [new file with mode: 0644]

index 9227fa983c9040f8d556136d5ebc8e0149b0946c..b62a818122c8c3a955250380450d5bf876c53ca6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-02-06  Frank Ch. Eigler  <fche@elastic.org>
+
+       * stapfuncs.5.in: Add docs for kernel_{long,int,short,char} and
+       some user_string* variants.
+
 2007-01-31  Martin Hunt  <hunt@redhat.com>
 
        * translate.cxx (translate_pass): Remove old string impedance 
index a76ff240600326490b566aaf6133b45a8f6f29d2..af4cbd15dc8dab2b107e307eed13593d00ca0110 100644 (file)
@@ -65,15 +65,37 @@ unwind the current probe handler, nor block new probe handlers.
 will shortly respond to the request and initiate an orderly shutdown.
 
 .SS CONVERSIONS
+.PP
+These functions access kernel or user-space data.  They try to validate the
+supplied addresses, and can thus result in errors if the pointers are invalid,
+or if a user-space access would cause a fault.
 .TP
 kernel_string:string (addr:long)
-Copy a string from kernel space at given address.  The validation of this
-address is only partial at present.
+Copy a 0-terminated string from kernel space at given address.
+.TP
+kernel_long:long (addr:long)
+Copy a long from kernel space at given address.
+.TP
+kernel_int:long (addr:long)
+Copy an int from kernel space at given address.
+.TP
+kernel_short:long (addr:long)
+Copy a short from kernel space at given address.
+.TP
+kernel_char:long (addr:long)
+Copy a char from kernel space at given address.
 .TP
 user_string:string (addr:long)
-Copy a string from user space at given address.  The validation of this
-address is only partial at present.
-
+Copy a string from user space at given address.  If the access would
+fault, return "<unknown>" and signal no errors.
+.TP
+user_string2:string (addr:long, err_msg:string)
+Copy a string from user space at given address.  If the access would
+fault, return instead the err_msg value.
+.TP
+user_string_warn:string (addr:long)
+Copy a string from user space at given address.  If the access would
+fault, signal a warning and return "<unknown>".
 .SS STRING
 .TP
 strlen:long (str:string)
index 7131e47261bf55db8650e50a261134c8754bbcb3..8e1766cd189154c9a78c4f431955038810190938 100644 (file)
@@ -1,3 +1,7 @@
+2007-02-06  Frank Ch. Eigler  <fche@elastic.org>
+
+       * conversions.stp (kernel_long/int/short/char): New functions.
+
 2007-01-31  Martin Hunt  <hunt@redhat.com>
 
        * context.stp (print_backtrace): Modify for new
index c311d25ac7684ca39ad7ff85fa4c332e9f8da001..fe5adc104f95ae6cc0653b1f2649f379788dd121 100644 (file)
@@ -1,5 +1,5 @@
 // conversions tapset
-// Copyright (C) 2005, 2006 Red Hat Inc.
+// Copyright (C) 2005-2007 Red Hat Inc.
 //
 // This file is part of systemtap, and is free software.  You can
 // redistribute it and/or modify it under the terms of the GNU General
@@ -12,7 +12,8 @@ function kernel_string:string (addr:long) %{ /* pure */
   goto success;
 deref_fault: /* branched to from deref() */
   {
-    static char errmsg[40];
+    /* XXX: concurrent errors could result in corrupted message string */
+    static char errmsg[50];
     snprintf (errmsg, 40, "kernel string copy fault at 0x%p",
         (void *) (uintptr_t) THIS->addr);
     CONTEXT->last_error = errmsg;
@@ -20,6 +21,59 @@ deref_fault: /* branched to from deref() */
 success: ;
 %}
 
+function kernel_long:long (addr:long) %{ /* pure */
+  THIS->__retvalue = (int64_t) deref (sizeof (long), (long *) (intptr_t) THIS->addr);
+  goto success;
+deref_fault: /* branched to from deref() */
+  {
+    static char errmsg[50];
+    snprintf (errmsg, 40, "kernel long copy fault at 0x%p",
+        (void *) (uintptr_t) THIS->addr);
+    CONTEXT->last_error = errmsg;
+  }
+success: ;
+%}
+
+function kernel_int:long (addr:long) %{ /* pure */
+  THIS->__retvalue = (int64_t) deref (sizeof (int), (int *) (intptr_t) THIS->addr);
+deref_fault: /* branched to from deref() */
+  {
+    static char errmsg[50];
+    snprintf (errmsg, 40, "kernel int copy fault at 0x%p",
+        (void *) (uintptr_t) THIS->addr);
+    CONTEXT->last_error = errmsg;
+  }
+success: ;
+%}
+
+function kernel_short:long (addr:long) %{ /* pure */
+  THIS->__retvalue = (int64_t) deref (sizeof (short), (short *) (intptr_t) THIS->addr);
+  goto success;
+deref_fault: /* branched to from deref() */
+  {
+    static char errmsg[50];
+    snprintf (errmsg, 40, "kernel short copy fault at 0x%p",
+        (void *) (uintptr_t) THIS->addr);
+    CONTEXT->last_error = errmsg;
+  }
+success: ;
+%}
+
+function kernel_char:long (addr:long) %{ /* pure */
+  THIS->__retvalue = (int64_t) deref (sizeof (char), (char *) (intptr_t) THIS->addr);
+  goto success;
+deref_fault: /* branched to from deref() */
+  {
+    static char errmsg[50];
+    snprintf (errmsg, 40, "kernel char copy fault at 0x%p",
+        (void *) (uintptr_t) THIS->addr);
+    CONTEXT->last_error = errmsg;
+  }
+success: ;
+%}
+
+
+
 
 // On rare cases when userspace data is not accessible, 
 // this function returns "<unknown>"
@@ -42,7 +96,7 @@ function user_string_warn:string (addr:long) %{ /* pure */
   long rc = _stp_strncpy_from_user (THIS->__retvalue,
                (const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN);
   if (rc < 0) {
-       static char errmsg[40];
+       static char errmsg[60];
        snprintf (errmsg, 40, "user string copy fault %ld at %p", rc,
                (void *) (uintptr_t) THIS->addr);
        _stp_warn(errmsg);
@@ -54,5 +108,6 @@ function user_string_quoted:string (addr:long) %{ /* pure */
   if (THIS->addr == 0) 
        strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN);
   else
+        /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?!  */
        _stp_text_str(THIS->__retvalue, (char *)(uintptr_t)THIS->addr, MAXSTRINGLEN, 1, 1);
 %}
index 2c72f3e5428e09363f1963e988148716da28419c..fcae70c33353dd91070c5794f7ab3601faa33c69 100644 (file)
@@ -1,3 +1,8 @@
+2007-02-06  Frank Ch. Eigler  <fche@elastic.org>
+
+       * buildok/conversions.stp: Build-test all conversions.stp functions.
+       * systemtap.stress/conversions.*: New test.
+
 2007-01-29  Frank Ch. Eigler  <fche@elastic.org>
 
        * systemtap.base/cache.exp (stap_compile): Accept new -p4 output.
diff --git a/testsuite/buildok/conversions.stp b/testsuite/buildok/conversions.stp
new file mode 100755 (executable)
index 0000000..5a4d46f
--- /dev/null
@@ -0,0 +1,13 @@
+# Test the conversions tapset.
+
+probe begin {
+  print (kernel_string(2342))
+  print (kernel_long(2342))
+  print (kernel_int(2342))
+  print (kernel_short(2342))
+  print (kernel_char(2342))
+
+  print (user_string(2342))
+  print (user_string2(2342,"foobar"))
+  print (user_string_warn(2342))
+}
\ No newline at end of file
diff --git a/testsuite/systemtap.stress/conversions.exp b/testsuite/systemtap.stress/conversions.exp
new file mode 100644 (file)
index 0000000..a7fd5e8
--- /dev/null
@@ -0,0 +1,19 @@
+
+set file $srcdir/$subdir/conversions.stp
+foreach value {0 0xffffffff 0xffffffffffffffff} {
+    set test "conversions.stp $value"
+    if {![installtest_p]} { untested $test; continue }
+    spawn stap -DMAXERRORS=40 $file $value
+    set errs 0
+    verbose -log "exp $test $errs"
+    expect {
+        -re {ERROR[^\r\n]*\r\n} { incr errs; exp_continue }
+        -re {WARNING[^\r\n]*\r\n} { incr errs; exp_continue }
+        eof { }
+        timeout { }
+    }
+    verbose -log "done exp $test $errs"
+    wait
+    if {$errs == 8} { pass $test } else { fail "$test ($errs)" }
+    verbose -log "done $test $errs"
+}
diff --git a/testsuite/systemtap.stress/conversions.stp b/testsuite/systemtap.stress/conversions.stp
new file mode 100644 (file)
index 0000000..797626a
--- /dev/null
@@ -0,0 +1,15 @@
+#! stap
+# Usage: set $1 to supply test address; -DMAXERRORS=<many>
+
+probe begin(-1) { print ("\n") }
+probe begin { print (kernel_string ($1)) }
+probe begin { print (kernel_long ($1)) }
+probe begin { print (kernel_int ($1)) }
+probe begin { print (kernel_short ($1)) }
+probe begin { print (kernel_char ($1)) }
+probe begin { print (kernel_int ($1)) }
+probe begin { print (user_string ($1)) }
+probe begin { print (user_string2 ($1,"<only suspected, not known>")) }
+probe begin { print (user_string_warn ($1)) }
+probe begin { print (user_string_quoted ($1)) }
+probe begin(1) { print ("\n") exit () }
This page took 0.04553 seconds and 5 git commands to generate.