valgrind作为一个检测内存泄露,同步或者互斥异常的利器,广泛被人们使用,接下来简单分析一下valgrind启动过程:
valgrind启动不同于一般的C程序,有一个main函数,而直接采用的是_start标签,因为GCC在编译的时候可以不去链接main函数,而通过-nostartfiles选项来说明不去链接main函数,也就是启动不从main函数开始,此时GCC默认会去链接_start标签,而valgrind正是从这个标签开始执行的。
_start:
........
call _start_in_C_linux
....
在_start中主要做了一些堆栈的建立,因为C的调用需要堆栈的支持!接着调用了_start_in_C_linux函数,进入了C的天下:
-
void _start_in_C_linux ( UWord* pArgc );
-
__attribute__ ((used))
-
void _start_in_C_linux ( UWord* pArgc )
-
{
-
Int r;
-
Word argc = pArgc[0];//编译器在调用_start之前,将传入的参数以及环境变量储存在某一个连续的位置,通过eax传递给了_start,接着start又传递给了pArgc变量
-
HChar** argv = (HChar**)&pArgc[1]; //进行参数的提取
-
HChar** envp = (HChar**)&pArgc[1+argc+1]; //进行环境变量的提取
-
-
VG_(memset)( &the_iicii, 0, sizeof(the_iicii) ); //初始化结构体
-
VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
-
-
the_iicii.sp_at_startup = (Addr)pArgc; //堆栈的位置
-
-
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) //如果是power pc,还需要配置不同的页尺寸
-
{
-
/* ppc/ppc64 can be configured with different page sizes.
-
Determine this early. This is an ugly hack and really should
-
be moved into valgrind_main. */
-
UWord *sp = &pArgc[1+argc+1];
-
while (*sp++ != 0)
-
;
-
for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
-
if (*sp == AT_PAGESZ) {
-
VKI_PAGE_SIZE = sp[1];
-
for (VKI_PAGE_SHIFT = 12;
-
VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
-
if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
-
break;
-
}
-
}
-
# endif
-
-
r = valgrind_main( (Int)argc, argv, envp ); //接着就进入了valgrind_main,看起来这个就像是我们常说的main函数了。
-
/* NOTREACHED */
-
VG_(exit)(r);
-
}
valgrind_main中,进行了各种初始化,接下的文章会详细讲解。
阅读(1239) | 评论(0) | 转发(0) |