Implement swapcontext() and makecontext()

This change introduces support for Linux-style uc_context manipulation
that's fast and works well on all supported OSes and architectures. It
also integrates with the Cosmpolitan runtime which can show backtraces
comprised of multiple stacks and fibers. See the test and example code
for further details. This will be used by Mold once it's been vendored
This commit is contained in:
Justine Tunney 2023-07-02 03:50:29 -07:00
parent 7ec84655b4
commit 197aa0d465
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
28 changed files with 617 additions and 355 deletions

View file

@ -45,7 +45,6 @@
#include "libc/str/str.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "libc/str/str.h"
#include "third_party/libcxx/math.h"
#ifdef __x86_64__
@ -230,8 +229,8 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + APE_GUARDSIZE))
? "Stack Overflow"
: GetSiCodeName(sig, si->si_code),
host, getpid(), gettid(), program_invocation_name, strerror(err), names.sysname,
names.version, names.nodename, names.release);
host, getpid(), gettid(), program_invocation_name, strerror(err),
names.sysname, names.version, names.nodename, names.release);
if (ctx) {
p = ShowGeneralRegisters(p, ctx);
p = ShowSseRegisters(p, ctx);
@ -314,6 +313,7 @@ relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
DebugBreak();
} else if (__nocolor || g_isrunningundermake) {
gdbpid = -1;
#if 0
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
// RestoreDefaultCrashSignalHandlers();
gdbpid = AttachDebugger(
@ -321,6 +321,7 @@ relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
(rip >= (intptr_t)&__executable_start && rip < (intptr_t)&_etext))
? rip
: 0);
#endif
}
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
__restore_tty();

View file

@ -16,21 +16,19 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/log/log.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
* Writes error messages to standard error.
*/
void perror(const char *message) {
int err;
err = errno;
if (message && *message) {
fputs(message, stderr);
fputs(": ", stderr);
}
fputs(strerror(err), stderr);
fputc('\n', stderr);
const char *estr;
estr = _strerdoc(errno);
if (!message) message = "";
if (!estr) estr = "Unknown error";
tinyprint(2, message, *message ? ": " : "", estr, "\n", NULL);
}