* What's new in version 1.4
+- The print_ubacktrace and usym* functions attempt to print the full
+ path of the user-space binaries' paths, instead of just the basename.
+ The maximum saved path length is set by -DTASK_FINDER_VMA_ENTRY_PATHLEN,
+ default 64.
+
- The new tz_ctime() tapset function prints times in the local time zone.
- More kernel tracepoints are accessible to the kernel.trace("...") mechanism,
if (flags & (_STP_SYM_SYMBOL | _STP_SYM_MODULE))
name = _stp_kallsyms_lookup(address, &size, &offset, &modname, task);
+ if (modname && (flags & _STP_SYM_MODULE_BASENAME)) {
+ modname = strrchr (modname, '/') ?: modname;
+ }
+
if (name && (flags & _STP_SYM_SYMBOL)) {
if ((flags & _STP_SYM_MODULE) && modname && *modname) {
if (flags & _STP_SYM_OFFSET) {
#define _STP_SYM_POST_SPACE 128
/* Adds a newline character, doesn't combine with _STP_SYM_POST_SPACE. */
#define _STP_SYM_NEWLINE 256
+/* Adds only module " [`basename name`]" if found, use with _STP_SYM_MODULE. */
+#define _STP_SYM_MODULE_BASENAME 512
/* Used for backtraces in hex string form. */
#define _STP_SYM_NONE (_STP_SYM_HEXSTR | _STP_SYM_POST_SPACE)
| _STP_SYM_SIZE | _STP_SYM_PRE_SPACE \
| _STP_SYM_NEWLINE)
/* Simple symbol format, as used in backtraces for strings. */
-#define _STP_SYM_SIMPLE (_STP_SYM_SYMBOL | _STP_SYM_MODULE \
+#define _STP_SYM_SIMPLE (_STP_SYM_SYMBOL | _STP_SYM_MODULE | _STP_SYM_MODULE_BASENAME \
| _STP_SYM_OFFSET | _STP_SYM_NEWLINE)
/* All symbol information (as used by [u]symdata). */
#define _STP_SYM_DATA (_STP_SYM_SYMBOL | _STP_SYM_MODULE \
#define TASK_FINDER_VMA_ENTRY_ITEMS 1536
#endif
+#ifndef TASK_FINDER_VMA_ENTRY_PATHLEN
+#define TASK_FINDER_VMA_ENTRY_PATHLEN 64
+#elif TASK_FINDER_VMA_ENTRY_PATHLEN < 8
+#error "gimme a little more TASK_FINDER_VMA_ENTRY_PATHLEN"
+#endif
+
+
struct __stp_tf_vma_entry {
struct hlist_node hlist;
pid_t pid;
unsigned long vm_start;
unsigned long vm_end;
- const char *name;
+ char path[TASK_FINDER_VMA_ENTRY_PATHLEN]; /* mmpath name, if known */
// User data (possibly stp_module)
void *user;
static int
stap_add_vma_map_info(struct task_struct *tsk,
unsigned long vm_start, unsigned long vm_end,
- const char *name, void *user)
+ const char *path, void *user)
{
struct hlist_head *head;
struct hlist_node *node;
entry->pid = tsk->pid;
entry->vm_start = vm_start;
entry->vm_end = vm_end;
- entry->name = name;
+ if (strlen(path) >= TASK_FINDER_VMA_ENTRY_PATHLEN-3)
+ {
+ strncpy (entry->path, "...", TASK_FINDER_VMA_ENTRY_PATHLEN);
+ strlcpy (entry->path+3, &path[strlen(path)-TASK_FINDER_VMA_ENTRY_PATHLEN+4],
+ TASK_FINDER_VMA_ENTRY_PATHLEN-3);
+ }
+ else
+ {
+ strlcpy (entry->path, path, TASK_FINDER_VMA_ENTRY_PATHLEN);
+ }
entry->user = user;
head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
static int
stap_find_vma_map_info(struct task_struct *tsk, unsigned long addr,
unsigned long *vm_start, unsigned long *vm_end,
- const char **name, void **user)
+ const char **path, void **user)
{
struct hlist_head *head;
struct hlist_node *node;
*vm_start = found_entry->vm_start;
if (vm_end != NULL)
*vm_end = found_entry->vm_end;
- if (name != NULL)
- *name = found_entry->name;
+ if (path != NULL)
+ *path = found_entry->path;
if (user != NULL)
*user = found_entry->user;
rc = 0;
static int
stap_find_vma_map_info_user(struct task_struct *tsk, void *user,
unsigned long *vm_start, unsigned long *vm_end,
- const char **name)
+ const char **path)
{
struct hlist_head *head;
struct hlist_node *node;
*vm_start = found_entry->vm_start;
if (vm_end != NULL)
*vm_end = found_entry->vm_end;
- if (name != NULL)
- *name = found_entry->name;
+ if (path != NULL)
+ *path = found_entry->path;
rc = 0;
}
read_unlock_irqrestore(&__stp_tf_vma_lock, flags);
int i, res;
struct _stp_module *module = NULL;
const char *name = (dentry != NULL) ? dentry->d_name.name : NULL;
+
+ if (path == NULL || *path == '\0') /* unknown? */
+ path = (char *)name; /* we'll copy this soon, in ..._add_vma_... */
#ifdef DEBUG_TASK_FINDER_VMA
_stp_dbug(__FUNCTION__, __LINE__,
atm. */
res = stap_add_vma_map_info(tsk->group_leader,
addr, addr + length,
- name, module);
+ path, module);
/* Warn, but don't error out. */
if (res != 0) {
_stp_warn ("Couldn't register module '%s' for pid %d (%d)\n", _stp_modules[i]->path, tsk->group_leader->pid, res);
|| _stp_target == tsk->group_leader->pid)
{
res = stap_add_vma_map_info(tsk->group_leader, addr,
- addr + length, name, NULL);
+ addr + length, path, NULL);
#ifdef DEBUG_TASK_FINDER_VMA
_stp_dbug(__FUNCTION__, __LINE__,
"registered '%s' for %d (res:%d)\n",
- name, tsk->group_leader->pid,
+ path, tsk->group_leader->pid,
res);
#endif
}
}
}
-set output "handler: main_handler ($testexename)
-handler: lib_handler (lib${testlibname}.so)"
+set output "handler: main_handler ([pwd]/$testexename)
+handler: lib_handler ([pwd]/lib${testlibname}.so)"
# Used to need to run stap with both the exe and the libraries used as -d args.
# Now use --ldd to pick up both exe and the library we just linked in.