在余老大(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.
分享到:
相关推荐
C++高效获取函数调用堆栈 在程序设计和开发过程中,出现问题是很正常的。这时候,快速找到问题所在,并确定程序的上下文环境就变得非常重要。函数调用堆栈的信息对于解决问题具有很大的帮助。传统的方法是使用 ...
这些函数需要一个lua_State指针和两个字符串参数,分别代表函数名和对应的C++函数指针。 4. **C++函数处理Lua栈**:Lua的所有数据都存储在一个虚拟栈上,C++函数需要通过`lua_gettop`检查栈顶元素,`lua_...
本节通过代码实例分析函数调用过程中栈帧的布局、形成和消亡。示例代码如下:该程序每个函数都嵌入汇编代码,以获取各函数运行时刻EBP和ESP寄存器的值。每个函数都打印出EBP寄存器所指向内存地址处的值,以及位于其...
调用堆栈,也称为运行时堆栈或函数调用栈,是程序执行过程中存储函数调用信息的数据结构。每次函数调用都会在堆栈上分配空间,保存返回地址、参数和局部变量等信息。当函数返回时,这些信息会被释放,以便为新的函数...
C语言中的函数调用是通过函数名和参数列表来实现的。函数调用是C语言中的一种基本机制,允许我们将一段代码分割成小块,以便于代码的重用和维护。下面我们将详细解释C语言函数调用的机制和步骤。 一、函数定义 在...
在C++builder中,__cdecl的函数输出前会带:"_",__stdcall无特征,只输出函数名,__fastcall函数输出前带:"@"。在VC中,__cdecl无特征,只输出函数名,__stdcall的函数输出前会带:"_",__fastcall函数输出前带:...
例如,上述提供的getFunctionName函数可以通过正则表达式来提取函数名,然后通过一个循环来递归查找每一个调用者,并将它们的名称添加到stack数组中,最后使用alert显示这个数组。这样,即使在没有内置trace方法的...
- 函数名可以传递给其他函数作为参数,通过函数指针变量可以在被调用函数中调用不同的实参函数。 - **示例代码**: ```c++ void process(int data, void (*func)(int)) { func(data); } void print(int data)...
要在Android代码中打印函数名和行号,通常可以使用`Log`类的`d()`方法,并结合`new Exception().getStackTrace()[2]`来获取当前调用栈的第二层信息(因为第一层通常是`getStackTrace()`本身)。例如: ```java try ...
栈回溯(Stack Tracing)是通过分析程序的调用栈来获取函数调用序列的过程。当程序出现异常或者错误时,栈回溯能提供一个清晰的调用路径,显示导致当前状态的所有函数调用。这对于诊断错误的起源、理解程序执行流程...
- 程序中定义了一个名为`Data`的结构体,用于表示栈。其中包含两个成员变量:`a[]`用于存储栈内的数据,`len`记录栈的当前长度。 - 结构体`Data`实例化为三个对象:`S`表示待出栈的栈,`R`表示待入栈的栈,`O`表示...
2. **准确性**:由于`StackTrace`是基于运行时的调用栈来获取信息的,因此在某些编译优化场景下(如方法内联),可能会导致获取的行号不准确。 3. **代码维护性**:确保在使用行号信息时,代码结构清晰且易于理解,...
在IT领域,跨语言调用是一个常见的需求,特别是在多种技术栈并存的项目中。本示例中的“MFC调用Python”就是一种这样的实践,它展示了如何在Microsoft Foundation Classes (MFC)的C++环境中调用Python脚本来执行特定...
首先,报告中定义了一个名为`sqstack`的结构体,用来表示一个顺序栈。结构体包含三个成员:`base`指向栈底的指针,`top`指向栈顶元素的指针,以及`stacksize`表示栈当前的容量。`StackInit`函数用于初始化栈,分配...
在C语言中,当一个函数调用结束后,程序会跳转到存储在栈上的返回地址继续执行。这个地址通常位于调用函数的栈帧中,是函数返回后的下一条指令的内存地址。攻击者可以通过溢出输入数据填充栈空间,覆盖这个返回地址...
在实际应用中,栈广泛用于表达式求值、括号匹配、递归调用、内存管理等多种场景。本话题将重点讨论如何建立栈以及如何实现栈的逆置。 首先,我们要理解如何建立一个栈。在C++编程语言中,可以使用STL(Standard ...
在提供的代码示例中,我们看到两个函数,`stripslashes_deep` 和 `...因此,必须确保仅对已知和安全的函数进行递归调用,避免使用用户提供的函数名。同时,对输入数据进行充分的验证和清理也是防止安全漏洞的关键。
由于这个例子中的对象是在栈上分配的,析构函数会在`main`函数执行完毕后自动调用。如果对象是动态分配的,则需要显式地调用`delete`来触发析构函数。 #### 使用场景 构造函数和析构函数的应用非常广泛,尤其是在...
函数定义通常包括函数类型、函数名和参数列表。例如,一个简单的求和函数定义如下: ```c int sum(int n1, int n2) { return n1 + n2; } ``` 8.2.2 函数的返回值与函数类型 函数可以通过`return`语句返回一个值。`...