我有一个系统点击脚本来探测内核函数"memcpy“。我想根据src缓冲区的内容打印堆栈跟踪,src缓冲区是一个空指针。
我的代码:
%{
#include <linux/string.h>
%}
probe begin
{
printf("Begin\n");
}
probe kernel.function("memcpy")
{
buffer = @cast($src, "char");
if (isinstr(buffer, "some pattern") != NULL) {
printf("Found\n");
print_backtrace();
}
}当我运行脚本时,这个脚本会给我一个错误:"stap -g stacktrace.stp“
未解析的目标-符号表达式:标识符'$src‘ 语义错误:类型不匹配(字符串):stacktrace.stp:31:14的标识符‘缓冲器’ 来源: if (isinstr(缓冲区,"shubham") != NULL) {^ 语义错误:类型是第一次推断在这里(长):标识符‘缓冲器’在:30:2 来源: buffer = @cast($src,"char");^ 通过2:分析失败。人为错误::pass2
我在linux内核代码中看到了memcpy的函数定义,该参数仅命名为src。无法解析变量名。我试过不同的名字-- $src,$from,$s,但是都没有用。
机器的内核版本是: 3.10.0-514.el7.x86_64 (RHEL7.3 (Maipo))
它上安装了以下内核包:
发布于 2019-02-28 08:12:25
更新2:
buffer = @cast($src, "char");那应该是字符指针而不是字符吗?
更新1:来自系统开发文档
语义错误:未解析的目标符号表达式
在无法解析的探测处理程序中引用了一个目标变量。或者,目标变量在脚本函数等上下文中根本无效。这个变量可能是由优化编译器省略的,或者没有合适的类型,或者只是某个地方有一个恼人的bug。使用稍微不同的探测点再试一次(使用语句()而不是函数())在同一区域搜索更协作的邻居。
原始漫谈
变量作为一种友好的东西被称为src的概念只存在于人类可读的源代码中。看看你的密码。您还没有声明任何名为src的变量。
我在linux内核代码中看到了memcpy的函数定义,参数命名为src。
是的,但这又一次是为了人类的利益。
您缺少的部分是,当将源代码编译到应用程序中时,编译器会整理我们所有的人工构造,并将它们转换为堆栈偏移量。
警告:为了简单起见,我完全忽略了函数调用约定。
如果您查看编译后的二进制文件,对于您的平台,您可以看到一些更好的提示,说明您需要做什么。假设您使用的是x86系统,您将看到如下所示:
memcpy:
push ebp
mov ebp, esp
sub esp, 8
// The function body starts here and you will see references
// to what we recognize as the variable "src" with an instructions like
mov edi, esp+0
// That just loaded the EDI register with a reference to the location of src您可以使用gdb查看平台的程序集。
发布于 2020-02-01 04:57:50
gcc在内核中的首次亮相可能不一致,因为它在使用的每个地方都为memcpy的内联副本保留了形式参数。
stap -vL 'kernel.function("memcpy").*'应列出所有网站的个人或摘要。机会就像
stap -e '
probe kernel.function("memcpy")
{ if (@defined($p) && @defined($q)) println($p, " ", $q) }'可能会起作用。它只会在定义了这两个参数的探测位置中触发println。在我最近的内核中,人们看到了类似于.
kernel.function("memcpy@./include/linux/string.h:347").inline /* pc=_stext+0x68c6a */ $q:void const* $p:void*
kernel.function("memcpy@./include/linux/string.h:347").inline /* pc=_stext+0x178ec */ $size:__kernel_size_t $p:void*
kernel.function("memcpy@./include/linux/string.h:347").inline /* pc=_stext+0x15a31 */ $size:__kernel_size_t $q:void const* $p:void*
kernel.function("memcpy@./include/linux/string.h:347").inline /* pc=_stext+0x13f1f */ $size:__kernel_size_t $q:void const* $p:void* $p_size:size_t $q_size:size_t
kernel.function("memcpy@./include/linux/string.h:347").inline /* pc=_stext+0xc717 */ $size:__kernel_size_t $q:void const* $p:void* $p_size:size_t $q_size:size_t..。所以stap代码必须容忍这种情况。
https://stackoverflow.com/questions/54759504
复制相似问题