VC 2015 调用栈查看主函数调用详情的设置

简介: VC 2015 调用栈查看主函数调用详情的设置

在 C 和 C++ 的教科书中会告诉程序员,main 函数是程序的入口函数。这个在初学 C 或 C++ 的时候并没有被怀疑过,因为每个 C 或 C++ 程序都会有一个 main 函数。

其实在进入 main 函数前,操作系统、编译器等已经做了很多工作了。只要在 VC 中,通过调用栈就可以看到相关一些内容。这里使用 VC 2015 来进行简单的演示。

用 VC 2015 创建一个控制台的程序,代码如下:

#include <stdio.h>intmain()
{
printf("Hello World\r\n");
return0;
}

其实代码是什么无所谓,只要这里有一行代码即可。

有了上面的代码后,按下 F10 键,进入调试状态。通过CTRL + ALT + C 打开调用窗口,调用窗口如下所示。

1111.png

可以看到,此时调用栈的栈顶是 main 函数,也就是我们的代码当中。通过调用栈可以看到,在 main 函数上面还有 “外部代码”,还有一个没有 kernel32.dll 符号的提示。这样已经可以看出,在 main 函数之前肯定是有相关的代码已经被执行了。那么,如果能看到更详细的信息呢?

在调用栈窗口上单击右键,在弹出的菜单上选择 “显示外部代码”,在调用栈窗口中就会把 “外部代码” 显示出来,如下图所示。

2222.png

33333.png

从上图可以看到,刚刚显示 “外部代码” 的部分已经被具体的方法替换了,分别是 invoke_main()、__scrt_common_main_seh()、__scrt_common_main() 和 mainCRTStartup() 四个函数。它们的调用关系是从下往上的。

mainCRTStartup() 函数是由 kernel32.dll 的 76bffa29() 的函数调用的,而且在这个函数之前还有 ntdll.dll 的函数被调用了。那么这里是否可以显示呢?也是可以显示的。

这里在 kernel32.dll!76bffa29() 上单击右键,在弹出的菜单上选择 “加载符号”,如下图所示。

4444.png

5555.png

然后会出现一个加载符号文件的提示,耐心等待一下,然后再观察调用栈的信息,如下图。

66666.png

可以看到,kernel32.dll!@BaseThreadInitThunk@12() 已经被显示出来了,继续在 ntdll.dll 上进行加载,都加载完后的调用栈显示如下:

77777.png

可以看到,调用栈中的调用关系的显示也都完整了。

到此,我们可以看出,在进入 main 函数之前,经历了 ntdll.dll 中的 __RtlUserThreadStart@8() 和 __RtlUserThreadStart() 函数,到了 kernel32.dll 中的 BaseThreadInitThunk@12() 函数,然后到了当前 exe 文件的启动函数 mainCRTStartup() 函数,在启动函数中调用了 __scrt_common_main()、__scrt_common_main_seh()、invoke_main() 后调用到了程序员编写的 main() 函数处,也就是程序员的入口函数处。


最后,我们可以在菜单中选择 调试 -> 选项,在弹出的设置框中选择 调试 -> 符号 来进行设置,设置如下图所示。

888888.png

所有的 pdb 文件,也就是符号文件都下载到了 SymbolCache 目录中了,这个目录是 VS 为我们提供的一个默认的目录。

相关文章
|
数据建模 C++ 容器
调试实战 —— dll 加载失败之全局变量初始化篇
调试实战 —— dll 加载失败之全局变量初始化篇
|
8月前
LabVIEW使用调用节点与通过引用调用节点调用VI时的差别
LabVIEW使用调用节点与通过引用调用节点调用VI时的差别
139 1
|
8月前
LabVIEW调用库函数节点无法显示DLL中的函数
LabVIEW调用库函数节点无法显示DLL中的函数
58 0
|
关系型数据库 MySQL Go
[Golang]存在调用同一个包内某个结构体的方法出错?可能是未初始化结构体
[Golang]存在调用同一个包内某个结构体的方法出错?可能是未初始化结构体
|
Java Linux Android开发
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
253 0
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
|
存储 Android开发
【Android 应用开发】Activity 返回堆栈管理 ( 阶段总结 | 任务栈管理 | 返回堆栈 | 清除返回堆栈 | 亲和性 | 启动模式补充 | standard | singleTop )
【Android 应用开发】Activity 返回堆栈管理 ( 阶段总结 | 任务栈管理 | 返回堆栈 | 清除返回堆栈 | 亲和性 | 启动模式补充 | standard | singleTop )
375 0
|
Android开发 开发者
【Android 应用开发】Activity 返回堆栈清除操作 ( 默认状态 | 清除返回堆栈配置 | 不清除返回堆栈配置 | 清除指定界面配置 )
【Android 应用开发】Activity 返回堆栈清除操作 ( 默认状态 | 清除返回堆栈配置 | 不清除返回堆栈配置 | 清除指定界面配置 )
490 0
Qt-调用CAN开发包时,显示无法找到调用函数
说先,对下错误,免得看半天发现说的不是一个东西
426 0

热门文章

最新文章