总结:一个VS2015混合C和Assembler的解决方案,升级到VS2017或VS2019后调试时不显示汇编代码中的符号)。
[2109 年 10 月:问题已解决,请参阅末尾的注释]。
长细节:
我有一个由 VS 2015 编译器编译的带有 32 位 C 代码的 VS 2015 xxx.sln,以及一个由自定义命令行组装的大型 32 位汇编代码 parlanse0.asm:
parlanse0.asm 属性页
Item Type: Custom Build Tool
Command Line: ml /D SANITYCHECKS="1" /D EVENTBUFFERENABLE="1" /D TESTING="1" /D PROFILE="0" /Sg /Sl132 /Sx /Zd /Zi /c /Cx /coff /Zd /Fl "%(FullPath)"
Outputs: parlanse0.obj;%(Outputs)
Additional Dependencies: <list of MASM include file>
Link Objects: Yes
Treat Output As Content: No
我不确定这是否相关,但这是链接器选项:
/OUT:"Debug\run.exe" /MANIFEST /PROFILE /NXCOMPAT:NO /PDB:"Debug/erun.pdb" /DYNAMICBASE:NO "odbc32.lib" "odbccp32.lib" "netapi32.lib" "iphlpapi.lib" "psapi.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" /LARGEADDRESSAWARE /MACHINE:X86 /SAFESEH:NO /INCREMENTAL:NO /PGD:".\Debug\run.pgd" /SUBSYSTEM:CONSOLE",5.01" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:".\Debug\run.exe.intermediate.manifest" /MAP":.\Debug/run.map" /ORDER:@"RTSCFunctionOrder.txt" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Program Files\Microsoft Platform SDK\Lib" /DELAYLOAD:"iphlpapi.dll" /DELAYLOAD:"comdlg32.dll" /TLBID:1
[如果这是链接器命令行,它从哪里获得它处理的 .obj 文件的名称?]
此解决方案在 VS 2015 下编译/构建/运行良好。
我正在尝试升级到 VS 2017(更新:2019 年 9 月,问题从未解决,所以我只是用 VS 2019 再次尝试......同样的问题)。
升级似乎微不足道:我只是启动了 VS 2017 并将其指向 VS 2015 解决方案文件。显然
没有任何变化,至少我的源代码控制(通过各种 MS 构建文件,如 .sln 看不到任何变化)。神奇的是,几乎一切正常:我可以编译/运行/调试应用程序。
但是,当我在调试器中并尝试“转到源代码”时,汇编源代码不再可见。来自汇编程序的“转到源代码”在 VS 2015 中工作正常。同样,如果在调试期间我选择一个汇编语言源代码行并尝试“转到反汇编”,我会得到一个弹出窗口“无法显示反汇编......那里没有与此位置关联的可执行代码”,这显然是错误的。还有在 VS 2015 下发现的行为。
我需要改变什么?是否有文件描述了不同之处?
[附加:汇编源代码与 .C 源代码位于不同的目录中。这会导致汇编代码的 .sbr 文件在与 C 代码的 .sbr 文件不同的目录中生成。显然,汇编代码 .sbr 没有在构建过程中使用;在其中一个日志文件中,我可以看到 C 代码的所有 .sbr 文件,但不能看到汇编程序的所有 .sbr 文件。
所以这看起来不对。但是,我的理解是 .sbr 文件支持 VisualStudio 标记查找,而不是对象位置到源线映射,所以我认为这是一个红鲱鱼。对象位置到源线图是在哪里产生的?链接器会这样做吗?]
[附加:按照评论中的建议查看另一个答案,我将/DEBUG 选项更改为/DEBUG:FULL 对问题没有明显影响。]
[我找到了一些关于 PDB 文件的文章,以及 C++ 编译器如何按原样“更新”它来编译单个 .cpp (.c?) 文件。 MASM 是否应该生成 PDB 文件?那么... MASM 将如何更新编译器的目标 PDB 文件?]
... 延迟 2 个月后添加 ...
我在汇编代码的反汇编窗口中看到了这一点:
00480107 CC int 3
00480108 CC int 3
RTSAllocate11D_end:
00480109 8D A4 24 00 00 00 00 lea esp,[esp]
00480110 8D A4 24 00 00 00 00 lea esp,[esp]
00480117 8D A4 24 00 00 00 00 lea esp,[esp]
0048011E 8D A4 24 00 00 00 00 lea esp,[esp]
00480125 8D A4 24 00 00 00 00 lea esp,[esp]
0048012C 8D A4 24 00 00 00 00 lea esp,[esp]
00480133 8D A4 24 00 00 00 00 lea esp,[esp]
0048013A 8D 9B 00 00 00 00 lea ebx,[ebx]
allocate_2to1E_bytes:
这些是我的符号,因此它们显然正在进入调试器。我要求反汇编窗口显示行号......它什么也不做。所以不知何故,符号正在通过,但不是行号信息,也可能不是源文件位置。想法?
编辑:2019 年 10 月 9 日:问题已解决。 与 Microsoft 的长时间交互使他们同意这是调试器中的问题。我确认 VS 2015 Update 1 是最后一个运行正常的版本; VS 2015 Update 2 及更高版本、VS 2017 和 VS 2019 都遇到同样的问题。 MS 告诉我,他们已经确定了问题,并且将在 2019 年 12 月的 VS 2019 v16.4 公开版本中提供修复程序。
最佳答案
要获得调试信息(在 pdb 文件中)需要 2 个步骤:
编译器这是 /Zd选项
获取调试信息(存储在
.debug$S
obj/lib 文件的部分中)和创建 pdb 文件
如果编译器和链接器的命令行都正确(有这个选项)需要按以下顺序检查:
文件中存在源代码 asm 文件名。只需搜索
PARLANSE0.ASM
(或您的源文件如何命名)在文件中(所有名称存储为 ansi 纯文本) - 是否找到此名称是路径
是正确的 ?如果是 - 这意味着编译器(在我们的例子中为 ml 所有
正确,我们可以继续前进)
.pdb
- 完整(且正确)的路径你的 pdb 存在于 exe 文件中吗?它再次存储为普通ansi
正文
去源码。为了便于检查,您甚至可以制作特殊的临时
build - 在转到汇编代码之前设置断点(或直接在某些汇编代码中
过程)并在 exe 的最开始调用这个过程。即使
这个逻辑上的“不正确” - 我们只需要检查 - 是调试器
了解 pdb 格式并可以显示 asm 的源代码
如果 windbg 可以转到 asm 源代码 - 这意味着集成的 vs2017 调试器存在一些问题。如果windbg不能 - 生成的pdb格式的一些问题
关于winapi - 如何将 Win32 C + MASM "solution"从 Visual Studio 2015 升级到 VS 2017/2019,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44937125/