如何删除警告 LNK4099:未找到 PDB 'lib.pdb' [英] How to remove warning LNK4099: PDB 'lib.pdb' was not found

查看:50
本文介绍了如何删除警告 LNK4099:未找到 PDB 'lib.pdb'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在静态编译的链接阶段在 Windows 上构建时可能会出现 LNK4099 警告.

例如使用 nmake 和 VC10 构建时,我收到一连串 LNK4099 警告,例如:

libcurl_a_debug.lib(rc2_cbc.obj) : 警告 LNK4099: 没有找到 PDB 'lib.pdb' 和 'libcurl_a_debug.lib(rc2_cbc.obj)' 或在 'C:devscalercenterdluxlib.pdb';链接对象就好像没有调试信息一样

StackOverflow 提供了对问题的良好概述,但没有提供理解问题所需的细节.

而不是忽略警告禁用警告,我想修复构建中的 makefile 以消除问题.

问题是怎么产生的?如何消除警告的原因?

解决方案

了解潜在问题是警告中提到的库缺少调试符号文件 (.pdb).库文件包含基于对象文件的对 .pdb 的静态引用.当一个库被另一个库使用并使用静态编译时,Visual Studio 将所有符号收集到一个 .pdb 中,并更新对象文件中的 .pdb 引用.但是,如果它找不到符号,它将保留旧路径.

通过重新编译警告中提到的库来修复警告,并确保编译器可以访问每个引用库的 .pdb.这涉及确定无法找到哪个 .pdb 文件,然后进行更改以确保可以找到 .pdb.

我们缺少哪个目标文件(以及库)的符号 (.pdb)?

@goth 提供了一个博客链接,解释了 .pdb 引用的来源,但这是我的总结:>

