Skip to content

Implement SymbolInfo::getFilename() on Win32 #62577

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/swift/Runtime/Win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@

#include "swift/shims/Visibility.h"

#include <cwchar>
#include <functional>
#include <type_traits>

// For HANDLE
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <Windows.h>

#include <wchar.h>
#pragma mark - Wide-character string conversion

/// Convert a wide string to UTF-8.
///
Expand All @@ -53,6 +54,8 @@ char *_swift_win32_copyUTF8FromWide(const wchar_t *str);
SWIFT_RUNTIME_STDLIB_SPI
wchar_t *_swift_win32_copyWideFromUTF8(const char *str);

#pragma mark - DbgHelp library thread-safety

/// Configure the environment to allow calling into the Debug Help library.
///
/// \param body A function to invoke. This function attempts to first initialize
Expand Down
19 changes: 14 additions & 5 deletions stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,15 @@ internal func _getMetadataSection(_ index: UInt) -> UnsafeRawPointer?
@_silgen_name("swift_getMetadataSectionCount")
internal func _getMetadataSectionCount() -> UInt

@_silgen_name("swift_getMetadataSectionName")
internal func _getMetadataSectionName(
@_silgen_name("swift_copyMetadataSectionName")
internal func _copyMetadataSectionName(
_ metadata_section: UnsafeRawPointer
) -> UnsafePointer<CChar>
) -> UnsafeMutablePointer<CChar>?

@_silgen_name("swift_freeMetadataSectionName")
internal func _freeMetadataSectionName(
_ name: UnsafeMutablePointer<CChar>
) -> Void
#endif

