diff options
author | hunt <hunt> | 2007-01-31 20:13:02 +0000 |
---|---|---|
committer | hunt <hunt> | 2007-01-31 20:13:02 +0000 |
commit | 1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b (patch) | |
tree | 09dddc7115d2691e05ee392c2316c0793013a709 | |
parent | dcc4fec4fbb6caddbc82c758f57c014cfc37d088 (diff) | |
download | systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.tar.gz systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.tar.xz systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.zip |
2007-01-31 Martin Hunt <hunt@redhat.com>
* string.c (_stp_string_init): Deleted.
(_stp_sprintf): Deleted.
(_stp_vsprintf): Deleted.
(_stp_string_cat_cstr): Deleted.
(_stp_string_cat_string): Deleted.
(_stp_string_cat_char): Deleted.
(_stp_string_ptr): Deleted.
(_stp_string_cat): Deleted.
(_stp_snprintf): Moved from vsprintf.c.
(_stp_vscnprintf): Moved from vsprintf.c.
* string.h (STP_STRING_SIZE): Deleted.
(STP_NUM_STRINGS): Deleted.
Remove all references to type "String".
* vsprintf.c (_stp_vscnprintf): Moved to string.c.
(_stp_snprintf): Moved to string.c
* sym.c (_stp_symbol_sprint): Replaced with
_stp_symbol_print, which writes to the print buffer.
(_stp_symbol_sprint_basic): Replaced with
_stp_symbol_snprint.
* runtime.h: Include io.c.
* stat-common.c: Use new _stp_print* functions.
* stat.c: Ditto.
* regs.c: Renamed to regs-ia64.c.
* current.c: Renamed regs.c.
* regs-ia64.c: New file (renamed from regs.c).
* stack.c (_stp_stack_sprint): Renamed _stp_stack_print
and now just prints to the print buffer. Calls
__stp_stack_print instead of __stp_stack_sprint.
(_stp_stack_snprint): New function. Calls _stp_stack_print and
then copies the print buffer into a string.
(_stp_stack_printj): Deleted.
(_stp_ustack_sprint): Deleted.
* stack-*.c: Rewritten to print instead of writing to strings.
Uses new _stp_print* functions.
* print.c (_stp_printf): Create new function instead of macro.
(_stp_print): Ditto.
(_stp_print_char): New function.
* map.c: Use _stp_print() and _stp_print_char()
instead of _stp_print_cstr().
* io.c (_stp_vlog): Use _stp_print() instead
of _stp_string_cat_cstr().
* copy.c (_stp_string_from_user): Deleted.
-rw-r--r-- | runtime/ChangeLog | 57 | ||||
-rw-r--r-- | runtime/copy.c | 26 | ||||
-rw-r--r-- | runtime/current.c | 257 | ||||
-rw-r--r-- | runtime/io.c | 13 | ||||
-rw-r--r-- | runtime/map.c | 10 | ||||
-rw-r--r-- | runtime/print.c | 120 | ||||
-rw-r--r-- | runtime/regs-ia64.c | 89 | ||||
-rw-r--r-- | runtime/regs.c | 279 | ||||
-rw-r--r-- | runtime/runtime.h | 1 | ||||
-rw-r--r-- | runtime/stack-i386.c | 38 | ||||
-rw-r--r-- | runtime/stack-ia64.c | 14 | ||||
-rw-r--r-- | runtime/stack-ppc64.c | 29 | ||||
-rw-r--r-- | runtime/stack-s390.c | 36 | ||||
-rw-r--r-- | runtime/stack-x86_64.c | 28 | ||||
-rw-r--r-- | runtime/stack.c | 91 | ||||
-rw-r--r-- | runtime/stat-common.c | 14 | ||||
-rw-r--r-- | runtime/stat.c | 4 | ||||
-rw-r--r-- | runtime/string.c | 213 | ||||
-rw-r--r-- | runtime/string.h | 27 | ||||
-rw-r--r-- | runtime/sym.c | 52 | ||||
-rw-r--r-- | runtime/vsprintf.c | 17 |
21 files changed, 590 insertions, 825 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index a4e8a7b4..95cf3483 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,60 @@ +2007-01-31 Martin Hunt <hunt@redhat.com> + + * string.c (_stp_string_init): Deleted. + (_stp_sprintf): Deleted. + (_stp_vsprintf): Deleted. + (_stp_string_cat_cstr): Deleted. + (_stp_string_cat_string): Deleted. + (_stp_string_cat_char): Deleted. + (_stp_string_ptr): Deleted. + (_stp_string_cat): Deleted. + (_stp_snprintf): Moved from vsprintf.c. + (_stp_vscnprintf): Moved from vsprintf.c. + + * string.h (STP_STRING_SIZE): Deleted. + (STP_NUM_STRINGS): Deleted. + Remove all references to type "String". + + * vsprintf.c (_stp_vscnprintf): Moved to string.c. + (_stp_snprintf): Moved to string.c + + * sym.c (_stp_symbol_sprint): Replaced with + _stp_symbol_print, which writes to the print buffer. + (_stp_symbol_sprint_basic): Replaced with + _stp_symbol_snprint. + + * runtime.h: Include io.c. + + * stat-common.c: Use new _stp_print* functions. + * stat.c: Ditto. + + * regs.c: Renamed to regs-ia64.c. + * current.c: Renamed regs.c. + * regs-ia64.c: New file (renamed from regs.c). + + * stack.c (_stp_stack_sprint): Renamed _stp_stack_print + and now just prints to the print buffer. Calls + __stp_stack_print instead of __stp_stack_sprint. + (_stp_stack_snprint): New function. Calls _stp_stack_print and + then copies the print buffer into a string. + (_stp_stack_printj): Deleted. + (_stp_ustack_sprint): Deleted. + * stack-*.c: Rewritten to print instead of writing to strings. + Uses new _stp_print* functions. + + * print.c (_stp_printf): Create new function instead of macro. + (_stp_print): Ditto. + (_stp_print_char): New function. + + * map.c: Use _stp_print() and _stp_print_char() + instead of _stp_print_cstr(). + + * io.c (_stp_vlog): Use _stp_print() instead + of _stp_string_cat_cstr(). + + * copy.c (_stp_string_from_user): Deleted. + + 2007-01-30 Martin Hunt <hunt@redhat.com> * io.c (_stp_vlog): Use dynamic percpu allocations diff --git a/runtime/copy.c b/runtime/copy.c index 4d716861..da27673c 100644 --- a/runtime/copy.c +++ b/runtime/copy.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Copy from user space functions - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 2007 Red Hat Inc. * Copyright (C) 2005 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -119,30 +119,6 @@ _stp_strncpy_from_user(char *dst, const char __user *src, long count) return res; } -/** Copy a String from userspace. - * Copies a string of up to \e count bytes from userspace into a String. - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * @param str Destination String. - * @param src Source address, in user space. - * @param count Maximum number of bytes to copy, including the trailing NULL. - * - */ - -long _stp_string_from_user (String str, const char __user *src, long count) -{ - long res = -EFAULT; - if (count > STP_STRING_SIZE - str->len - 1) - count = STP_STRING_SIZE - str->len - 1; - if (access_ok(VERIFY_READ, src, count)) { - __stp_strncpy_from_user(str->buf + str->len, src, count, res); - if (res > 0) { - str->len += res; - str->buf[str->len] = '\0'; - } - } - return res; -} /** Copy a block of data from user space. * diff --git a/runtime/current.c b/runtime/current.c deleted file mode 100644 index 809f253b..00000000 --- a/runtime/current.c +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- linux-c -*- - * Functions to access the members of pt_regs struct - * Copyright (C) 2005 Red Hat Inc. - * Copyright (C) 2005 Intel Corporation. - * - * 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 - * Public License (GPL); either version 2, or (at your option) any - * later version. - */ - -#ifndef _CURRENT_C_ /* -*- linux-c -*- */ -#define _CURRENT_C_ - -#include "regs.h" - -/** @file current.c - * @brief Functions to get the current state. - */ -/** @addtogroup current Current State - * Functions to get the current state. - * @{ - */ - - -/** Get the current return address. - * Call from kprobes (not jprobes). - * @param regs The pt_regs saved by the kprobe. - * @return The return address saved in the stack pointer. - * @note i386 and x86_64 only so far. - */ - -unsigned long _stp_ret_addr (struct pt_regs *regs) -{ -#ifdef __x86_64__ - unsigned long *ra = (unsigned long *)regs->rsp; - if (ra) - return *ra; - else - return 0; -#elif defined (__i386__) - return regs->esp; -#elif defined (__powerpc64__) - return REG_LINK(regs); -#elif defined (__ia64__) - return regs->b0; -#elif defined (__s390__) || defined (__s390x__) - return regs->gprs[14]; -#else - #error Unimplemented architecture -#endif -} - -/** Get the current return address for a return probe. - * Call from kprobe return probe. - * @param ri Pointer to the struct kretprobe_instance. - * @return The return address - */ -#define _stp_ret_addr_r(ri) (ri->ret_addr) - -/** Get the probe address for a kprobe. - * Call from a kprobe. This will return the - * address of the function that is being probed. - * @param kp Pointer to the struct kprobe. - * @return The function's address - */ -#define _stp_probe_addr(kp) (kp->addr) - -/** Get the probe address for a return probe. - * Call from kprobe return probe. This will return the - * address of the function that is being probed. - * @param ri Pointer to the struct kretprobe_instance. - * @return The function's address - */ -#define _stp_probe_addr_r(ri) (ri->rp->kp.addr) - -#ifdef __x86_64__ -void _stp_sprint_regs(String str, struct pt_regs * regs) -{ - unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; - unsigned int fsindex,gsindex; - unsigned int ds,cs,es; - - _stp_sprintf(str,"RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->rip, regs->rsp, regs->eflags); - _stp_sprintf(str,"RAX: %016lx RBX: %016lx RCX: %016lx\n", - regs->rax, regs->rbx, regs->rcx); - _stp_sprintf(str,"RDX: %016lx RSI: %016lx RDI: %016lx\n", - regs->rdx, regs->rsi, regs->rdi); - _stp_sprintf(str,"RBP: %016lx R08: %016lx R09: %016lx\n", - regs->rbp, regs->r8, regs->r9); - _stp_sprintf(str,"R10: %016lx R11: %016lx R12: %016lx\n", - regs->r10, regs->r11, regs->r12); - _stp_sprintf(str,"R13: %016lx R14: %016lx R15: %016lx\n", - regs->r13, regs->r14, regs->r15); - - asm("movl %%ds,%0" : "=r" (ds)); - asm("movl %%cs,%0" : "=r" (cs)); - asm("movl %%es,%0" : "=r" (es)); - asm("movl %%fs,%0" : "=r" (fsindex)); - asm("movl %%gs,%0" : "=r" (gsindex)); - - rdmsrl(MSR_FS_BASE, fs); - rdmsrl(MSR_GS_BASE, gs); - rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); - - asm("movq %%cr0, %0": "=r" (cr0)); - asm("movq %%cr2, %0": "=r" (cr2)); - asm("movq %%cr3, %0": "=r" (cr3)); - asm("movq %%cr4, %0": "=r" (cr4)); - - _stp_sprintf(str,"FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", - fs,fsindex,gs,gsindex,shadowgs); - _stp_sprintf(str,"CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); - _stp_sprintf(str,"CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); -} - -#elif defined (__ia64__) -void _stp_sprint_regs(String str, struct pt_regs * regs) -{ - unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; - - _stp_sprintf(str, "\nPid: %d, CPU %d, comm: %20s\n", current->pid, - smp_processor_id(), current->comm); - _stp_sprintf(str, "psr : %016lx ifs : %016lx ip : [<%016lx>] \n", - regs->cr_ipsr, regs->cr_ifs, ip); - _stp_sprintf(str, "unat: %016lx pfs : %016lx rsc : %016lx\n", - regs->ar_unat, regs->ar_pfs, regs->ar_rsc); - _stp_sprintf(str, "rnat: %016lx bsps: %016lx pr : %016lx\n", - regs->ar_rnat, regs->ar_bspstore, regs->pr); - _stp_sprintf(str, "ldrs: %016lx ccv : %016lx fpsr: %016lx\n", - regs->loadrs, regs->ar_ccv, regs->ar_fpsr); - _stp_sprintf(str, "csd : %016lx ssd : %016lx\n", - regs->ar_csd, regs->ar_ssd); - _stp_sprintf(str, "b0 : %016lx b6 : %016lx b7 : %016lx\n", - regs->b0, regs->b6, regs->b7); - _stp_sprintf(str, "f6 : %05lx%016lx f7 : %05lx%016lx\n", - regs->f6.u.bits[1], regs->f6.u.bits[0], - regs->f7.u.bits[1], regs->f7.u.bits[0]); - _stp_sprintf(str, "f8 : %05lx%016lx f9 : %05lx%016lx\n", - regs->f8.u.bits[1], regs->f8.u.bits[0], - regs->f9.u.bits[1], regs->f9.u.bits[0]); - _stp_sprintf(str, "f10 : %05lx%016lx f11 : %05lx%016lx\n", - regs->f10.u.bits[1], regs->f10.u.bits[0], - regs->f11.u.bits[1], regs->f11.u.bits[0]); -} - -#elif defined (__i386__) - -/** Write the registers to a string. - * @param regs The pt_regs saved by the kprobe. - * @note i386 and x86_64 only so far. - */ -void _stp_sprint_regs(String str, struct pt_regs * regs) -{ - unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; - - _stp_sprintf (str, "EIP: %08lx\n",regs->eip); - _stp_sprintf (str, "ESP: %08lx\n",regs->esp); - _stp_sprintf (str, "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - regs->eax,regs->ebx,regs->ecx,regs->edx); - _stp_sprintf (str, "ESI: %08lx EDI: %08lx EBP: %08lx", - regs->esi, regs->edi, regs->ebp); - _stp_sprintf (str, " DS: %04x ES: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes); - - __asm__("movl %%cr0, %0": "=r" (cr0)); - __asm__("movl %%cr2, %0": "=r" (cr2)); - __asm__("movl %%cr3, %0": "=r" (cr3)); - /* This could fault if %cr4 does not exist */ - __asm__("1: movl %%cr4, %0 \n" - "2: \n" - ".section __ex_table,\"a\" \n" - ".long 1b,2b \n" - ".previous \n" - : "=r" (cr4): "0" (0)); - _stp_sprintf (str, "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); -} - -#elif defined (__powerpc64__) - -void _stp_sprint_regs(String str, struct pt_regs * regs) -{ - int i; - - _stp_sprintf(str, "NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n", - regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr); - _stp_sprintf(str, "REGS: %p TRAP: %04lx\n", regs, regs->trap); - _stp_sprintf(str, "MSR: %016lx CR: %08X\n", - regs->msr, (unsigned int)regs->ccr); - _stp_sprintf(str, "DAR: %016lx DSISR: %016lx\n", - regs->dar, regs->dsisr); - -#ifdef CONFIG_SMP - _stp_sprintf(str, " CPU: %d", smp_processor_id()); -#endif /* CONFIG_SMP */ - - for (i = 0; i < 32; i++) { - if ((i % 4) == 0) { - _stp_sprintf(str, "\n GPR%02d: ", i); - } - - _stp_sprintf(str, "%016lX ", regs->gpr[i]); - if (i == 13 && !FULL_REGS(regs)) - break; - } - _stp_string_cat(str, "\n"); - _stp_sprintf(str, "NIP [%016lx] ", regs->nip); - _stp_sprintf(str, "LR [%016lx] ", regs->link); - _stp_string_cat(str, regs->link); - _stp_string_cat(str, "\n"); -} - -#elif defined (__s390x__) || defined (__s390__) - -#ifdef __s390x__ -#define GPRSIZE "%016lX " -#else /* s390 */ -#define GPRSIZE "%08lX " -#endif - -void _stp_sprint_regs(String str, struct pt_regs * regs) -{ - char *mode; - int i; - - mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; - _stp_sprintf(str,"%s PSW : ["GPRSIZE"] ["GPRSIZE"]", - mode, (void *) regs->psw.mask, - (void *) regs->psw.addr); - -#ifdef CONFIG_SMP - _stp_sprintf(str, " CPU: %d", smp_processor_id()); -#endif /* CONFIG_SMP */ - - for (i = 0; i < 16; i++) { - if ((i % 4) == 0) { - _stp_sprintf(str, "\n GPRS%02d: ", i); - } - _stp_sprintf(str, GPRSIZE, regs->gprs[i]); - } - _stp_string_cat(str, "\n"); -} - -#endif - -/** Print the registers. - * @param regs The pt_regs saved by the kprobe. - * @note i386 and x86_64 only so far. - */ -#define _stp_print_regs(regs) \ - { \ - _stp_sprint_regs(_stp_stdout,regs); \ - _stp_print_flush(); \ - } - -/** @} */ -#endif /* _CURRENT_C_ */ diff --git a/runtime/io.c b/runtime/io.c index 1483acfd..34c69727 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -11,11 +11,6 @@ #ifndef _IO_C_ #define _IO_C_ -#include "transport/transport.c" - -void _stp_print_flush (void); -void _stp_string_cat_cstr (String str1, const char *str2); - /** @file io.c * @brief I/O for printing warnings, errors and debug messages. */ @@ -27,12 +22,6 @@ void _stp_string_cat_cstr (String str1, const char *str2); #define ERR_STRING "ERROR: " enum code { INFO=0, WARN, ERROR, DBUG }; -/** private buffer for _stp_log() */ -#define STP_LOG_BUF_LEN 256 - -typedef char _stp_lbuf[STP_LOG_BUF_LEN]; -void *Stp_lbuf = NULL; - static void _stp_vlog (enum code type, const char *func, int line, const char *fmt, va_list args) { int num; @@ -60,7 +49,7 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f if (type != DBUG) _stp_write(STP_OOB_DATA, buf, start + num + 1); else { - _stp_string_cat_cstr(_stp_stdout,buf); + _stp_print(buf); _stp_print_flush(); } } diff --git a/runtime/map.c b/runtime/map.c index 9fc414a7..dfef2f73 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Map Functions - * Copyright (C) 2005 Red Hat Inc. + * Copyright (C) 2005, 2006, 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 @@ -643,7 +643,7 @@ static int print_keytype (char *fmt, int type, key_data *kd) case STRING: if (*fmt != 's') return 1; - _stp_print_cstr (kd->strp); + _stp_print (kd->strp); break; case INT64: if (*fmt == 'x') @@ -675,7 +675,7 @@ static void print_valtype (MAP map, char *fmt, struct map_node *ptr) switch (map->type) { case STRING: if (*fmt == 's') - _stp_print_cstr(_stp_get_str(ptr)); + _stp_print (_stp_get_str(ptr)); break; case INT64: { @@ -739,11 +739,11 @@ void _stp_map_printn (MAP map, int n, const char *fmt) if (*f) f++; } - _stp_print_cstr ("\n"); + _stp_print_char ('\n'); if (n && (--n <= 0)) break; } - _stp_print_cstr ("\n"); + _stp_print_char ('\n'); _stp_print_flush(); } diff --git a/runtime/print.c b/runtime/print.c index 8ddafab8..b4c7bc49 100644 --- a/runtime/print.c +++ b/runtime/print.c @@ -13,8 +13,7 @@ #include "string.h" #include "vsprintf.c" -#include "io.c" - +#include "transport/transport.c" /** @file print.c * Printing Functions. @@ -51,6 +50,12 @@ typedef struct __stp_pbuf { void *Stp_pbuf = NULL; +/** private buffer for _stp_log() */ +#define STP_LOG_BUF_LEN 256 + +typedef char _stp_lbuf[STP_LOG_BUF_LEN]; +void *Stp_lbuf = NULL; + /* create percpu print and io buffers */ int _stp_print_init (void) { @@ -133,7 +138,7 @@ static void * _stp_reserve_bytes (int numbytes) if (unlikely(numbytes == 0 || numbytes > STP_BUFFER_SIZE)) return NULL; - if (numbytes > size) + if (unlikely(numbytes > size)) _stp_print_flush(); ret = pb->buf + pb->len; @@ -159,7 +164,7 @@ static void _stp_print_binary (int num, ...) args = _stp_reserve_bytes(num * sizeof(int64_t)); - if (args != NULL) { + if (likely(args != NULL)) { va_start(vargs, num); for (i = 0; i < num; i++) { args[i] = va_arg(vargs, int64_t); @@ -169,42 +174,72 @@ static void _stp_print_binary (int num, ...) } /** Print into the print buffer. - * Like printf, except output goes to the print buffer. - * Safe because overflowing the buffer is not allowed. + * Like C printf. * * @sa _stp_print_flush() */ -#define _stp_printf(args...) _stp_sprintf(_stp_stdout,args) - -/** Print into the print buffer. - * Use this if your function already has a va_list. - * You probably want _stp_printf(). - */ +void _stp_printf (const char *fmt, ...) +{ + int num; + va_list args; + _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); + char *buf = pb->buf + pb->len; + int size = STP_BUFFER_SIZE - pb->len; -#define _stp_vprintf(fmt,args) _stp_vsprintf(_stp_stdout,fmt,args) + va_start(args, fmt); + num = _stp_vsnprintf(buf, size, fmt, args); + va_end(args); + if (unlikely(num >= size)) { + /* overflowed the buffer */ + if (pb->len == 0) { + /* A single print request exceeded the buffer size. */ + /* Should not be possible with Systemtap-generated code. */ + pb->len = STP_BUFFER_SIZE; + _stp_print_flush(); + num = 0; + } else { + /* Need more space. Flush the previous contents */ + _stp_print_flush(); + + /* try again */ + va_start(args, fmt); + num = _stp_vsnprintf(pb->buf, STP_BUFFER_SIZE, fmt, args); + va_end(args); + } + } + pb->len += num; +} -/** Write a C string into the print buffer. - * Copies a string into a print buffer. - * Safe because overflowing the buffer is not allowed. - * This is more efficient than using _stp_printf() if you don't - * need fancy formatting. - * - * @param str A C string. - * @sa _stp_print +/** Write a string into the print buffer. + * @param str A C string (char *) */ -#define _stp_print_cstr(str) _stp_string_cat_cstr(_stp_stdout,str) +void _stp_print (const char *str) +{ + int num = strlen (str); + _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); + int size = STP_BUFFER_SIZE - pb->len; + if (unlikely(num >= size)) { + _stp_print_flush(); + if (num > STP_BUFFER_SIZE) + num = STP_BUFFER_SIZE; + } + memcpy (pb->buf + pb->len, str, num); + pb->len += num; +} + +void _stp_print_char (const char c) +{ + char *buf; + _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); + int size = STP_BUFFER_SIZE - pb->len; + if (unlikely(1 >= size)) + _stp_print_flush(); + + pb->buf[pb->len] = c; + pb->len ++; +} -/** Write a String into the print buffer. - * Copies a String into a print buffer. - * Safe because overflowing the buffer is not allowed. - * This is more efficient than using _stp_printf() if you don't - * need fancy formatting. - * - * @param str A String. - * @sa _stp_print - */ -#define _stp_print_string(str) _stp_string_cat_string(_stp_stdout,str) /* This function is used when printing maps or stats. */ /* Probably belongs elsewhere, but is here for now. */ @@ -220,7 +255,7 @@ static char *next_fmt(char *fmt, int *num) while (*f) { if (in_fmt) { if (*f == '%') { - _stp_string_cat_char(_stp_stdout,'%'); + _stp_print_char('%'); in_fmt = 0; } else if (*f > '0' && *f <= '9') { *num = *f - '0'; @@ -231,28 +266,11 @@ static char *next_fmt(char *fmt, int *num) } else if (*f == '%') in_fmt = 1; else - _stp_string_cat_char(_stp_stdout,*f); + _stp_print_char(*f); f++; } return f; } -/** Write a String or C string into the print buffer. - * This macro selects the proper function to call. - * @param str A String or C string (char *) - * @sa _stp_print_cstr _stp_print_string - */ - -#define _stp_print(str) \ - ({ \ - if (__builtin_types_compatible_p (typeof (str), char[])) { \ - char *x = (char *)str; \ - _stp_string_cat_cstr(_stp_stdout,x); \ - } else { \ - String x = (String)str; \ - _stp_string_cat_string(_stp_stdout,x); \ - } \ - }) - /** @} */ #endif /* _PRINT_C_ */ diff --git a/runtime/regs-ia64.c b/runtime/regs-ia64.c new file mode 100644 index 00000000..50bf17d7 --- /dev/null +++ b/runtime/regs-ia64.c @@ -0,0 +1,89 @@ +/* -*- linux-c -*- + * IA64 register access functions + * Copyright (C) 2005 Intel Corporation. + * + * 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 + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _REGS_IA64_C_ +#define _REGS_IA64_C_ + +#if defined __ia64__ + +struct ia64_stap_get_arbsp_param { + unsigned long ip; + unsigned long *address; +}; + +static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg) +{ + unsigned long ip; + struct ia64_stap_get_arbsp_param *lp = arg; + + do { + unw_get_ip(info, &ip); + if (ip == 0) + break; + if (ip == lp->ip) { + unw_get_bsp(info, (unsigned long*)&lp->address); + return; + } + } while (unw_unwind(info) >= 0); + lp->address = 0; +} + +static long ia64_fetch_register(int regno, struct pt_regs *pt_regs) +{ + struct ia64_stap_get_arbsp_param pa; + + if (regno >= 8 && regno <= 11) + return *(unsigned long *)(&pt_regs->r8 + regno - 8); + else if (regno < 32 || regno > 127) + return 0; + + pa.ip = pt_regs->cr_iip; + unw_init_running(ia64_stap_get_arbsp, &pa); + if (pa.address == 0) + return 0; + + return *ia64_rse_skip_regs(pa.address, regno-32); +} + +static void ia64_store_register(int regno, + struct pt_regs *pt_regs, + unsigned long value) +{ + struct ia64_stap_get_arbsp_param pa; + unsigned long rsc_save = 0; + unsigned long *addr; + + if (regno >= 8 && regno <= 11) { + addr =&pt_regs->r8; + addr += regno - 8; + *(addr) = value; + } + else if (regno < 32 || regno > 127) + return; + + pa.ip = pt_regs->cr_iip; + unw_init_running(ia64_stap_get_arbsp, &pa); + if (pa.address == 0) + return; + *ia64_rse_skip_regs(pa.address, regno-32) = value; + //Invalidate all stacked registers outside the current frame + asm volatile( "mov %0=ar.rsc;;\n\t" + "mov ar.rsc=0;;\n\t" + "{\n\tloadrs;;\n\t\n\t\n\t}\n\t" + "mov ar.rsc=%1\n\t" + :"=r" (rsc_save):"r" (rsc_save):"memory"); + + return; +} + +#endif /* if defined __ia64__ */ + + +#endif /* _REGS_IA64_C_ */ diff --git a/runtime/regs.c b/runtime/regs.c index 6a879966..ead4ed8f 100644 --- a/runtime/regs.c +++ b/runtime/regs.c @@ -1,5 +1,6 @@ /* -*- linux-c -*- - * register access functions + * Functions to access the members of pt_regs struct + * Copyright (C) 2005 Red Hat Inc. * Copyright (C) 2005 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -8,82 +9,236 @@ * later version. */ -#ifndef _REG_C_ -#define _REG_C_ +#ifndef _REGS_C_ +#define _REGS_C_ -#if defined __ia64__ +#include "regs.h" -struct ia64_stap_get_arbsp_param { - unsigned long ip; - unsigned long *address; -}; +/** @file current.c + * @brief Functions to get the current state. + */ +/** @addtogroup current Current State + * Functions to get the current state. + * @{ + */ -static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg) -{ - unsigned long ip; - struct ia64_stap_get_arbsp_param *lp = arg; - do { - unw_get_ip(info, &ip); - if (ip == 0) - break; - if (ip == lp->ip) { - unw_get_bsp(info, (unsigned long*)&lp->address); - return; - } - } while (unw_unwind(info) >= 0); - lp->address = 0; +/** Get the current return address. + * Call from kprobes (not jprobes). + * @param regs The pt_regs saved by the kprobe. + * @return The return address saved in the stack pointer. + * @note i386 and x86_64 only so far. + */ + +unsigned long _stp_ret_addr (struct pt_regs *regs) +{ +#ifdef __x86_64__ + unsigned long *ra = (unsigned long *)regs->rsp; + if (ra) + return *ra; + else + return 0; +#elif defined (__i386__) + return regs->esp; +#elif defined (__powerpc64__) + return REG_LINK(regs); +#elif defined (__ia64__) + return regs->b0; +#elif defined (__s390__) || defined (__s390x__) + return regs->gprs[14]; +#else + #error Unimplemented architecture +#endif } -static long ia64_fetch_register(int regno, struct pt_regs *pt_regs) +/** Get the current return address for a return probe. + * Call from kprobe return probe. + * @param ri Pointer to the struct kretprobe_instance. + * @return The return address + */ +#define _stp_ret_addr_r(ri) (ri->ret_addr) + +/** Get the probe address for a kprobe. + * Call from a kprobe. This will return the + * address of the function that is being probed. + * @param kp Pointer to the struct kprobe. + * @return The function's address + */ +#define _stp_probe_addr(kp) (kp->addr) + +/** Get the probe address for a return probe. + * Call from kprobe return probe. This will return the + * address of the function that is being probed. + * @param ri Pointer to the struct kretprobe_instance. + * @return The function's address + */ +#define _stp_probe_addr_r(ri) (ri->rp->kp.addr) + +#ifdef __x86_64__ +void _stp_print_regs(struct pt_regs * regs) { - struct ia64_stap_get_arbsp_param pa; + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; + unsigned int fsindex,gsindex; + unsigned int ds,cs,es; + + _stp_printf("RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->rip, regs->rsp, regs->eflags); + _stp_printf("RAX: %016lx RBX: %016lx RCX: %016lx\n", + regs->rax, regs->rbx, regs->rcx); + _stp_printf("RDX: %016lx RSI: %016lx RDI: %016lx\n", + regs->rdx, regs->rsi, regs->rdi); + _stp_printf("RBP: %016lx R08: %016lx R09: %016lx\n", + regs->rbp, regs->r8, regs->r9); + _stp_printf("R10: %016lx R11: %016lx R12: %016lx\n", + regs->r10, regs->r11, regs->r12); + _stp_printf("R13: %016lx R14: %016lx R15: %016lx\n", + regs->r13, regs->r14, regs->r15); + + asm("movl %%ds,%0" : "=r" (ds)); + asm("movl %%cs,%0" : "=r" (cs)); + asm("movl %%es,%0" : "=r" (es)); + asm("movl %%fs,%0" : "=r" (fsindex)); + asm("movl %%gs,%0" : "=r" (gsindex)); + + rdmsrl(MSR_FS_BASE, fs); + rdmsrl(MSR_GS_BASE, gs); + rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); + + asm("movq %%cr0, %0": "=r" (cr0)); + asm("movq %%cr2, %0": "=r" (cr2)); + asm("movq %%cr3, %0": "=r" (cr3)); + asm("movq %%cr4, %0": "=r" (cr4)); + + _stp_printf("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + fs,fsindex,gs,gsindex,shadowgs); + _stp_printf("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); + _stp_printf("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); +} - if (regno >= 8 && regno <= 11) - return *(unsigned long *)(&pt_regs->r8 + regno - 8); - else if (regno < 32 || regno > 127) - return 0; +#elif defined (__ia64__) +void _stp_print_regs(struct pt_regs * regs) +{ + unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; + + _stp_printf("\nPid: %d, CPU %d, comm: %20s\n", current->pid, + smp_processor_id(), current->comm); + _stp_printf("psr : %016lx ifs : %016lx ip : [<%016lx>] \n", + regs->cr_ipsr, regs->cr_ifs, ip); + _stp_printf("unat: %016lx pfs : %016lx rsc : %016lx\n", + regs->ar_unat, regs->ar_pfs, regs->ar_rsc); + _stp_printf("rnat: %016lx bsps: %016lx pr : %016lx\n", + regs->ar_rnat, regs->ar_bspstore, regs->pr); + _stp_printf("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", + regs->loadrs, regs->ar_ccv, regs->ar_fpsr); + _stp_printf("csd : %016lx ssd : %016lx\n", + regs->ar_csd, regs->ar_ssd); + _stp_printf("b0 : %016lx b6 : %016lx b7 : %016lx\n", + regs->b0, regs->b6, regs->b7); + _stp_printf("f6 : %05lx%016lx f7 : %05lx%016lx\n", + regs->f6.u.bits[1], regs->f6.u.bits[0], + regs->f7.u.bits[1], regs->f7.u.bits[0]); + _stp_printf("f8 : %05lx%016lx f9 : %05lx%016lx\n", + regs->f8.u.bits[1], regs->f8.u.bits[0], + regs->f9.u.bits[1], regs->f9.u.bits[0]); + _stp_printf("f10 : %05lx%016lx f11 : %05lx%016lx\n", + regs->f10.u.bits[1], regs->f10.u.bits[0], + regs->f11.u.bits[1], regs->f11.u.bits[0]); +} - pa.ip = pt_regs->cr_iip; - unw_init_running(ia64_stap_get_arbsp, &pa); - if (pa.address == 0) - return 0; +#elif defined (__i386__) - return *ia64_rse_skip_regs(pa.address, regno-32); +/** Write the registers to a string. + * @param regs The pt_regs saved by the kprobe. + * @note i386 and x86_64 only so far. + */ +void _stp_print_regs(struct pt_regs * regs) +{ + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; + + _stp_printf ("EIP: %08lx\n",regs->eip); + _stp_printf ("ESP: %08lx\n",regs->esp); + _stp_printf ("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + regs->eax,regs->ebx,regs->ecx,regs->edx); + _stp_printf ("ESI: %08lx EDI: %08lx EBP: %08lx", + regs->esi, regs->edi, regs->ebp); + _stp_printf (" DS: %04x ES: %04x\n", + 0xffff & regs->xds,0xffff & regs->xes); + + __asm__("movl %%cr0, %0": "=r" (cr0)); + __asm__("movl %%cr2, %0": "=r" (cr2)); + __asm__("movl %%cr3, %0": "=r" (cr3)); + /* This could fault if %cr4 does not exist */ + __asm__("1: movl %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (cr4): "0" (0)); + _stp_printf ("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); } -static void ia64_store_register(int regno, - struct pt_regs *pt_regs, - unsigned long value) +#elif defined (__powerpc64__) + +void _stp_print_regs(struct pt_regs * regs) { - struct ia64_stap_get_arbsp_param pa; - unsigned long rsc_save = 0; - unsigned long *addr; - - if (regno >= 8 && regno <= 11) { - addr =&pt_regs->r8; - addr += regno - 8; - *(addr) = value; + int i; + + _stp_printf("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n", + regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr); + _stp_printf("REGS: %p TRAP: %04lx\n", regs, regs->trap); + _stp_printf("MSR: %016lx CR: %08X\n", + regs->msr, (unsigned int)regs->ccr); + _stp_printf("DAR: %016lx DSISR: %016lx\n", + regs->dar, regs->dsisr); + +#ifdef CONFIG_SMP + _stp_printf(" CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 32; i++) { + if ((i % 4) == 0) { + _stp_printf("\n GPR%02d: ", i); + } + + _stp_printf("%016lX ", regs->gpr[i]); + if (i == 13 && !FULL_REGS(regs)) + break; } - else if (regno < 32 || regno > 127) - return; - - pa.ip = pt_regs->cr_iip; - unw_init_running(ia64_stap_get_arbsp, &pa); - if (pa.address == 0) - return; - *ia64_rse_skip_regs(pa.address, regno-32) = value; - //Invalidate all stacked registers outside the current frame - asm volatile( "mov %0=ar.rsc;;\n\t" - "mov ar.rsc=0;;\n\t" - "{\n\tloadrs;;\n\t\n\t\n\t}\n\t" - "mov ar.rsc=%1\n\t" - :"=r" (rsc_save):"r" (rsc_save):"memory"); - - return; + _stp_printf("\nNIP [%016lx] ", regs->nip); + _stp_printf("LR [%016lx]\n", regs->link); } -#endif /* if defined __ia64__ */ +#elif defined (__s390x__) || defined (__s390__) + +#ifdef __s390x__ +#define GPRSIZE "%016lX " +#else /* s390 */ +#define GPRSIZE "%08lX " +#endif + +void _stp_print_regs(struct pt_regs * regs) +{ + char *mode; + int i; + + mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; + _stp_printf("%s PSW : ["GPRSIZE"] ["GPRSIZE"]", + mode, (void *) regs->psw.mask, + (void *) regs->psw.addr); + +#ifdef CONFIG_SMP + _stp_printf(" CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) { + _stp_printf("\n GPRS%02d: ", i); + } + _stp_printf(GPRSIZE, regs->gprs[i]); + } + _stp_printf("\n"); +} +#endif -#endif /* _REG_C_ */ +/** @} */ +#endif /* _REGS_C_ */ diff --git a/runtime/runtime.h b/runtime/runtime.h index 4013e9bc..4d741cf4 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -75,6 +75,7 @@ static struct #include "alloc.c" #include "print.c" #include "string.c" +#include "io.c" #include "arith.c" #include "copy.c" #include "sym.h" diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index d36f30d2..d10a8cfe 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * i386 stack tracing functions - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 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 @@ -18,7 +18,7 @@ static inline int _stp_valid_stack_ptr_info(struct unwind_frame_info *info) } static int -_stp_show_trace_unwind(String str, struct unwind_frame_info *info, int verbose) +_stp_show_trace_unwind(struct unwind_frame_info *info, int verbose) { int n = 0; @@ -27,11 +27,11 @@ _stp_show_trace_unwind(String str, struct unwind_frame_info *info, int verbose) break; n++; if (verbose) { - _stp_string_cat(str, " "); - _stp_symbol_sprint (str, UNW_PC(info)); - _stp_string_cat(str, "\n"); + _stp_print_char (' '); + _stp_symbol_print (UNW_PC(info)); + _stp_print_char ('\n'); } else - _stp_sprintf (str, "%p ", UNW_PC(info)); + _stp_printf ("%p ", UNW_PC(info)); if (arch_unw_user_mode(info)) break; } @@ -44,7 +44,7 @@ static inline int _stp_valid_stack_ptr(unsigned long context, unsigned long p) return p > context && p < context + THREAD_SIZE - 3; } -static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, int levels) +static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { unsigned long *stack = (unsigned long *)®_SP(regs); unsigned long context = (unsigned long)stack & ~(THREAD_SIZE - 1); @@ -54,12 +54,12 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i #ifdef CONFIG_STACK_UNWIND struct unwind_frame_info info; if (unwind_init_frame_info(&info, current, regs) == 0) - uw_ret = _stp_show_trace_unwind(str, &info, verbose); + uw_ret = _stp_show_trace_unwind(&info, verbose); stack = (void *)UNW_SP(&info); #endif if (uw_ret == 0) - _stp_string_cat(str, "Inexact backtrace:\n"); + _stp_print("Inexact backtrace:\n"); #ifdef CONFIG_FRAME_POINTER { @@ -72,13 +72,13 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i if (verbose) { if (uw_ret) { uw_ret = 0; - _stp_string_cat(str, "Leftover inexact backtrace:\n"); + _stp_print("Leftover inexact backtrace:\n"); } - _stp_string_cat(str, " "); - _stp_symbol_sprint (str, addr); - _stp_string_cat(str, "\n"); + _stp_print_char(' '); + _stp_symbol_print (addr); + _stp_print_char('\n'); } else - _stp_sprintf (str, "%p ", (void *)addr); + _stp_printf ("%p ", (void *)addr); ebp = *(unsigned long *)ebp; } } @@ -89,13 +89,13 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i if (verbose) { if (uw_ret) { uw_ret = 0; - _stp_string_cat(str, "Leftover inexact backtrace:\n"); + _stp_print("Leftover inexact backtrace:\n"); } - _stp_string_cat(str, " "); - _stp_symbol_sprint(str, addr); - _stp_string_cat(str, "\n"); + _stp_print_char(' '); + _stp_symbol_print(addr); + _stp_print_char('\n'); } else - _stp_sprintf (str, "%p ", (void *)addr); + _stp_printf ("%p ", (void *)addr); } } #endif diff --git a/runtime/stack-ia64.c b/runtime/stack-ia64.c index f941869e..4ad045da 100644 --- a/runtime/stack-ia64.c +++ b/runtime/stack-ia64.c @@ -10,13 +10,11 @@ struct dump_para{ unsigned long *sp; - String str; }; static void __stp_show_stack_sym(struct unw_frame_info *info, void *arg) { unsigned long ip, skip=1; - String str = ((struct dump_para*)arg)->str; struct pt_regs *regs = container_of(((struct dump_para*)arg)->sp, struct pt_regs, r12); do { @@ -27,16 +25,15 @@ static void __stp_show_stack_sym(struct unw_frame_info *info, void *arg) skip = 0; else continue; } - _stp_string_cat(str, " "); - _stp_symbol_sprint(str, ip); - _stp_string_cat (str, "\n"); + _stp_print_char(' '); + _stp_symbol_print(ip); + _stp_print_char('\n'); } while (unw_unwind(info) >= 0); } static void __stp_show_stack_addr(struct unw_frame_info *info, void *arg) { unsigned long ip, skip=1; - String str = ((struct dump_para*)arg)->str; struct pt_regs *regs = container_of(((struct dump_para*)arg)->sp, struct pt_regs, r12); do { @@ -47,16 +44,15 @@ static void __stp_show_stack_addr(struct unw_frame_info *info, void *arg) skip = 0; continue; } - _stp_sprintf (str, "%lx ", ip); + _stp_printf ("%p ", ip); } while (unw_unwind(info) >= 0); } -static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, int levels) +static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { unsigned long *stack = (unsigned long *)®_SP(regs); struct dump_para para; - para.str = str; para.sp = stack; if (verbose) unw_init_running(__stp_show_stack_sym, ¶); diff --git a/runtime/stack-ppc64.c b/runtime/stack-ppc64.c index 72542bd2..87c528fd 100644 --- a/runtime/stack-ppc64.c +++ b/runtime/stack-ppc64.c @@ -7,7 +7,7 @@ * later version. */ -static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, int levels) +static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { unsigned long ip, newsp, lr = 0; int count = 0; @@ -23,14 +23,14 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i ip = _sp[2]; if (!firstframe || ip != lr) { if (verbose) { - _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); - _stp_symbol_sprint(str, ip); + _stp_printf("[%p] [%p] ", sp, ip); + _stp_symbol_print(ip); if (firstframe) - _stp_string_cat(str, " (unreliable)"); - _stp_string_cat(str, "\n"); + _stp_print(" (unreliable)"); + _stp_print_char('\n'); } else - _stp_sprintf(str,"%lx ", ip); + _stp_printf("%p ", ip); } firstframe = 0; /* @@ -41,19 +41,18 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); if (verbose) { - _stp_sprintf(str, "--- Exception: %lx at ", - regs->trap); - _stp_symbol_sprint(str, regs->nip); - _stp_string_cat(str, "\n"); + _stp_printf("--- Exception: %lx at ",regs->trap); + _stp_symbol_print(regs->nip); + _stp_print_char('\n'); lr = regs->link; - _stp_string_cat(str, " LR ="); - _stp_symbol_sprint(str, lr); - _stp_string_cat(str, "\n"); + _stp_print(" LR ="); + _stp_symbol_print(lr); + _stp_print_char('\n'); firstframe = 1; } else { - _stp_sprintf(str, "%lx ",regs->nip); - _stp_sprintf(str, "%lx ",regs->link); + _stp_printf("%p ",regs->nip); + _stp_printf("%p ",regs->link); } } diff --git a/runtime/stack-s390.c b/runtime/stack-s390.c index c65de741..fcf634ed 100644 --- a/runtime/stack-s390.c +++ b/runtime/stack-s390.c @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * ppc64 stack tracing functions + * s390 stack tracing functions * * 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 @@ -8,7 +8,7 @@ */ static unsigned long -__stp_show_stack (String str, unsigned long sp, unsigned long low, +__stp_show_stack (unsigned long sp, unsigned long low, unsigned long high, int verbose) { @@ -24,11 +24,11 @@ __stp_show_stack (String str, unsigned long sp, unsigned long low, sf = (struct stack_frame *) sp; ip = sf->gprs[8] & PSW_ADDR_INSN; if (verbose) { - _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); - _stp_symbol_sprint(str, ip); - _stp_string_cat(str, "\n"); + _stp_printf("[%p] [%p] ", sp, ip); + _stp_symbol_print(ip); + _stp_print_char('\n'); }else{ - _stp_sprintf(str,"%lx ", ip); + _stp_printf("%p ", ip); } /* Follow the back_chain */ while (1) { @@ -41,11 +41,11 @@ __stp_show_stack (String str, unsigned long sp, unsigned long low, sf = (struct stack_frame *) sp; ip = sf->gprs[8] & PSW_ADDR_INSN; if (verbose) { - _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); - _stp_symbol_sprint(str, ip); - _stp_string_cat(str, "\n"); + _stp_printf("[%p] [%p] ", sp, ip); + _stp_symbol_print(ip); + _stp_print_char('\n'); }else{ - _stp_sprintf(str,"%lx ", ip); + _stp_printf("%p ", ip); } } /* Zero backchain detected, check for interrupt frame. */ @@ -54,29 +54,29 @@ __stp_show_stack (String str, unsigned long sp, unsigned long low, return sp; regs = (struct pt_regs *) sp; if (verbose) { - _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); - _stp_symbol_sprint(str, ip); - _stp_string_cat(str, "\n"); + _stp_printf("[%p] [%p] ", sp, ip); + _stp_symbol_print(ip); + _stp_print_char('\n'); }else{ - _stp_sprintf(str,"%lx ", ip); + _stp_printf("%p ", ip); } low = sp; sp = regs->gprs[15]; } } -static void __stp_stack_sprint (String str, struct pt_regs *regs, - int verbose, int levels) +static void __stp_stack_print (struct pt_regs *regs, + int verbose, int levels) { unsigned long *_sp = (unsigned long *)®_SP(regs); unsigned long sp = (unsigned long)_sp; // unsigned long sp = (unsigned long)*_sp; - sp = __stp_show_stack(str, sp, + sp = __stp_show_stack(sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack,verbose); - __stp_show_stack(str, sp, + __stp_show_stack(sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE,verbose); } diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 3a188c2c..b8875edb 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * x86_64 stack tracing functions - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 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 @@ -17,7 +17,7 @@ static inline int _stp_valid_stack_ptr(struct unwind_frame_info *info) return p > context && p < context + THREAD_SIZE - 3; } -static int _stp_show_trace_unwind(String str, struct unwind_frame_info *info, int verbose) +static int _stp_show_trace_unwind(struct unwind_frame_info *info, int verbose) { int n = 0; @@ -26,11 +26,11 @@ static int _stp_show_trace_unwind(String str, struct unwind_frame_info *info, in break; n++; if (verbose) { - _stp_string_cat(str, " "); - _stp_symbol_sprint (str, UNW_PC(info)); - _stp_string_cat(str, "\n"); + _stp_print_char(' '); + _stp_symbol_print (UNW_PC(info)); + _stp_print_char('\n'); } else - _stp_sprintf (str, "%p ", UNW_PC(info)); + _stp_printf ("%p ", UNW_PC(info)); if (arch_unw_user_mode(info)) break; } @@ -38,7 +38,7 @@ static int _stp_show_trace_unwind(String str, struct unwind_frame_info *info, in } #endif /* CONFIG_STACK_UNWIND */ -static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, int levels) +static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { unsigned long *stack = (unsigned long *)®_SP(regs); unsigned long addr; @@ -47,12 +47,12 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i #ifdef CONFIG_STACK_UNWIND struct unwind_frame_info info; if (unwind_init_frame_info(&info, current, regs) == 0) - uw_ret = _stp_show_trace_unwind(str, &info, verbose); + uw_ret = _stp_show_trace_unwind(&info, verbose); stack = (void *)UNW_SP(&info); #endif if (uw_ret == 0) - _stp_string_cat(str, "Inexact backtrace:\n"); + _stp_print("Inexact backtrace:\n"); while ((long)stack & (THREAD_SIZE-1)) { addr = *stack++; @@ -60,13 +60,13 @@ static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, i if (verbose) { if (uw_ret) { uw_ret = 0; - _stp_string_cat(str, "Leftover inexact backtrace:\n"); + _stp_print("Leftover inexact backtrace:\n"); } - _stp_string_cat(str, " "); - _stp_symbol_sprint(str, addr); - _stp_string_cat(str, "\n"); + _stp_print_char(' '); + _stp_symbol_print(addr); + _stp_print_char('\n'); } else - _stp_sprintf (str, "%p ", (void *)addr); + _stp_printf("%p ", (void *)addr); } } } diff --git a/runtime/stack.c b/runtime/stack.c index 72a57e19..dfc7f0d3 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Stack tracing functions - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 2007 Red Hat Inc. * Copyright (C) 2005 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -12,7 +12,6 @@ #ifndef _STACK_C_ #define _STACK_C_ - /** @file stack.c * @brief Stack Tracing Functions */ @@ -64,80 +63,62 @@ static int _stp_kta(unsigned long addr) return 0; } -/** Writes stack backtrace to a String - * - * @param str String +/** Prints the stack backtrace * @param regs A pointer to the struct pt_regs. - * @returns Same String as was input with trace info appended, */ -String _stp_stack_sprint (String str, struct pt_regs *regs, int verbose, struct kretprobe_instance *pi) + +void _stp_stack_print(struct pt_regs *regs, int verbose, struct kretprobe_instance *pi) { if (verbose) { /* print the current address */ if (pi) { - _stp_string_cat(str, "Returning from: "); - _stp_symbol_sprint(str, (unsigned long)_stp_probe_addr_r(pi)); - _stp_string_cat(str, "\nReturning to: "); - _stp_symbol_sprint(str, (unsigned long)_stp_ret_addr_r(pi)); - } else - _stp_symbol_sprint (str, REG_IP(regs)); - _stp_string_cat(str, "\n"); + _stp_print("Returning from: "); + _stp_symbol_print((unsigned long)_stp_probe_addr_r(pi)); + _stp_print("\nReturning to : "); + _stp_symbol_print((unsigned long)_stp_ret_addr_r(pi)); + } else { + _stp_print_char(' '); + _stp_symbol_print (REG_IP(regs)); + } + _stp_print_char('\n'); } else - _stp_sprintf (str, "%lx ", REG_IP(regs)); - __stp_stack_sprint (str, regs, verbose, 0); - return str; + _stp_printf ("%p ", REG_IP(regs)); + __stp_stack_print (regs, verbose, 0); } -/** Prints the stack backtrace +/** Writes stack backtrace to a string + * + * @param str string * @param regs A pointer to the struct pt_regs. + * @returns void */ - -#define _stp_stack_print(regs,pi) (void)_stp_stack_sprint(_stp_stdout,regs,1,pi) - -/** Writes stack backtrace to a String. - * Use this when calling from a jprobe. - * @param str String - * @returns Same String as was input with trace info appended, - * @sa _stp_stack_sprint() - */ -String _stp_stack_sprintj(String str) +void _stp_stack_snprint (char *str, int size, struct pt_regs *regs, int verbose, struct kretprobe_instance *pi) { - unsigned long stack; - _stp_sprintf (str, "trace for %d (%s)\n", current->pid, current->comm); -/* __stp_stack_sprint (str, &stack, 1, 0); */ - return str; + /* To get a string, we use a simple trick. First flush the print buffer, */ + /* then call _stp_stack_print, then copy the result into the output string */ + /* and clear the print buffer. */ + _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); + _stp_print_flush(); + _stp_stack_print(regs, verbose, pi); + strlcpy(str, pb->buf, size < pb->len ? size : pb->len); + pb->len = 0; } -/** Prints the stack backtrace. - * Use this when calling from a jprobe. - * @sa _stp_stack_print() - */ -#define _stp_stack_printj() (void)_stp_stack_sprintj(_stp_stdout) -/** Writes the user stack backtrace to a String - * @param str String - * @returns Same String as was input with trace info appended, +/** Prints the user stack backtrace + * @param str string + * @returns Same string as was input with trace info appended, * @note Currently limited to a depth of two. Works from jprobes and kprobes. */ -String _stp_ustack_sprint (String str) +#if 0 +void _stp_ustack_print (char *str) { struct pt_regs *nregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1; -#if BITS_PER_LONG == 64 - _stp_sprintf (str, " 0x%016lx : [user]\n", REG_IP(nregs)); + _stp_printf ("%p : [user]\n", REG_IP(nregs)); if (REG_SP(nregs)) - _stp_sprintf (str, " 0x%016lx : [user]\n", *(unsigned long *)REG_SP(nregs)); -#else - _stp_sprintf (str, " 0x%08lx : [user]\n", REG_IP(nregs)); - if (REG_SP(nregs)) - _stp_sprintf (str, " 0x%08lx : [user]\n", *(unsigned long *)REG_SP(nregs)); -#endif - return str; + _stp_printf ("%p : [user]\n", *(unsigned long *)REG_SP(nregs)); } - -/** Prints the user stack backtrace - * @note Currently limited to a depth of two. Works from jprobes and kprobes. - */ -#define _stp_ustack_print() (void)_stp_ustack_sprint(_stp_stdout) +#endif /* 0 */ /** @} */ #endif /* _STACK_C_ */ diff --git a/runtime/stat-common.c b/runtime/stat-common.c index edab9aa4..48f8218a 100644 --- a/runtime/stat-common.c +++ b/runtime/stat-common.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * common stats functions for aggragations and maps - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 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 @@ -34,7 +34,7 @@ static int needed_space(int64_t v) static void reprint (int num, char *s) { while (num > 0) { - _stp_print_cstr (s); + _stp_print(s); num--; } } @@ -149,10 +149,10 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) else val_space = 5; for ( i = 0; i < j; i++) - _stp_print_cstr (" "); - _stp_print_cstr("value |"); + _stp_print(" "); + _stp_print("value |"); reprint (HIST_WIDTH, "-"); - _stp_print_cstr (" count\n"); + _stp_print(" count\n"); if (st->type == HIST_LINEAR) val = st->start; else @@ -161,7 +161,7 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) if (i >= low_bucket && i <= high_bucket) { reprint (val_space - needed_space(val), " "); _stp_printf("%lld", val); - _stp_print_cstr (" |"); + _stp_print(" |"); /* v = s->histogram[i] / scale; */ v = sd->histogram[i]; @@ -178,7 +178,7 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) else val *= 2; } - _stp_print_cstr ("\n"); + _stp_print_char('\n'); _stp_print_flush(); } diff --git a/runtime/stat.c b/runtime/stat.c index 98a283cf..cf224e5e 100644 --- a/runtime/stat.c +++ b/runtime/stat.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Statistics Aggregation - * Copyright (C) 2005 Red Hat Inc. + * Copyright (C) 2005, 2007 Red Hat Inc. * Copyright (C) 2006 Intel Corporation * * This file is part of systemtap, and is free software. You can @@ -246,7 +246,7 @@ static void __stp_stat_print (char *fmt, Stat st, stat *sd, int cpu) if (*f) f++; } - _stp_print_cstr ("\n"); + _stp_print_char('\n'); _stp_print_flush(); } diff --git a/runtime/string.c b/runtime/string.c index b740c064..6bf89966 100644 --- a/runtime/string.c +++ b/runtime/string.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * String Functions - * Copyright (C) 2005, 2006 Red Hat Inc. + * Copyright (C) 2005, 2006, 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 @@ -13,217 +13,38 @@ #include "string.h" /** @file string.c - * @brief Implements String type. + * @brief Implements string functions. */ /** @addtogroup string String Functions * * @{ */ -/** Initialize a String for our use. - * This grabs one of the global Strings for our temporary use. +/** Sprintf into a string. + * Like printf, except output goes into a string. * - * @param num Number of the preallocated String to use. - * #STP_NUM_STRINGS are statically allocated for our use. The - * translator (or author) should be sure to grab a free one. - * @returns An empty String. - */ - -String _stp_string_init (int num) -{ - String str; - - if (num >= STP_NUM_STRINGS || num < 0) { - _stp_error ("_stp_string_init internal error: requested string exceeded allocated number or was negative"); - return NULL; - } - str = &_stp_string[num][smp_processor_id()]; - str->len = 0; - str->buf[0] = 0; - return str; -} - - -/** Sprintf into a String. - * Like printf, except output goes into a String. - * Safe because overflowing the buffer is not allowed. - * Size is limited by length of String, #STP_STRING_SIZE. - * - * @param str String + * @param str string * @param fmt A printf-style format string followed by a * variable number of args. */ -void _stp_sprintf (String str, const char *fmt, ...) -{ - int num; - va_list args; - if (str == _stp_stdout) { - _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); - char *buf = pb->buf + pb->len; - int size = STP_BUFFER_SIZE - pb->len; - va_start(args, fmt); - num = _stp_vsnprintf(buf, size, fmt, args); - va_end(args); - if (unlikely(num >= size)) { - /* overflowed the buffer */ - if (pb->len == 0) { - /* A single print request exceeded the buffer size. */ - /* Should not be possible with Systemtap-generated code. */ - pb->len = STP_BUFFER_SIZE; - _stp_print_flush(); - num = 0; - } else { - /* Need more space. Flush the previous contents */ - _stp_print_flush(); - - /* try again */ - va_start(args, fmt); - num = _stp_vsnprintf(pb->buf, STP_BUFFER_SIZE, fmt, args); - va_end(args); - } - } - pb->len += num; - } else { - va_start(args, fmt); - num = _stp_vscnprintf(str->buf + str->len, STP_STRING_SIZE - str->len, fmt, args); - va_end(args); - if (likely(num > 0)) - str->len += num; - } -} - -/** Vsprintf into a String - * Use this if your function already has a va_list. - * You probably want _stp_sprintf(). - */ -void _stp_vsprintf (String str, const char *fmt, va_list args) -{ - int num; - if (str == _stp_stdout) { - _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); - char *buf = pb->buf + pb->len; - int size = STP_BUFFER_SIZE - pb->len; - num = _stp_vsnprintf(buf, size, fmt, args); - if (unlikely(num > size)) { - /* overflowed the buffer */ - if (pb->len == 0) { - /* A single print request exceeded the buffer size. */ - /* Should not be possible with Systemtap-generated code. */ - pb->len = STP_BUFFER_SIZE; - _stp_print_flush(); - num = 0; - } else { - /* Need more space. Flush the previous contents */ - _stp_print_flush(); - - /* try again */ - num = _stp_vsnprintf(pb->buf, STP_BUFFER_SIZE, fmt, args); - } - } - pb->len += num; - } else { - num = _stp_vscnprintf(str->buf + str->len, STP_STRING_SIZE - str->len, fmt, args); - if (num > 0) - str->len += num; - } -} - -/** ConCATenate (append) a C string to a String. - * Like strcat(). - * @param str1 String - * @param str2 C string (char *) - * @sa _stp_string_cat - */ -void _stp_string_cat_cstr (String str1, const char *str2) -{ - int num = strlen (str2); - if (str1 == _stp_stdout) { - _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); - int size = STP_BUFFER_SIZE - pb->len; - if (num > size) { - _stp_print_flush(); - if (num > STP_BUFFER_SIZE) - num = STP_BUFFER_SIZE; - } - memcpy (pb->buf + pb->len, str2, num); - pb->len += num; - } else { - int size = STP_STRING_SIZE - str1->len - 1; - if (num > size) - num = size; - memcpy (str1->buf + str1->len, str2, num); - str1->len += num; - str1->buf[str1->len] = 0; - } -} - -/** ConCATenate (append) a String to a String. - * Like strcat(). - * @param str1 String - * @param str2 String - * @sa _stp_string_cat - */ -void _stp_string_cat_string (String str1, String str2) -{ - if (str2->len) - _stp_string_cat_cstr (str1, str2->buf); -} - -void _stp_string_cat_char (String str1, const char c) +int _stp_snprintf(char *buf, size_t size, const char *fmt, ...) { - if (str1 == _stp_stdout) { - _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); - int size = STP_BUFFER_SIZE - pb->len; - char *buf; + va_list args; + int i; - if (1 >= size) - _stp_print_flush(); - - buf = pb->buf + pb->len; - buf[0] = c; - pb->len ++; - } else { - int size = STP_STRING_SIZE - str1->len - 1; - if (size > 0) { - char *buf = str1->buf + str1->len; - buf[0] = c; - buf[1] = 0; - str1->len ++; - } - } + va_start(args, fmt); + i = _stp_vsnprintf(buf,size,fmt,args); + va_end(args); + return i; } -/** Get a pointer to String's buffer - * For rare cases when a C string is needed and you have a String. - * One example is when you want to print a String with _stp_printf(). - * @param str String - * @returns A C string (char *) - * @note Readonly. Don't write to this pointer or it will mess up - * the internal String state and probably mess up your output or crash something. - */ -char * _stp_string_ptr (String str) +int _stp_vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { - return str->buf; + int i = _stp_vsnprintf(buf,size,fmt,args); + return (i >= size) ? (size - 1) : i; } -/** ConCATenate (append) a String or C string to a String. - * This macro selects the proper function to call. - * @param str1 A String - * @param str2 A String or C string (char *) - * @sa _stp_string_cat_cstr _stp_string_cat_string - */ -#define _stp_string_cat(str1, str2) \ - ({ \ - if (__builtin_types_compatible_p (typeof (str2), char[])) { \ - char *x = (char *)str2; \ - _stp_string_cat_cstr(str1,x); \ - } else { \ - String x = (String)str2; \ - _stp_string_cat_string(str1,x); \ - } \ - }) - /** Return a printable text string. * @@ -244,8 +65,8 @@ void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) const int length = len; char c, *out = outstr; - if (len == 0 || len > STP_STRING_SIZE-1) - len = STP_STRING_SIZE-1; + if (len == 0 || len > MAXSTRINGLEN-1) + len = MAXSTRINGLEN-1; if (quoted) { len -= 2; *out++ = '\"'; diff --git a/runtime/string.h b/runtime/string.h index b4411411..dc7d6592 100644 --- a/runtime/string.h +++ b/runtime/string.h @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * Copyright (C) 2005 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 @@ -9,32 +9,11 @@ #ifndef _STRING_H_ #define _STRING_H_ -/** Maximum string size allowed in Strings */ -#ifndef STP_STRING_SIZE -#define STP_STRING_SIZE 2048 -#endif - -/** Maximum number of strings a probe uses. */ -#ifndef STP_NUM_STRINGS -#define STP_NUM_STRINGS 0 -#endif - -struct string { - int len; - char buf[STP_STRING_SIZE]; -}; - -static struct string _stp_string[STP_NUM_STRINGS][NR_CPUS]; - -typedef struct string *String; - /* set up a special stdout string */ -static struct string __stp_stdout = {.len = 0}; -String _stp_stdout = &__stp_stdout; +static char _stp_stdout[] = "_stdout_"; #define to_oct_digit(c) ((c) + '0') -void _stp_vsprintf (String str, const char *fmt, va_list args); -void _stp_string_cat_char (String str1, const char c); +void _stp_vsprintf (char *str, const char *fmt, va_list args); void _stp_text_str(char *out, char *in, int len, int quoted, int user); #endif /* _STRING_H_ */ diff --git a/runtime/sym.c b/runtime/sym.c index 2a823ca9..1e9de765 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Symbolic Lookup Functions - * Copyright (C) 2005 Red Hat Inc. + * Copyright (C) 2005, 2006, 2007 Red Hat Inc. * Copyright (C) 2006 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -142,14 +142,13 @@ static const char * _stp_kallsyms_lookup ( return NULL; } -/** Write addresses symbolically into a String - * @param str String +/** Print an address symbolically. * @param address The address to lookup. * @note Symbolic lookups should not normally be done within * a probe because it is too time-consuming. Use at module exit time. */ -String _stp_symbol_sprint (String str, unsigned long address) +void _stp_symbol_print (unsigned long address) { char *modname; const char *name; @@ -158,36 +157,17 @@ String _stp_symbol_sprint (String str, unsigned long address) name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf); - _stp_sprintf (str, "%p", (void *)address); + _stp_printf ("%p", (void *)address); if (name) { if (modname) - _stp_sprintf (str, " : %s+%#lx/%#lx [%s]", name, offset, size, modname); + _stp_printf (" : %s+%#lx/%#lx [%s]", name, offset, size, modname); else - _stp_sprintf (str, " : %s+%#lx/%#lx", name, offset, size); + _stp_printf (" : %s+%#lx/%#lx", name, offset, size); } - return str; } - -/** Print addresses symbolically to the print buffer. - * @param address The address to lookup. - * @note Symbolic lookups should not normally be done within - * a probe because it is too time-consuming. Use at module exit time. - */ - -#define _stp_symbol_print(address) _stp_symbol_sprint(_stp_stdout,address) - - -/** Write addresses symbolically into a char buffer - * @param str Destination buffer - * @param len Length of destination buffer - * @param address The address to lookup. - * @note Symbolic lookups should not normally be done within - * a probe because it is too time-consuming. Use at module exit time. - */ - -const char *_stp_symbol_sprint_basic (char *str, size_t len, unsigned long address) +void _stp_symbol_snprint (char *str, size_t len, unsigned long address) { char *modname; const char *name; @@ -195,18 +175,16 @@ const char *_stp_symbol_sprint_basic (char *str, size_t len, unsigned long addre char namebuf[KSYM_NAME_LEN+1]; if (len > KSYM_NAME_LEN) { - name = _stp_kallsyms_lookup(address, &size, &offset, &modname, str); - if (!name) - snprintf(str, len, "%p", (void *)address); + name = _stp_kallsyms_lookup(address, &size, &offset, &modname, str); + if (!name) + snprintf(str, len, "%p", (void *)address); } else { - name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf); - if (name) - strlcpy(str, namebuf, len); - else - snprintf(str, len, "%p", (void *)address); + name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf); + if (name) + strlcpy(str, namebuf, len); + else + snprintf(str, len, "%p", (void *)address); } - - return str; } /** @} */ diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c index 4582ad83..eb47e156 100644 --- a/runtime/vsprintf.c +++ b/runtime/vsprintf.c @@ -427,21 +427,4 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) return str-buf; } -int _stp_vscnprintf(char *buf, size_t size, const char *fmt, va_list args) -{ - int i = vsnprintf(buf,size,fmt,args); - return (i >= size) ? (size - 1) : i; -} - -int _stp_snprintf(char *buf, size_t size, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=_stp_vsnprintf(buf,size,fmt,args); - va_end(args); - return i; -} - #endif /* _VSPRINTF_C_ */ |