diff options
author | fche <fche> | 2007-02-06 20:23:25 +0000 |
---|---|---|
committer | fche <fche> | 2007-02-06 20:23:25 +0000 |
commit | f902d9596b3f7ee135d180ec0bae01c05d9a97bd (patch) | |
tree | 360649626b889dbeb0d1ed861e2b6631fe9ba1ab /tapset/conversions.stp | |
parent | 34f6a71cdaa6cf4835819ca5b92a152e2cd5bde0 (diff) | |
download | systemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.tar.gz systemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.tar.xz systemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.zip |
* kernel_{string,long,...,char} protected accessor functions
* 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.
Diffstat (limited to 'tapset/conversions.stp')
-rw-r--r-- | tapset/conversions.stp | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/tapset/conversions.stp b/tapset/conversions.stp index c311d25a..fe5adc10 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -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); %} |