microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.21k stars 1.51k forks source link

`<stacktrace>` fails to load `.pdb` of shared library #4746

Open ObeliskGate opened 4 months ago

ObeliskGate commented 4 months ago

I'm going to use std::stacktrace in a .dll whitch is loaded by LoadLibrary. While I have followed the instruction from a previous issue #2779 and passed /PDBALTPATH:%_PDB% to link.exe for two binaries, the .pdb file fails to load correctly. The current directory structure is:

C:.
│  test.exe
│  test.pdb
│
└─so
        dll.dll
        dll.pdb

sources of the two binaries is: dll.cpp

#include "head.h"
#include <stacktrace>
#include <iostream>

DLL_API void ps() {
    std::cout << std::stacktrace::current() << std::endl;
}

test.cpp

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include "head.h"
int main() {
    auto hModule = LoadLibrary("./so/dll.dll");
    if (!hModule) {
        std::cerr << "Failed to load library" << std::endl;
        return 1;
    }
    auto func = reinterpret_cast<decltype(&ps)>(GetProcAddress(hModule, "ps"));
    if (!func) {
        std::cerr << "Failed to get function" << std::endl;
        return 1;
    }
    func();
    FreeLibrary(hModule);
    return 0;
}

head.h

extern "C" {
#ifdef _EXPORT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

DLL_API void ps();
}

And when I run test.exe, it prints something like:

0> dll!ps+0x4A
1> C:\space\projects\cpp\st\test.cpp(18): test!main+0x7E
2> D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288): test!__scrt_common_main_seh+0x10C
3> KERNEL32!BaseThreadInitThunk+0x1D
4> ntdll!RtlUserThreadStart+0x28

, indicating that dll.pdb is not loaded correctly (otherwise it should print the directory of dll.cpp).

Since the document of std::stacktrace is missing, is there any solution?

AlexGuteniev commented 4 months ago

I'm not sure if this can be fixed from withing std::stacktrace implementation in this repo and not causing other problems by a possible fix.

I think we need proper upstream API to hadnle this scenario.

I've reported it as one of the problems in DevCom-10692305.

Ulysses1337 commented 4 months ago

The quick workaround is to make sure each pathless PDB is in the working directory. Also note that running within VS starts in ProjectDir instead of OutDir by default.

ObeliskGate commented 4 months ago

The quick workaround is to make sure each pathless PDB is in the working directory. Also note that running within VS starts in ProjectDir instead of OutDir by default.

for a .dll file loaded by LoadLobrary in a more complicated scenario (like Python extension), that's something tricky because sometimes I even don't know the cwd of .exe.