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

Symbols file for stacktrace is not loaded after deployment in Windows #55

Closed
jzmaddock opened this issue May 10, 2018 · 6 comments
Closed

Comments

@jzmaddock
Copy link

Moved from https://svn.boost.org/trac10/ticket/13529

@zlojvavan
Copy link

see also #47 (comment)

@emptyVoid
Copy link

emptyVoid commented Feb 25, 2019

If anyone else is struggling with this issue, here's a works-for-me workaround:

  • Link applications and dynamic libraries with /PDBALTPATH:%_PDB% setting (see docs for details) -- presumably it works with arbitrary relative or absolute path, though I've tested it with no path information only.

In case application's working directory differs from the PDBs' location and the latter is not known at link stage (e.g. user can change the install location), here's an additional step:

  • Set _NT_SYMBOL_PATH environment variable to the path to PDBs (see docs for details). I'm doing it at the application start with something like this:
wchar_t path[MAX_PATH];
GetModuleFileNameW( nullptr, path, MAX_PATH );
PathRemoveFileSpecW( path );
SetEnvironmentVariableW( L"_NT_SYMBOL_PATH", path );

@rogerorr
Copy link

A small change to the work around emptyVoid suggests above is to set _NT_ALT_SYMBOL_PATH to the path of the PDBs. This allows you to retain the use of _NT_SYMBOL_PATH (eg to symbols from a symbol store), while also finding any PDBs installed next to the application binary.

@rogerorr
Copy link

rogerorr commented Nov 30, 2019

I've reported the underlying issue to the Microsoft 'Feedback Hub' using Category "Developer Platform" and Subcategory "Debugging Tools for Windows"

See https://aka.ms/AA6pxh8

Feel free to upvote ...

apolukhin added a commit that referenced this issue Jan 23, 2020
@apolukhin
Copy link
Member

Added description of that issue to the docs.
Many thanks for the links, tweaks and workarounds!

@SpriteOvO
Copy link

I don't know why the solution provided by @emptyVoid for setting the env variable doesn't work for me with the RelWithDebInfo configuration (yes, pdb files are in the same directory as the executable, and Debug configuration works).

So I had to start trying the linker option /PDBALTPATH:%_PDB%, and this is the beginning of a nightmare.

It looks very simple, just add_link_options("/PDBALTPATH:%_PDB%"). But I tried for 3 hours and still can't get it to work. Eventually I stumbled upon CMake escaping that linker option.

So if you try set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/PDBALTPATH:%_PDB%"), CMake will escape the option to /PDBALTPATH:%%_PDB%%,
and if you try add_link_options("/PDBALTPATH:%_PDB%"), CMake will escape the option to /PDBALTPATH:%%%%_PDB%%%%.

And I couldn't find any mention of the "%" escape in their documentation.

This is the bug report for it:
https://cmake.org/Bug/view.php?id=15865
https://gitlab.kitware.com/cmake/cmake/-/issues/15865

Since I didn't find any way to suppress the "%" escape, my workaround is pretty hacky: at the end of the top-level CMakeLists.txt, enumerate all targets and manually specify the pdb file name for each target so that it does not rely on the "%" character.

Now the library is working for me. Here is the code, hopefully it will save close to 6 hours for some people. 😭

macro(get_all_targets_recursive targets dir)
    get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
    foreach(subdir ${subdirectories})
        get_all_targets_recursive(${targets} ${subdir})
    endforeach()

    get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
    list(APPEND ${targets} ${current_targets})
endmacro()

function(get_all_targets var)
    set(targets)
    get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
    set(${var} ${targets} PARENT_SCOPE)
endfunction()

function(apply_pdbaltpath_pdb_for_all_targets)
    get_all_targets(ALL_TARGETS)
    foreach(TARGET_NAME ${ALL_TARGETS})
        get_target_property(OUTPUT_NAME ${TARGET_NAME} OUTPUT_NAME)
        if ("${OUTPUT_NAME}" STREQUAL "OUTPUT_NAME-NOTFOUND" OR "${OUTPUT_NAME}" STREQUAL "")
            set(OUTPUT_NAME ${TARGET_NAME})
        endif()
        set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/PDBALTPATH:${OUTPUT_NAME}.pdb")
    endforeach()
endfunction()

# At the end of the top-level CMakeLists.txt
apply_pdbaltpath_pdb_for_all_targets()

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

6 participants