diff --git a/stdlib/public/Backtracing/Elf.swift b/stdlib/public/Backtracing/Elf.swift index da8ff0d6d097f..3758bbbc99a53 100644 --- a/stdlib/public/Backtracing/Elf.swift +++ b/stdlib/public/Backtracing/Elf.swift @@ -875,8 +875,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 } @@ -999,6 +999,8 @@ class ElfImage= $0.baseAddress && address < $0.endOfText } ) { - let relativeAddress = address - FileImageSource.Address(theImages[imageNdx].baseAddress) var symbol: Symbol = Symbol(imageIndex: imageNdx, imageName: theImages[imageNdx].name, rawName: "", @@ -504,19 +503,26 @@ public struct SymbolicatedBacktrace: CustomStringConvertible { sourceLocation: nil) var elf32Image = elf32Cache[imageNdx] var elf64Image = elf64Cache[imageNdx] + var imageBase = FileImageSource.Address(0) if elf32Image == nil && elf64Image == nil { if let source = try? FileImageSource(path: theImages[imageNdx].path) { if let elfImage = try? Elf32Image(source: source) { elf32Image = elfImage elf32Cache[imageNdx] = elfImage + imageBase = elfImage.imageBase } else if let elfImage = try? Elf64Image(source: source) { elf64Image = elfImage elf64Cache[imageNdx] = elfImage + imageBase = elfImage.imageBase } } } + let relativeAddress = FileImageSource.Address( + address - theImages[imageNdx].baseAddress + ) + imageBase + if let theSymbol = elf32Image?.lookupSymbol(address: relativeAddress) { var location: SourceLocation? 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;