一个库包含许多目标文件.每个目标文件都包含调试符号的路径.我们可以使用工具提取这些信息.根据目标文件和路径,我们可以找出找不到哪个调试符号文件(.pdb).

  1. 打开 Visual Studio 命令提示符.这将创建一个带有访问 Visual Studio 工具所需的环境变量的命令外壳.(应该在埋在开始菜单中的Visual Studio 工具"下,但这会有所不同)

  2. 使用lib 工具的/list 选项获取库中目标文件的内部路径.例如

C:devlibcurlwinlib>lib/list libcurl_a_debug.lib >list_of_object_files_in_library.txtC:devscalercenteragent	hirdpartylibcurlwinlib>more list_of_object_files_in_library.txtMicrosoft (R) 库管理器版本 10.00.40219.01版权所有 (C) 微软公司.版权所有...uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/file.obj..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/rc2_cbc.obj...

  1. 使用路径,使用 lib 工具的 /extract 选项提取目标文件.

C:devscalercenteragent	hirdpartylibcurlwinlib>lib/extract:..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj libcurl_a_debug.libMicrosoft (R) 库管理器版本 10.00.40219.01版权所有 (C) 微软公司.版权所有.

  1. 目标文件包含一个名为 .debug$T 的调试部分,我们可以使用 dumpbin 工具提取该部分.例如

C:devscalercenteragent	hirdpartylibcurlwinlib>dumpbin/section:.debug$T/rawdata rc2_cbc.obj >dump_of_object_file_debug_info.txtC:devscalercenteragent	hirdpartylibcurlwinlib>more dump_of_object_file_debug_info.txtMicrosoft (R) COFF/PE Dumper 版本 10.00.40219.01版权所有 (C) 微软公司.版权所有.转储文件 ./rc2_cbc.obj文件类型:COFF 对象部分标题 #9.debug$T 名称0 物理地址0 虚拟地址5C大小的原始数据1D53 指向原始数据的文件指针(00001D53 到 00001DAE)0 指向重定位表的文件指针0 指向行号的文件指针0 次搬迁0 行号数42100040 标志初始化数据可丢弃1 字节对齐只读原始数据 #900000000: 04 00 00 56 00 15 15 03 7A 47 A3 3D 4A 8C 4B ....V....zGú=J.K00000010: A2 A5 26 D3 D6 57 15 46 3A 00 00 00 73 3A 5C 73 óÑ&ËÍW.F:...s:s00000020: 63 61 6C 65 78 2E 6E 65 77 5C 63 65 6E 74 72 6F caler.newcenter00000030: 5C 6F 70 65 6E 73 73 6C 5C 62 75 69 6C 64 5C 6F openssluildo00000040: 70 65 6E 73 73 6C 2D 31 2E 30 2E 30 62 5C 74 6D penssl-1.0.0b	m00000050:70 33 32 5C 6C 69 62 2E 70 64 62 00 p32lib.pdb.概括5C .debug$T

在上面,您会看到目标文件显示其调试符号 s:scaler.newcenteropenssluildopenssl-1.0.0b mp32lib.pdb.因此,问题在于我们构建libcurl使用的openssl库时生成的.pdb.

如何将调试符号添加到生成警告的库中?

/Fd 选项控制 .pdb 符号文件的名称和位置.例如.编译 libcurl 时,我使用了以下标志:

...!如果定义(VC10)NT_MAK_FLAGS = APP_CFLAG="/GX/GZ/MTd/Fdtmp32.dbg/app" LIB_CFLAG="/Zl/Z7/Fdtmp32.dbg/lib"!万一...

lib.pdb 的符号文件名及其相对于构建的路径由 /Fdtmp32.dbg/lib 给出.

问题是 NT_MAK_FLAGS 被重用于编译 openssl 时生成的许多库.结果,除了最后一个库之外,所有lib.pdb 都被破坏(覆盖).要解决此问题,应为每个库提供具有唯一名称的 .pdb.为了进一步简化问题,请确保编译位置与 libcurl 构建位于同一树中.

LNK4099 warnings can occur when building on Windows during the link phase of a static compilation.

E.g. when building using nmake and VC10 I get a stream of LNK4099 warnings like:

libcurl_a_debug.lib(rc2_cbc.obj) : warning LNK4099: PDB 'lib.pdb' was not found with 'libcurl_a_debug.lib(rc2_cbc.obj)' or at 'C:devscalercenterdluxlib.pdb'; linking object as if no debug info

StackOverflow gives a good overview of the problem, but not the detail required to understand it.

Rather than ignore the warning or disable the warning, I would like to fix the makefiles in my build to remove the problem.

How does the problem arise? How do I remove the cause of the warnings?

解决方案

Understand that the underlying problem is a missing debug symbols file (.pdb) for the library mentioned in the warning. Library files contain a static reference to the .pdb on an object file basis. When a library is used by another library and static compilation is used, Visual Studio collects all the symbols into a single .pdb and the .pdb references in the object files are updated. However, if it cannot find the symbols, it will leave the old path in place.

Fix the warning by recompiling the library mentioned in the warnings, and make sure the compiler has access to the .pdb of every referenced library. This involves determining which .pdb file cannot be found, and then making changes to ensure the .pdb can be found.

Which object file (and thus library) are we missing the symbols (.pdb) for?

@goth provided a blog link explaining where the .pdb reference comes from, but here is my summary:

A library contains a number of object files. Each object file includes a path to the debug symbols. We can use tools extract this information. Based on the object file and path, we can figure out which debug symbols file (.pdb) could not be found.

  1. Open the Visual Studio Command Prompt. This creates a command shell with environment variables required to access Visual Studio tools. (Should be under "Visual Studio Tools" buried in the Start Menu, but this varies)

  2. Obtain the internal path of the object file in the library using the lib tool's /list option. E.g.

C:devlibcurlwinlib>lib /list libcurl_a_debug.lib > list_of_object_files_in_library.txt

C:devscalercenteragent	hirdpartylibcurlwinlib>more list_of_object_files_in_library.txt
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/file.obj
..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj
..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/rc2_cbc.obj

...

  1. Using the path, extract the object file using the lib tool's /extract option.

C:devscalercenteragent	hirdpartylibcurlwinlib>lib /extract:..uildslibcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj libcurl_a_debug.lib
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

  1. The object file contains a debug section called .debug$T that we can extract using the dumpbin tool. E.g.

C:devscalercenteragent	hirdpartylibcurlwinlib>dumpbin /section:.debug$T /rawdata rc2_cbc.obj > dump_of_object_file_debug_info.txt

C:devscalercenteragent	hirdpartylibcurlwinlib>more dump_of_object_file_debug_info.txt
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file ./rc2_cbc.obj

File Type: COFF OBJECT

SECTION HEADER #9
.debug$T name
       0 physical address
       0 virtual address
      5C size of raw data
    1D53 file pointer to raw data (00001D53 to 00001DAE)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42100040 flags
         Initialized Data
         Discardable
         1 byte align
         Read Only

RAW DATA #9
  00000000: 04 00 00 00 56 00 15 15 03 7A 47 A3 3D 4A 8C 4B  ....V....zGú=J.K
  00000010: A2 A5 26 D3 D6 57 15 46 3A 00 00 00 73 3A 5C 73  óÑ&ËÍW.F:...s:s
  00000020: 63 61 6C 65 78 2E 6E 65 77 5C 63 65 6E 74 72 6F  caler.newcenter
  00000030: 5C 6F 70 65 6E 73 73 6C 5C 62 75 69 6C 64 5C 6F  openssluildo
  00000040: 70 65 6E 73 73 6C 2D 31 2E 30 2E 30 62 5C 74 6D  penssl-1.0.0b	m
  00000050: 70 33 32 5C 6C 69 62 2E 70 64 62 00              p32lib.pdb.

  Summary

          5C .debug$T

Above, you see that the object file says its debug symbols s:scaler.newcenteropenssluildopenssl-1.0.0b mp32lib.pdb. Therefore, the problem lies with the .pdb generated when we built the openssl library used by libcurl.

How do I add the debug symbols to the library generating the warning?

The /Fd option governs the name and location of the .pdb symbols file. E.g. when compiling libcurl, I used the following flags:

...
!IF DEFINED(VC10)
NT_MAK_FLAGS = APP_CFLAG="/GX /GZ /MTd /Fdtmp32.dbg/app" LIB_CFLAG="/Zl /Z7 /Fdtmp32.dbg/lib"
!ENDIF
...

The symbol file name of lib.pdb and its path relative to the build is given by /Fdtmp32.dbg/lib.

The problem is that the NT_MAK_FLAGS is reused for a number of libraries that are generated when openssl is compiled. As a result, lib.pdb is clobbered (overwritten) for all but the last library. To resolve the problem, each library should be given .pdb with a unique name. To simplify matters further, ensure that the compilation location is in the same tree as the libcurl build.

这篇关于如何删除警告 LNK4099:未找到 PDB 'lib.pdb'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