Skip to content

Commit 1173939

Browse files
authored
Merge pull request #82633 from al45tair/eng/PR-154282813-6.1
[Backtracing][Linux] Fix crash handler for musl.
2 parents e69c5d6 + 150305c commit 1173939

File tree

3 files changed

+56
-15
lines changed

3 files changed

+56
-15
lines changed

stdlib/public/Backtracing/Elf.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,8 +875,8 @@ struct ElfSymbolTable<SomeElfTraits: ElfTraits>: ElfSymbolTableProtocol {
875875
continue
876876
}
877877

878-
// Ignore anything undefined
879-
if symbol.st_shndx == SHN_UNDEF {
878+
// Ignore anything undefined or absolute
879+
if symbol.st_shndx == SHN_UNDEF || symbol.st_shndx == SHN_ABS {
880880
continue
881881
}
882882

@@ -999,6 +999,8 @@ class ElfImage<SomeImageSource: ImageSource,
999999
var sectionHeaders: [Traits.Shdr]?
10001000
var shouldByteSwap: Bool { return header.shouldByteSwap }
10011001

1002+
var imageBase: Source.Address
1003+
10021004
required init(source: SomeImageSource,
10031005
baseAddress: Source.Address = 0,
10041006
endAddress: Source.Address = 0) throws {
@@ -1029,11 +1031,21 @@ class ElfImage<SomeImageSource: ImageSource,
10291031

10301032
var phdrs: [Traits.Phdr] = []
10311033
var phAddr = Source.Address(header.e_phoff)
1034+
var minAddr: Traits.Address? = nil
10321035
for _ in 0..<header.e_phnum {
10331036
let phdr = maybeSwap(try source.fetch(from: phAddr, as: Traits.Phdr.self))
10341037
phdrs.append(phdr)
10351038
phAddr += Source.Address(header.e_phentsize)
1039+
1040+
if phdr.p_type == .PT_LOAD {
1041+
if let oldMinAddr = minAddr {
1042+
minAddr = min(oldMinAddr, phdr.p_vaddr)
1043+
} else {
1044+
minAddr = phdr.p_vaddr
1045+
}
1046+
}
10361047
}
1048+
imageBase = Source.Address(exactly: minAddr ?? 0)!
10371049
programHeaders = phdrs
10381050

10391051
if source.isMappedImage {

stdlib/public/Backtracing/SymbolicatedBacktrace.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,27 +496,33 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
496496
where: { address >= $0.baseAddress
497497
&& address < $0.endOfText }
498498
) {
499-
let relativeAddress = address - FileImageSource.Address(theImages[imageNdx].baseAddress)
500499
var symbol: Symbol = Symbol(imageIndex: imageNdx,
501500
imageName: theImages[imageNdx].name,
502501
rawName: "<unknown>",
503502
offset: 0,
504503
sourceLocation: nil)
505504
var elf32Image = elf32Cache[imageNdx]
506505
var elf64Image = elf64Cache[imageNdx]
506+
var imageBase = FileImageSource.Address(0)
507507

508508
if elf32Image == nil && elf64Image == nil {
509509
if let source = try? FileImageSource(path: theImages[imageNdx].path) {
510510
if let elfImage = try? Elf32Image(source: source) {
511511
elf32Image = elfImage
512512
elf32Cache[imageNdx] = elfImage
513+
imageBase = elfImage.imageBase
513514
} else if let elfImage = try? Elf64Image(source: source) {
514515
elf64Image = elfImage
515516
elf64Cache[imageNdx] = elfImage
517+
imageBase = elfImage.imageBase
516518
}
517519
}
518520
}
519521

522+
let relativeAddress = FileImageSource.Address(
523+
address - theImages[imageNdx].baseAddress
524+
) + imageBase
525+
520526
if let theSymbol = elf32Image?.lookupSymbol(address: relativeAddress) {
521527
var location: SourceLocation?
522528

stdlib/public/runtime/CrashHandlerLinux.cpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@
4949
#include <string.h>
5050
#include <unistd.h>
5151

52+
#define DEBUG_MEMSERVER 0
53+
54+
#if DEBUG_MEMSERVER
55+
#include <stdio.h>
56+
#define memserver_error(x) perror(x)
57+
#else
58+
#define memserver_error(x)
59+
#endif
60+
5261
#include "swift/Runtime/Backtrace.h"
5362

5463
#include <cstring>
@@ -86,8 +95,8 @@ ssize_t safe_read(int fd, void *buf, size_t len) {
8695
ssize_t ret;
8796
do {
8897
ret = read(fd, buf, len);
89-
} while (ret < 0 && errno == EINTR);
90-
if (ret < 0)
98+
} while (ret <= 0 && errno == EINTR);
99+
if (ret <= 0)
91100
return ret;
92101
total += ret;
93102
ptr += ret;
@@ -106,8 +115,8 @@ ssize_t safe_write(int fd, const void *buf, size_t len) {
106115
ssize_t ret;
107116
do {
108117
ret = write(fd, buf, len);
109-
} while (ret < 0 && errno == EINTR);
110-
if (ret < 0)
118+
} while (ret <= 0 && errno == EINTR);
119+
if (ret <= 0)
111120
return ret;
112121
total += ret;
113122
ptr += ret;
@@ -657,20 +666,28 @@ memserver_start()
657666
int fds[2];
658667

659668
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
660-
if (ret < 0)
669+
if (ret < 0) {
670+
memserver_error("memserver_start: socketpair failed");
661671
return ret;
672+
}
662673

663674
memserver_fd = fds[0];
664675
ret = clone(memserver_entry, memserver_stack + sizeof(memserver_stack),
665676
#if MEMSERVER_USE_PROCESS
666677
0,
667678
#else
668-
CLONE_THREAD | CLONE_VM | CLONE_FILES
669-
| CLONE_FS | CLONE_IO | CLONE_SIGHAND,
679+
#ifndef __musl__
680+
// Can't use CLONE_THREAD on musl because the clone() function
681+
// there returns EINVAL if we do.
682+
CLONE_THREAD | CLONE_SIGHAND |
683+
#endif
684+
CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_IO,
670685
#endif
671686
NULL);
672-
if (ret < 0)
687+
if (ret < 0) {
688+
memserver_error("memserver_start: clone failed");
673689
return ret;
690+
}
674691

675692
#if MEMSERVER_USE_PROCESS
676693
memserver_pid = ret;
@@ -718,7 +735,7 @@ memserver_entry(void *dummy __attribute__((unused))) {
718735
int fd = memserver_fd;
719736
int result = 1;
720737

721-
#if MEMSERVER_USE_PROCESS
738+
#if MEMSERVER_USE_PROCESS || defined(__musl__)
722739
prctl(PR_SET_NAME, "[backtrace]");
723740
#endif
724741

@@ -743,8 +760,10 @@ memserver_entry(void *dummy __attribute__((unused))) {
743760
ssize_t ret;
744761

745762
ret = safe_read(fd, &req, sizeof(req));
746-
if (ret != sizeof(req))
763+
if (ret != sizeof(req)) {
764+
memserver_error("memserver: terminating because safe_read() returned wrong size");
747765
break;
766+
}
748767

749768
uint64_t addr = req.addr;
750769
uint64_t bytes = req.len;
@@ -761,15 +780,19 @@ memserver_entry(void *dummy __attribute__((unused))) {
761780
resp.len = ret;
762781

763782
ret = safe_write(fd, &resp, sizeof(resp));
764-
if (ret != sizeof(resp))
783+
if (ret != sizeof(resp)) {
784+
memserver_error("memserver: terminating because safe_write() failed");
765785
goto fail;
786+
}
766787

767788
if (resp.len < 0)
768789
break;
769790

770791
ret = safe_write(fd, memserver_buffer, resp.len);
771-
if (ret != resp.len)
792+
if (ret != resp.len) {
793+
memserver_error("memserver: terminating because safe_write() failed (2)");
772794
goto fail;
795+
}
773796

774797
addr += resp.len;
775798
bytes -= resp.len;

0 commit comments

Comments
 (0)