Archive for the ‘trick’ tag
Xen虚拟机调试的小技巧
1. xenctx分析上下文
在VM的配置文件中加入
on_reboot="preserve" on_crash="preserve"
等配置。出问题之后可以用xenctx取得VM的上下文。
2. 调试QEMU
在VM配置文件中使用device_model_override指定一个脚本作为DM,这个DM中包括如下的语句
echo $@ > /tmp/qemu-dm sleep 1h
然后再手动用gdb启动QEMU后端。注意xl有一个timeout,所以动作要够快。或者自己把xl的timeout改一下。
LD_PRELOAD的trick
ld.so(8)在为程序加载动态库时,会根据很多不同的环境变量而有不同的表现。这里关注一个LD_PRELOAD的环境变量,此环境变量指定的动态库可以优先于所有其他的动态库加载。
优先加载的动态库中的symbol会override后加载的symbol,所以LD_PRELOAD有一个比较好用的trick就是把一些程序中用的函数替换成自己的版本。
例如,要把malloc和free替换成为自己的实现,可以用:
$ LD_PRELOAD="path/to/my/malloc.so" program
据目前得到的资料来看,一些memory leak检测库、以及一些改进libc函数的库就是这样做的。
但是这个trick也有一定的安全隐患,一些关键函数被恶意、隐式地替换的话,可以想像后果有多严重,所以正常情况下是不推荐使用的。虽然对于setgid/setuid程序有一定的安全防范措施(For setuid/setgid ELF binaries, only libraries in the standard search directories that are also setgid will be loaded),但是一般程序是不会检查的。
Date: 2010-12-18 23:10:43
HTML generated by org-mode 6.33x in emacs 23
通过一次malloc生成char**的方法
看到类似这样的代码。
char **arr; int len; arr = produce_array(&len); /* 此时生成了有len个元素的含有内容的数组。用一次free来释放? */ free(arr);
原来看到free()那里,觉得会有问题,我的想法是要为每一个char *分别malloc内存,所以需要有len次free。其实不然,C语言太灵活了,不要被自己原来固有的想法束缚了才好。完全可以通过一次malloc申请到所有的空间,再活用这些空间。
/* 设有 n 个以 NULL 结尾的字符串放在 data 中,它们的总长为 dlen */
char **produce_array(int *len)
{
char **ret;
int i;
*len = n;
ret = malloc(sizeof(char *) * n + dlen);
ret[0] = (char *)(ret + n);
memcpy(ret[0], data, dlen);
for (i = 1; i < n; i++)
ret[i] = ret[i-1] + strlen(ret[i-1]) + 1;
return ret;
}
container_of
#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n))
再来看看Linux Kernel中的实现。
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})