diff --git a/stdlib/public/RuntimeModule/Elf.swift b/stdlib/public/RuntimeModule/Elf.swift index 006a62c456b79..d5b7d1573751e 100644 --- a/stdlib/public/RuntimeModule/Elf.swift +++ b/stdlib/public/RuntimeModule/Elf.swift @@ -1064,8 +1064,8 @@ struct ElfSymbolTable: ElfSymbolTableProtocol { continue } - // Ignore anything undefined - if symbol.st_shndx == SHN_UNDEF { + // Ignore anything undefined or absolute + if symbol.st_shndx == SHN_UNDEF || symbol.st_shndx == SHN_ABS { continue } @@ -1190,6 +1190,8 @@ final class ElfImage var sectionHeaders: [Traits.Shdr]? var shouldByteSwap: Bool { return header.shouldByteSwap } + var imageBase: ImageSource.Address + @_specialize(kind: full, where SomeElfTraits == Elf32Traits) @_specialize(kind: full, where SomeElfTraits == Elf64Traits) required init(source: ImageSource, @@ -1222,11 +1224,21 @@ final class ElfImage var phdrs: [Traits.Phdr] = [] var phAddr = ImageSource.Address(header.e_phoff) + var minAddr: Traits.Address? = nil for _ in 0.." var symbol: Symbol = Symbol(imageIndex: imageNdx, imageName: name, @@ -527,6 +524,9 @@ public struct SymbolicatedBacktrace: CustomStringConvertible { if let hit = cache.lookup(path: theImages[imageNdx].path) { switch hit { case let .elf32Image(image): + let relativeAddress = ImageSource.Address( + address - theImages[imageNdx].baseAddress + ) + image.imageBase if let theSymbol = lookupSymbol(image: image, at: imageNdx, named: name, @@ -534,6 +534,9 @@ public struct SymbolicatedBacktrace: CustomStringConvertible { symbol = theSymbol } case let .elf64Image(image): + let relativeAddress = ImageSource.Address( + address - theImages[imageNdx].baseAddress + ) + image.imageBase if let theSymbol = lookupSymbol(image: image, at: imageNdx, named: name, diff --git a/stdlib/public/runtime/CrashHandlerLinux.cpp b/stdlib/public/runtime/CrashHandlerLinux.cpp index 477d68bbf12b4..f8e0241be2c1e 100644 --- a/stdlib/public/runtime/CrashHandlerLinux.cpp +++ b/stdlib/public/runtime/CrashHandlerLinux.cpp @@ -49,6 +49,15 @@ #include #include +#define DEBUG_MEMSERVER 0 + +#if DEBUG_MEMSERVER +#include +#define memserver_error(x) perror(x) +#else +#define memserver_error(x) +#endif + #include "swift/Runtime/Backtrace.h" #include @@ -86,8 +95,8 @@ ssize_t safe_read(int fd, void *buf, size_t len) { ssize_t ret; do { ret = read(fd, buf, len); - } while (ret < 0 && errno == EINTR); - if (ret < 0) + } while (ret <= 0 && errno == EINTR); + if (ret <= 0) return ret; total += ret; ptr += ret; @@ -106,8 +115,8 @@ ssize_t safe_write(int fd, const void *buf, size_t len) { ssize_t ret; do { ret = write(fd, buf, len); - } while (ret < 0 && errno == EINTR); - if (ret < 0) + } while (ret <= 0 && errno == EINTR); + if (ret <= 0) return ret; total += ret; ptr += ret; @@ -657,20 +666,28 @@ memserver_start() int fds[2]; ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); - if (ret < 0) + if (ret < 0) { + memserver_error("memserver_start: socketpair failed"); return ret; + } memserver_fd = fds[0]; ret = clone(memserver_entry, memserver_stack + sizeof(memserver_stack), #if MEMSERVER_USE_PROCESS 0, #else - CLONE_THREAD | CLONE_VM | CLONE_FILES - | CLONE_FS | CLONE_IO | CLONE_SIGHAND, + #ifndef __musl__ + // Can't use CLONE_THREAD on musl because the clone() function + // there returns EINVAL if we do. + CLONE_THREAD | CLONE_SIGHAND | + #endif + CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_IO, #endif NULL); - if (ret < 0) + if (ret < 0) { + memserver_error("memserver_start: clone failed"); return ret; + } #if MEMSERVER_USE_PROCESS memserver_pid = ret; @@ -718,7 +735,7 @@ memserver_entry(void *dummy __attribute__((unused))) { int fd = memserver_fd; int result = 1; -#if MEMSERVER_USE_PROCESS +#if MEMSERVER_USE_PROCESS || defined(__musl__) prctl(PR_SET_NAME, "[backtrace]"); #endif @@ -743,8 +760,10 @@ memserver_entry(void *dummy __attribute__((unused))) { ssize_t ret; ret = safe_read(fd, &req, sizeof(req)); - if (ret != sizeof(req)) + if (ret != sizeof(req)) { + memserver_error("memserver: terminating because safe_read() returned wrong size"); break; + } uint64_t addr = req.addr; uint64_t bytes = req.len; @@ -761,15 +780,19 @@ memserver_entry(void *dummy __attribute__((unused))) { resp.len = ret; ret = safe_write(fd, &resp, sizeof(resp)); - if (ret != sizeof(resp)) + if (ret != sizeof(resp)) { + memserver_error("memserver: terminating because safe_write() failed"); goto fail; + } if (resp.len < 0) break; ret = safe_write(fd, memserver_buffer, resp.len); - if (ret != resp.len) + if (ret != resp.len) { + memserver_error("memserver: terminating because safe_write() failed (2)"); goto fail; + } addr += resp.len; bytes -= resp.len;