extension Section {
Expand All @@ -154,9 +159,13 @@ extension Section {
internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
#if INTERNAL_CHECKS_ENABLED
return _getMetadataSection(UInt(i)).map { rawPointer in
let name = _getMetadataSectionName(rawPointer)
let cName = _copyMetadataSectionName(rawPointer)
defer {
_freeMetadataSectionName(cName)
}
let name = cName.flatMap { String(validatingUTF8: $0) } ?? "<unavailable>"
let metadataSection = rawPointer.bindMemory(to: MetadataSections.self, capacity: 1).pointee
return ReflectionInfo(imageName: String(validatingUTF8: name)!,
return ReflectionInfo(imageName: name,
fieldmd: Section(range: metadataSection.swift5_fieldmd),
assocty: Section(range: metadataSection.swift5_assocty),
builtin: Section(range: metadataSection.swift5_builtin),
Expand Down
2 changes: 0 additions & 2 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ set(swift_runtime_sources
HeapObject.cpp
ImageInspectionCommon.cpp
ImageInspectionMachO.cpp
ImageInspectionELF.cpp
ImageInspectionCOFF.cpp
ImageInspectionStatic.cpp
ImageInspectionWasm.cpp
SymbolInfo.cpp
Expand Down
22 changes: 11 additions & 11 deletions stdlib/public/runtime/Errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ enum: uint32_t {
using namespace swift;

#if SWIFT_STDLIB_SUPPORTS_BACKTRACE_REPORTING && SWIFT_STDLIB_HAS_DLADDR
static bool getSymbolNameAddr(llvm::StringRef libraryName,
const SymbolInfo &syminfo,
static bool getSymbolNameAddr(const SymbolInfo &syminfo,
std::string &symbolName, uintptr_t &addrOut) {
// If we failed to find a symbol and thus dlinfo->dli_sname is nullptr, we
// need to use the hex address.
Expand Down Expand Up @@ -150,12 +149,14 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
return;
}

// If SymbolInfo:lookup succeeded then fileName is non-null. Thus, we find the
// If SymbolInfo:lookup succeeded and fileName is non-null, we can find the
// library name here. Avoid using StringRef::rsplit because its definition
// is not provided in the header so that it requires linking with
// libSupport.a.
llvm::StringRef libraryName{syminfo->getFilename()};
libraryName = libraryName.substr(libraryName.rfind('/')).substr(1);
const char *libraryName = syminfo->getImageFilename();
if (!libraryName) {
libraryName = "<unavailable>";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: <unknown> might be better to match what we do with functions which we cannot symbolize.

}

// Next we get the symbol name that we are going to use in our backtrace.
std::string symbolName;
Expand All @@ -164,12 +165,12 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
// we just get HexAddr + 0.
uintptr_t symbolAddr = uintptr_t(framePC);
bool foundSymbol =
getSymbolNameAddr(libraryName, syminfo.value(), symbolName, symbolAddr);
getSymbolNameAddr(syminfo.value(), symbolName, symbolAddr);
ptrdiff_t offset = 0;
if (foundSymbol) {
offset = ptrdiff_t(uintptr_t(framePC) - symbolAddr);
} else {
auto baseAddress = syminfo->getBaseAddress();
const void *baseAddress = syminfo->getImageBaseAddress();
offset = ptrdiff_t(uintptr_t(framePC) - uintptr_t(baseAddress));
symbolAddr = uintptr_t(framePC);
symbolName = "<unavailable>";
Expand All @@ -183,12 +184,11 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
// This gives enough info to reconstruct identical debugging target after
// this process terminates.
if (shortOutput) {
fprintf(stderr, "%s`%s + %td", libraryName.data(), symbolName.c_str(),
offset);
fprintf(stderr, "%s`%s + %td", libraryName, symbolName.c_str(), offset);
} else {
constexpr const char *format = "%-4u %-34s 0x%0.16" PRIxPTR " %s + %td\n";
fprintf(stderr, format, index, libraryName.data(), symbolAddr,
symbolName.c_str(), offset);
fprintf(stderr, format, index, libraryName, symbolAddr, symbolName.c_str(),
offset);
}
#else
if (shortOutput) {
Expand Down
89 changes: 0 additions & 89 deletions stdlib/public/runtime/ImageInspectionCOFF.cpp

This file was deleted.

24 changes: 14 additions & 10 deletions stdlib/public/runtime/ImageInspectionCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ static void fixupMetadataSectionBaseAddress(swift::MetadataSections *sections) {
if (fixupNeeded) {
// We need to fix up the base address. We'll need a known-good address in
// the same image: `sections` itself will work nicely.
auto symbolInfo = SymbolInfo::lookup(sections);
if (symbolInfo.has_value() && symbolInfo->getBaseAddress()) {
sections->baseAddress.store(symbolInfo->getBaseAddress(),
std::memory_order_relaxed);
if (auto symbolInfo = SymbolInfo::lookup(sections)) {
if (const void *baseAddress = symbolInfo->getImageBaseAddress()) {
sections->baseAddress.store(baseAddress, std::memory_order_relaxed);
}
}
}
}
Expand Down Expand Up @@ -200,22 +200,26 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
}

SWIFT_RUNTIME_EXPORT
const char *
swift_getMetadataSectionName(const swift::MetadataSections *section) {
char *swift_copyMetadataSectionName(const swift::MetadataSections *section) {
if (auto info = swift::SymbolInfo::lookup(section)) {
if (info->getFilename()) {
return info->getFilename();
if (const char *imagePath = info->getImagePath()) {
return strdup(imagePath);
}
}
return "";
return nullptr;
}

SWIFT_RUNTIME_EXPORT
void swift_freeMetadataSectionName(char *name) {
free(name);
}

SWIFT_RUNTIME_EXPORT
void swift_getMetadataSectionBaseAddress(const swift::MetadataSections *section,
void const **out_actual,
void const **out_expected) {
if (auto info = swift::SymbolInfo::lookup(section)) {
*out_actual = info->getBaseAddress();
*out_actual = info->getImageBaseAddress();
} else {
*out_actual = nullptr;
}
Expand Down
7 changes: 5 additions & 2 deletions stdlib/public/runtime/ImageInspectionCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ void swift_enumerateAllMetadataSections(
#ifndef NDEBUG

SWIFT_RUNTIME_EXPORT
const char *
swift_getMetadataSectionName(const struct swift::MetadataSections *section);
char *
swift_copyMetadataSectionName(const struct swift::MetadataSections *section);

SWIFT_RUNTIME_EXPORT
void swift_freeMetadataSectionName(char *name);

SWIFT_RUNTIME_EXPORT
void swift_getMetadataSectionBaseAddress(
Expand Down
25 changes: 0 additions & 25 deletions stdlib/public/runtime/ImageInspectionELF.cpp

This file was deleted.

4 changes: 2 additions & 2 deletions stdlib/public/runtime/ReflectionMirror.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,8 @@ id swift_reflectionMirror_quickLookObject(OpaqueValue *value, const Metadata *T)
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
const char *swift_keyPath_copySymbolName(void *address) {
if (auto info = SymbolInfo::lookup(address)) {
if (info->getSymbolName()) {
return strdup(info->getSymbolName());
if (const char *symbolName = info->getSymbolName()) {
return strdup(symbolName);
}
}
return nullptr;
Expand Down
Loading