在余老大(http://blog.yufeng.info/)的指引下开始学习SystemTap了。
最近要追查MySQL中一个耗时函数的调用栈,刚好用到这个神器。在1.3版本中自带的tapset中有 print_ubacktrace 和 sprint_ubacktrace 这两个函数。输出的格式是 “函数名+地址 [进程名]“。 为了得到函数名,要作字符串处理。
早上在tapset中发现了另外一个函数print_ubacktrace_brief, 输出格式是 “函数名+地址”。
因此想到如果能有个函数只输出函数名就好了,依葫芦画瓢可以自定义函数如下。
function sprint_ubacktrace_func () %{
/* unprivileged */ /* pragma:uprobes */ /* pragma:vma */
assert_is_myproc();
/* use task_pt_regs, CONTEXT->regs might be kernel regs, or not set. */
if (current->mm)
{
struct pt_regs *uregs;
int valid;
if (CONTEXT->regs && (CONTEXT->regflags & _STP_REGS_USER_FLAG))
{
uregs = CONTEXT->regs;
valid = 1;
}
else
{
uregs = task_pt_regs(current);
valid = _stp_task_pt_regs_valid(current, uregs);
}
if (uregs)
{
_stp_stack_sprint (THIS->__retvalue, MAXSTRINGLEN, _STP_SYM_SYMBOL|_STP_SYM_POST_SPACE,
uregs, CONTEXT->pi, MAXTRACE,
current, CONTEXT->ri, valid);
return;
}
}
strlcpy (THIS->__retvalue, "", MAXSTRINGLEN);
%}
其实重点就是_stp_stack_sprint函数的第三个参数,自己定义不同的宏有不同的效果。简单例子中进程ex_stack调用顺序为 main -> p1 -> p2 -> p3 -> p4,则在 process(“ex_stack”).function(“p4”).call 中调用上面这个函数,返回值为
" p4 p3 p2 p1 main xxxx(空格隔开)"
直接显示省了字符串处理J
另外,脚本中使用这函数的话,记得带-g.
5032

被折叠的 条评论
为什么被折叠?



