Skip to content

Commit 30b7be5

Browse files
committed
Address feedback
1 parent 5d3e8cb commit 30b7be5

File tree

9 files changed

+87
-40
lines changed

9 files changed

+87
-40
lines changed

include/swift/Runtime/Win32Strings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace swift {
2525
/// @param str The string to convert.
2626
///
2727
/// @returns The string, converted to UTF-8. The caller is responsible for
28-
/// freeing this string when done with it.
28+
/// freeing this string with @c free() when done with it.
2929
///
3030
/// If @a str cannot be converted to UTF-8, @c nullptr is returned.
3131
SWIFT_RUNTIME_STDLIB_INTERNAL

stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ internal func _getMetadataSectionCount() -> UInt
142142
internal func _copyMetadataSectionName(
143143
_ metadata_section: UnsafeRawPointer
144144
) -> UnsafeMutablePointer<CChar>?
145+
146+
@_silgen_name("swift_freeMetadataSectionName")
147+
internal func _freeMetadataSectionName(
148+
_ name: UnsafeMutablePointer<CChar>
149+
) -> Void
145150
#endif
146151

147152
extension Section {
@@ -156,7 +161,7 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
156161
return _getMetadataSection(UInt(i)).map { rawPointer in
157162
let cName = _copyMetadataSectionName(rawPointer)
158163
defer {
159-
cName.deallocate()
164+
_freeMetadataSectionName(cName)
160165
}
161166
let name = cName.flatMap { String(validatingUTF8: $0) } ?? "<unavailable>"
162167
let metadataSection = rawPointer.bindMemory(to: MetadataSections.self, capacity: 1).pointee

stdlib/public/runtime/Errors.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ enum: uint32_t {
7878
using namespace swift;
7979

8080
#if SWIFT_STDLIB_SUPPORTS_BACKTRACE_REPORTING && SWIFT_STDLIB_HAS_DLADDR
81-
static bool getSymbolNameAddr(llvm::StringRef libraryName,
82-
const SymbolInfo &syminfo,
81+
static bool getSymbolNameAddr(const SymbolInfo &syminfo,
8382
std::string &symbolName, uintptr_t &addrOut) {
8483
// If we failed to find a symbol and thus dlinfo->dli_sname is nullptr, we
8584
// need to use the hex address.
@@ -153,10 +152,9 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
153152
// library name here. Avoid using StringRef::rsplit because its definition
154153
// is not provided in the header so that it requires linking with
155154
// libSupport.a.
156-
llvm::StringRef libraryName{"<unavailable>"};
157-
if (const char *filename = syminfo->getFilename()) {
158-
libraryName = filename;
159-
libraryName = libraryName.substr(libraryName.rfind('/')).substr(1);
155+
const char *libraryName = syminfo->getImageFilename();
156+
if (!libraryName) {
157+
libraryName = "<unavailable>";
160158
}
161159

162160
// Next we get the symbol name that we are going to use in our backtrace.
@@ -166,12 +164,12 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
166164
// we just get HexAddr + 0.
167165
uintptr_t symbolAddr = uintptr_t(framePC);
168166
bool foundSymbol =
169-
getSymbolNameAddr(libraryName, syminfo.value(), symbolName, symbolAddr);
167+
getSymbolNameAddr(syminfo.value(), symbolName, symbolAddr);
170168
ptrdiff_t offset = 0;
171169
if (foundSymbol) {
172170
offset = ptrdiff_t(uintptr_t(framePC) - symbolAddr);
173171
} else {
174-
const void *baseAddress = syminfo->getBaseAddress();
172+
const void *baseAddress = syminfo->getImageBaseAddress();
175173
offset = ptrdiff_t(uintptr_t(framePC) - uintptr_t(baseAddress));
176174
symbolAddr = uintptr_t(framePC);
177175
symbolName = "<unavailable>";
@@ -185,12 +183,11 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
185183
// This gives enough info to reconstruct identical debugging target after
186184
// this process terminates.
187185
if (shortOutput) {
188-
fprintf(stderr, "%s`%s + %td", libraryName.data(), symbolName.c_str(),
189-
offset);
186+
fprintf(stderr, "%s`%s + %td", libraryName, symbolName.c_str(), offset);
190187
} else {
191188
constexpr const char *format = "%-4u %-34s 0x%0.16" PRIxPTR " %s + %td\n";
192-
fprintf(stderr, format, index, libraryName.data(), symbolAddr,
193-
symbolName.c_str(), offset);
189+
fprintf(stderr, format, index, libraryName, symbolAddr, symbolName.c_str(),
190+
offset);
194191
}
195192
#else
196193
if (shortOutput) {

stdlib/public/runtime/ImageInspectionCommon.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ static void fixupMetadataSectionBaseAddress(swift::MetadataSections *sections) {
6464
if (fixupNeeded) {
6565
// We need to fix up the base address. We'll need a known-good address in
6666
// the same image: `sections` itself will work nicely.
67-
auto symbolInfo = SymbolInfo::lookup(sections);
68-
if (symbolInfo.has_value() && symbolInfo->getBaseAddress()) {
69-
sections->baseAddress.store(symbolInfo->getBaseAddress(),
70-
std::memory_order_relaxed);
67+
if (auto symbolInfo = SymbolInfo::lookup(sections)) {
68+
if (const void *baseAddress = symbolInfo->getImageBaseAddress()) {
69+
sections->baseAddress.store(baseAddress, std::memory_order_relaxed);
70+
}
7171
}
7272
}
7373
}
@@ -190,19 +190,24 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
190190
SWIFT_RUNTIME_EXPORT
191191
char *swift_copyMetadataSectionName(const swift::MetadataSections *section) {
192192
if (auto info = SymbolInfo::lookup(section)) {
193-
if (info->getFilename()) {
194-
return strdup(info->getFilename());
193+
if (const char *imagePath = info->getImagePath()) {
194+
return strdup(imagePath);
195195
}
196196
}
197197
return "";
198198
}
199199

200+
SWIFT_RUNTIME_EXPORT
201+
void swift_freeMetadataSectionName(char *name) {
202+
free(name);
203+
}
204+
200205
SWIFT_RUNTIME_EXPORT
201206
void swift_getMetadataSectionBaseAddress(const swift::MetadataSections *section,
202207
void const **out_actual,
203208
void const **out_expected) {
204209
if (auto info = SymbolInfo::lookup(section)) {
205-
*out_actual = info->getBaseAddress();
210+
*out_actual = info->getImageBaseAddress();
206211
} else {
207212
*out_actual = nullptr;
208213
}

stdlib/public/runtime/ImageInspectionCommon.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ SWIFT_RUNTIME_EXPORT
8989
char *
9090
swift_copyMetadataSectionName(const struct swift::MetadataSections *section);
9191

92+
SWIFT_RUNTIME_EXPORT
93+
void swift_freeMetadataSectionName(char *name);
94+
9295
SWIFT_RUNTIME_EXPORT
9396
void swift_getMetadataSectionBaseAddress(
9497
const struct swift::MetadataSections *section,

stdlib/public/runtime/ReflectionMirror.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,9 +1116,10 @@ id swift_reflectionMirror_quickLookObject(OpaqueValue *value, const Metadata *T)
11161116

11171117
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
11181118
const char *swift_keyPath_copySymbolName(void *address) {
1119-
auto info = SymbolInfo::lookup(address);
1120-
if (info.has_value() && info->getSymbolName()) {
1121-
return strdup(info->getSymbolName());
1119+
if (auto info = SymbolInfo::lookup(address)) {
1120+
if (const char *symbolName = info->getSymbolName()) {
1121+
return strdup(symbolName);
1122+
}
11221123
}
11231124
return nullptr;
11241125
}

stdlib/public/runtime/SymbolInfo.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <Windows.h>
1919
#include <DbgHelp.h>
2020
#include <Psapi.h>
21+
#include <shlwapi.h>
2122
#elif SWIFT_STDLIB_HAS_DLADDR
2223
#include <dlfcn.h>
2324
#endif
@@ -42,8 +43,8 @@ _address(nullptr)
4243

4344
SymbolInfo::~SymbolInfo() {
4445
#if defined(_WIN32) && !defined(__CYGWIN__)
45-
if (char *filename = _filename.getValueOr(nullptr)) {
46-
free(filename);
46+
if (char *imagePath = _imagePath.getValueOr(nullptr)) {
47+
free(imagePath);
4748
}
4849
#endif
4950
}
@@ -52,14 +53,14 @@ const void *SymbolInfo::getAddress() const {
5253
return _address;
5354
}
5455

55-
const char *SymbolInfo::getFilename() const {
56+
const char *getImagePath() const {
5657
#if defined(_WIN32) && !defined(__CYGWIN__)
57-
if (!_filename.has_value()) {
58+
if (!_imagePath.has_value()) {
5859
// On Win32/Win64, the base address of a loaded image and its HMODULE are
5960
// the same pointer, so we can simply cast from one to the other.
60-
HMODULE hModule = reinterpret_cast<HMODULE>(getBaseAddress());
61+
HMODULE hModule = reinterpret_cast<HMODULE>(getImageBaseAddress());
6162
if (!hModule) {
62-
_filename = nullptr;
63+
_imagePath = nullptr;
6364
return;
6465
}
6566

@@ -68,19 +69,36 @@ const char *SymbolInfo::getFilename() const {
6869
// other information we don't need.
6970
std::array<wchar_t, MAX_PATH> filename;
7071
if (GetModuleFileNameW(hModule, filename.data(), filename.size())) {
71-
_filename = swift_copyUTF8FromWide(filename.data());
72+
_imagePath = swift_copyUTF8FromWide(filename.data());
7273
}
7374
}
7475

75-
return _filename.getValueOr(nullptr);
76+
return _imagePath.getValueOr(nullptr);
7677
#elif SWIFT_STDLIB_HAS_DLADDR
7778
return _info.dli_fname;
7879
#else
7980
return nullptr;
8081
#endif
8182
}
8283

83-
const void *SymbolInfo::getBaseAddress() const {
84+
const char *SymbolInfo::getImageFilename() const {
85+
// TODO: if we adopt C++17, consider using std::filesystem::path::filename()
86+
const char *imagePath = getImagePath();
87+
if (!imagePath) {
88+
return nullptr;
89+
}
90+
#if defined(_WIN32) && !defined(__CYGWIN__)
91+
return PathFindFileNameA(imagePath);
92+
#else
93+
if (const char *lastSlash = strrchr(imagePath, '/')) {
94+
return lastSlash + 1;
95+
} else {
96+
return imagePath;
97+
}
98+
#endif
99+
}
100+
101+
const void *SymbolInfo::getImageBaseAddress() const {
84102
#if defined(_WIN32) && !defined(__CYGWIN__)
85103
return reinterpret_cast<const void *>(_package.si.ModBase);
86104
#elif SWIFT_STDLIB_HAS_DLADDR
@@ -127,7 +145,7 @@ llvm::Optional<SymbolInfo> SymbolInfo::lookup(const void *address) {
127145
// If there are real-world examples of symbol names with Unicode characters
128146
// that we need to consider, SymbolInfo can hold a SYMBOL_INFO_PACKAGEW and
129147
// call SymFromAddrW(), then lazily convert to UTF-8 on the first call to
130-
// getSymbolName() as is done in getFilename().
148+
// getSymbolName() as is done in getImagePath().
131149
SymbolInfo info;
132150
info._package.si.SizeOfStruct = sizeof(SYMBOL_INFO);
133151
info._package.si.MaxNameLen = MAX_SYM_NAME;

stdlib/public/runtime/SymbolInfo.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct SymbolInfo {
3636
private:
3737
#if defined(_WIN32) && !defined(__CYGWIN__)
3838
SYMBOL_INFO_PACKAGE _package;
39-
mutable llvm::Optional<char *> _filename;
39+
mutable llvm::Optional<char *> _imagePath;
4040
#elif SWIFT_STDLIB_HAS_DLADDR
4141
Dl_info _info;
4242
#endif
@@ -50,25 +50,38 @@ struct SymbolInfo {
5050
/// Get the address that was originally passed when this instance was created.
5151
const void *getAddress() const;
5252

53+
/// Get the path to the image where the symbol was found.
54+
///
55+
/// The image path uses the platform path convention. To consistently get just
56+
/// the filename of the image, use \c getImageFilename().
57+
///
58+
/// The resulting C string is only valid for the lifetime of \c this.
59+
const char *getImagePath() const;
60+
5361
/// Get the file name of the image where the symbol was found.
5462
///
63+
/// The file name is the last path component of the image path. If the
64+
/// filename cannot be determined from the image path (for instance, because
65+
/// it is a relative path or was invalidly specified), the complete image path
66+
/// is returned.
67+
///
5568
/// The resulting C string is only valid for the lifetime of \c this.
56-
const char *getFilename() const;
69+
const char *getImageFilename() const;
5770

5871
/// Get the base address of the image where the symbol was found.
59-
const void *getBaseAddress() const;
72+
const void *getImageBaseAddress() const;
6073

6174
/// Get the name of the symbol.
6275
///
63-
/// If the input address is valid within a loaded library, but does not
76+
/// If the input address is valid within a loaded image, but does not
6477
/// correspond to any known symbol, the resulting pointer may be \c nullptr.
6578
///
6679
/// The resulting C string is only valid for the lifetime of \c this.
6780
const char *getSymbolName() const;
6881

6982
/// Get the address of the symbol.
7083
///
71-
/// If the input address is valid within a loaded library, but does not
84+
/// If the input address is valid within a loaded image, but does not
7285
/// correspond to any known symbol, the resulting pointer may be \c nullptr.
7386
const void *getSymbolAddress() const;
7487

test/Runtime/loaded_image_uniqueness.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ internal func _copyMetadataSectionName(
1717
_ metadata_section: UnsafeRawPointer
1818
) -> UnsafeMutablePointer<CChar>?
1919

20+
@_silgen_name("swift_freeMetadataSectionName")
21+
internal func _freeMetadataSectionName(
22+
_ name: UnsafeMutablePointer<CChar>
23+
) -> Void
24+
2025
@_silgen_name("swift_getMetadataSectionBaseAddress")
2126
internal func _getMetadataSectionBaseAddress(
2227
_ metadata_section: UnsafeRawPointer,
@@ -36,7 +41,7 @@ do {
3641
}
3742
let cName = _copyMetadataSectionName(rawPointer)
3843
defer {
39-
cName.deallocate()
44+
_freeMetadataSectionName(cName)
4045
}
4146
let name = cName.flatMap { String(validatingUTF8: $0) } ?? "<unavailable>"
4247

0 commit comments

Comments
 (0)