Liuw's Thinkpad

想要赢就先学会输,想要成功就先学会失败

Archive for the ‘trick’ tag

Xen虚拟机调试的小技巧

without comments

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改一下。

Written by liuw

July 27th, 2011 at 2:04 pm

Posted in Programming

Tagged with , , ,

LD_PRELOAD的trick

without comments

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),但是一般程序是不会检查的。

Author:
<liuw AT liuw DOT name>

Date: 2010-12-18 23:10:43

HTML generated by org-mode 6.33x in emacs 23

Written by liuw

December 18th, 2010 at 11:04 pm

Posted in UNIX-like

Tagged with , ,

通过一次malloc生成char**的方法

without comments

看到类似这样的代码。

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;
}

Written by liuw

April 19th, 2010 at 3:42 pm

container_of

with 3 comments

#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) );})

Written by liuw

December 1st, 2009 at 10:47 pm

Posted in Programming

Tagged with , , ,