在系统运行中,我想查看某个进程的某个变量值,通过输入符号名,自动获得该符号名对应变量地址从而直接读内存得到。请问qnx应该如何设置,才会在加载进程时同时加载保存符号表,并提供了哪些接口读取这些符号表呢。谢谢
在QNX这样的使用MMU进行进程空间保护的系统里,每一个进程都有它独立完整的地址。“变量的地址”只对那个进程有意义,在别的进程里,那个地址完全可能是别的意义。
至于你所提的功能,在IDE的源码调试器里都可以完成。具体步骤可以参考 http://www.qnx.com/developers/docs/6.3.2/ide_en/user_guide/debug.html
谢谢回复。
是的,我们是想知道每个进程的变量地址。然后我们可以在每个进程挂个agent接受消息。我们一般不用IDE,所以想问QNX有没什么可以直接加载每个进程的符号表,并提供API根据符号名获得符号表。我们希望的是直接嵌入到进程获取,而不是先在PC通过二进制工具链得到符号地址表再处理。
如果你在同一进程里面,直接引用变量就可以得到地址啊?另外,如果是动态库的话,还有dlsym()函数可以用。
#include <stdio.h>
int global = 3;
int func(int x)
{
printf("in Func(), x is %d\n", x);
return x;
}
int main(int argc, char **argv)
{
printf("Function 'func' is at address %p\n", func);
printf("Var 'global' is at address %p\n", &global);
func(5);
printf("Function 'printf' is at address %p\n", printf);
return 0;
}
谢谢,我们想要的就是类似于dlsym这种函数。
我们实际上是想实现类似于shell这样的东西,敲入一个变量名,就能获得变量值或者修改等相关操作。因为事先也不知道用户要查询哪个变量,所以也就无法在代码里直接引用变量名,而只能根据传来的名字字串,使用类似dlsym这样的函数来获得地址。
但看dlsym只能适用于dlopen打开的动态库。QNX在启动进程时,是否有机制可以直接加载带符号表的ELF文件并保持符号表,然后提供类似于dlsym这样的函数获得符号地址吗。
可以把dlsym()的第一个参数置为RTLD_DEFAULT,这样可以读任何DLL的变量。(没有经dlopen()打开的也可以)但如果是程序中的变量(不是动态库)却不适用。
QNX的编译用的就是GCC,生成的也是ELF文件。如果你使用 -g 编译的话,变量地址应该就在ELF文件的DEBUG段里。QNX本身不提供这样的工具(除了用gdb),不过,这是标准的DWARF格式,应该在网上可以找得到读取这信息的地址吧。
又重新研究了一下这个问题。你可以在编译时加 -Wl,-E 命令,把所有的符号记录在执行文件里,这样,就可以用dlsym()直接查询了。
$ cat kk.c
#include <stdio.h>
#include <dlfcn.h>
int global = 3;
int main()
{
void *p;
p = dlsym(RTLD_DEFAULT, "printf");
printf("function 'printf' is at %p\n", p);
p = dlsym(RTLD_DEFAULT, "global");
printf("var 'global' is at %p\n", p);
return 0;
}
$ qcc -Wl,-E -o kk kk.c
$ ./kk
function 'printf' is at 80483e8
var 'global' is at 8049630