Make exciting improvements

- Add Lua backtraces to redbean!
- Wipe serving keys after redbean forks
- Audit redbean to remove free via exit
- Log SSL client ciphersuite preferences
- Increase ASAN malloc() backtrace depth
- Make GetSslRoots() behave as a singleton
- Move leaks.c from LIBC_TESTLIB to LIBC_LOG
- Add undocumented %n to printf() for newlines
- Fix redbean memory leak reindexing inode change
- Fix redbean memory leak with Fetch() DNS object
- Restore original environ after __cxa_finalize()
- Make backtrace always work after __cxa_finalize()
- Introduce COUNTEXPR() diagnostic / benchmark tool
- Fix a few more instances of errno being clobbered
- Consolidate the ANSI color disabling internal APIs
This commit is contained in:
Justine Tunney 2022-03-18 02:33:37 -07:00
parent f5831a62fa
commit af645fcbec
61 changed files with 1354 additions and 814 deletions

View file

@ -25,6 +25,7 @@
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/stdio/append.internal.h"
@ -84,7 +85,7 @@ char *StackOverrunCrash(int n) {
char *MemoryLeakCrash(void) {
char *p = strdup("doge");
testlib_checkformemoryleaks();
CheckForMemoryLeaks();
return p;
}
@ -123,6 +124,9 @@ void SetUp(void) {
exit((intptr_t)pMemoryLeakCrash());
case 7:
exit(pNpeCrash(0));
case 8:
__cxa_finalize(0);
exit(pNpeCrash(0));
default:
printf("preventing fork recursion: %s\n", __argv[1]);
exit(1);
@ -550,7 +554,7 @@ TEST(ShowCrashReports, testNpeCrash) {
ASSERT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(77, WEXITSTATUS(ws));
/* NULL is stopgap until we can copy symbol tablces into binary */
/* NULL is stopgap until we can copy symbol tables into binary */
if (!strstr(output, "null pointer dereference")) {
fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n",
gc(IndentLines(output, -1, 0, 4)));
@ -619,3 +623,57 @@ TEST(ShowCrashReports, testDataOverrunCrash) {
}
free(output);
}
TEST(ShowCrashReports, testNpeCrashAfterFinalize) {
/*
* this test makes sure we're not doing things like depending on
* environment variables after __cxa_finalize is called in cases
* where putenv() is used
*/
size_t got;
ssize_t rc;
int ws, pid, fds[2];
char *output, buf[512];
ASSERT_NE(-1, pipe2(fds, O_CLOEXEC));
ASSERT_NE(-1, (pid = vfork()));
if (!pid) {
dup2(fds[1], 1);
dup2(fds[1], 2);
execv(program_executable_name,
(char *const[]){program_executable_name, "8", 0});
_exit(127);
}
close(fds[1]);
output = 0;
appends(&output, "");
for (;;) {
rc = read(fds[0], buf, sizeof(buf));
if (rc == -1) {
ASSERT_EQ(EINTR, errno);
continue;
}
if ((got = rc)) {
appendd(&output, buf, got);
} else {
break;
}
}
ASSERT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(IsAsan() ? 77 : 128 + SIGSEGV, WEXITSTATUS(ws));
/* NULL is stopgap until we can copy symbol tables into binary */
if (!strstr(output, IsAsan() ? "null pointer dereference"
: "Uncaught SIGSEGV (SEGV_MAPERR)")) {
fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n",
gc(IndentLines(output, -1, 0, 4)));
__die();
}
#ifdef __FNO_OMIT_FRAME_POINTER__
if (!OutputHasSymbol(output, "NpeCrash")) {
fprintf(stderr, "ERROR: crash report didn't have backtrace\n%s\n",
gc(IndentLines(output, -1, 0, 4)));
__die();
}
#endif
free(output);
}

View file

@ -157,6 +157,16 @@ TEST(appendd, testMemFail_doesntFreeExistingAllocation) {
free(b);
}
TEST(appendd, nontrivialAmountOfMemory) {
char *b = 0;
int i, n = 40000;
for (i = 0; i < n; ++i) {
ASSERT_EQ(2, appendd(&b, "hi", 2));
}
EXPECT_EQ(40000 * 2, appendz(b).i);
free(b);
}
BENCH(vappendf, bench) {
const char t[] = {0};
char *b = 0;