Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with unresolved symbols when linking static net-snmp library (MSVC 2022, OpenSSL enabled) #905

Open
Temerin opened this issue Dec 9, 2024 · 8 comments

Comments

@Temerin
Copy link

Temerin commented Dec 9, 2024

Hello,

I encountered a problem when building the net-snmp library as a static library with the following configuration:

  • Compiler: MSVC 2022 (x64)
  • OpenSSL version: 3.4.0
  • Build type: Static

When linking the resulting library to my project, I get unresolved symbol errors for several SNMPv3-related protocols, such as usmAESPrivProtocol, usmHMACSHA1AuthProtocol, usmHMACMD5AuthProtocol, and others.

These issues occur in a function that initializes SNMPv3 sessions in my code. The errors point to missing definitions for these symbols in the static net-snmp library.

Interestingly, this problem does not appear when building net-snmp as a dynamic library.

Steps to reproduce:

  1. Build net-snmp as a static library using MSVC 2022 x64 with OpenSSL 3.4.0.
  2. Link the library to a project that uses SNMPv3 with authentication and privacy protocols.
  3. Attempt to compile the project.

Expected behavior:
The static library should include all necessary symbols to support SNMPv3 functionality, including authentication and privacy protocols.

Actual behavior:
Unresolved symbols prevent successful linking of the static library to the project.

Additional context:

This issue seems specific to static builds.
Dynamic builds work as expected without any linking errors.
This issue has been observed since the recent fixes for building the project as a static library on Windows x64, and it can be consistently reproduced on the latest commits as of December 8th.
Let me know if you need further details or a minimal reproducible example.

Thank you!

@bvanassche
Copy link
Contributor

As one can see here, building Net-SNMP as a static library works fine with OpenSSL 3.4.0: https://ci.appveyor.com/project/BVanAssche87257/net-snmp/builds/51128958/job/8n5yv7c90hr6p0d2

@Temerin
Copy link
Author

Temerin commented Dec 10, 2024

Thank you for your response.

I understand that the static build of net-snmp with OpenSSL 3.4.0 works fine on your CI setup. However, the issue I am experiencing is not during the build of net-snmp itself, but rather when using the statically built net-snmp library in my own project.

Specifically:

When I attempt to link the statically built net-snmp library to my project and use the mentioned OIDs (e.g., usmAESPrivProtocol, usmHMACSHA1AuthProtocol), the linker throws errors about missing implementations for these protocols.
From what I understand, this suggests that the static net-snmp library fails to properly link with OpenSSL during its build process, resulting in the missing symbols when I use the library in my project.
The dynamic build does not have this issue, which further supports the idea that this might be a problem with how the static library interacts with OpenSSL.

Please let me know if there are any additional configuration steps or flags that I might be missing to ensure proper linkage with OpenSSL in a static build.

Thank you!

@bvanassche
Copy link
Contributor

Are you using win32/build.bat or not? If not, please check whether _DLL is not defined. Net-SNMP decides as follows whether to link OpenSSL dynamically or statically:

/* MSVC OpenSSL linker settings. */
#if defined(_MSC_VER)
#  if defined(NETSNMP_USE_OPENSSL)
#    ifdef _DLL
#      pragma comment(lib, "libcrypto.lib")
#      pragma comment(lib, "libssl.lib")
#    else
#      pragma comment(lib, "libcrypto_static.lib")
#      pragma comment(lib, "libssl_static.lib")
#    endif
#    pragma comment(lib, "gdi32.lib")
#    pragma comment(lib, "user32.lib")
#  endif
#endif

@Temerin
Copy link
Author

Temerin commented Dec 12, 2024

Thank you for your clarification regarding the _DLL definition and the decision to link OpenSSL dynamically or statically.

I confirm that I used win32/build.bat with the following parameters:

  1. OpenSSL support: enabled
  2. OpenSSL include directory: C:\OpenSSL-Win64\include
  3. OpenSSL library directory: C:\OpenSSL-Win64\lib\VC\x64
  4. Install path: c:/usr
  5. Install after build: enabled
  6. Perl modules: disabled
  7. Install Perl modules: disabled
  8. Quiet build (logged): disabled
  9. Debug mode: disabled
  10. IPv6 transports: disabled
  11. winExtDLL agent: disabled
  12. Link type: static
  13. Install development files: enabled

I used pre-compiled OpenSSL 3.4.0, distributed as an installer.
From what I understand, since _DLL is typically defined for dynamic linking scenarios, it should not affect my static build configuration. However, the issue persists when using the resulting static net-snmp library in my project.

Could there be another potential cause, such as incorrect linkage to OpenSSL static libraries (libcrypto_static.lib and libssl_static.lib), or perhaps a misstep in the build script itself when handling these dependencies?

I’d appreciate any suggestions or additional checks I can perform to ensure the static library is properly linked with OpenSSL.

@bvanassche
Copy link
Contributor

I think it's time to analyze the involved binaries and check where the undefined symbols occur. Is this a good tool for analyzing the Net-SNMP static libraries and the .obj files to see which binary is causing the undefined symbol error: https://dependencywalker.com/?

@Temerin
Copy link
Author

Temerin commented Dec 13, 2024

As far as I know, Dependency Walker only works for *.exe and *.dll. For *.lib it gave me an error, without useful result.
I have analyzed the generated static library files using dumpbin /SYMBOLS, and here is what I found:

As shown in the attached screenshot, the following symbols are marked as "External" in the output of dumpbin:

  • usmNoAuthProtocol
  • usmHMACMD5AuthProtocol
  • usmHMACSHA1AuthProtocol
  • usmHMAC192SHA256AuthProtocol
  • usmHMAC256SHA384AuthProtocol
  • usmHMAC384SHA512AuthProtocol
  • usmDESPrivProtocol
  • usmAESPrivProtocol

I have searched for the implementation of these symbols in the other .lib files generated by the Net-SNMP build process, as well as in the OpenSSL 3.4.0 libraries, but I was unable to find them.

I have also come across mentions of similar issues online regarding unresolved external symbols related to SNMP protocols, but unfortunately, I couldn't find a suitable solution for this specific case.

Could this be a build configuration issue, or are these symbols expected to be implemented elsewhere? Any guidance would be much appreciated.

@bvanassche
Copy link
Contributor

I don't see any screenshot attached?

Anyway, all the names mentioned above are arrays defined in snmplib/snmpusm.c. These arrays should be present in netsnmp.lib. Which library has been analyzed with dumpbin? netsnmp.lib or another library? In case it is another library, does netsnmp.lib occur after the other Net-SNMP static libraries on the linker command line?

@Temerin
Copy link
Author

Temerin commented Dec 16, 2024

I have resolved the issue. I was under the impression that the .lib files in C:\usr were copies of the libraries being built. However, it turns out the correct libraries are located in Net-SNMP\win32\lib\release. Those libraries do indeed contain the necessary symbol implementations.

This behavior was counter-intuitive to me, but now it makes sense. Thank you for your help and guidance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants