mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-29 05:50:27 +00:00
Improve memory safety
This commit makes numerous refinements to cosmopolitan memory handling. The default stack size has been reduced from 2mb to 128kb. A new macro is now provided so you can easily reconfigure the stack size to be any value you want. Work around the breaking change by adding to your main: STATIC_STACK_SIZE(0x00200000); // 2mb stack If you're not sure how much stack you need, then you can use: STATIC_YOINK("stack_usage_logging"); After which you can `sort -nr o/$MODE/stack.log`. Based on the unit test suite, nothing in the Cosmopolitan repository (except for Python) needs a stack size greater than 30kb. There are also new macros for detecting the size and address of the stack at runtime, e.g. GetStackAddr(). We also now support sigaltstack() so if you want to see nice looking crash reports whenever a stack overflow happens, you can put this in main(): ShowCrashReports(); Under `make MODE=dbg` and `make MODE=asan` the unit testing framework will now automatically print backtraces of memory allocations when things like memory leaks happen. Bugs are now fixed in ASAN global variable overrun detection. The memtrack and asan runtimes also handle edge cases now. The new tools helped to identify a few memory leaks, which are fixed by this change. This change should fix an issue reported in #288 with ARG_MAX limits. Fixing this doubled the performance of MKDEPS.COM and AR.COM yet again.
This commit is contained in:
parent
a0b39f886c
commit
226aaf3547
317 changed files with 6474 additions and 3993 deletions
127
third_party/linenoise/linenoise.c
vendored
127
third_party/linenoise/linenoise.c
vendored
|
@ -257,6 +257,7 @@ static struct sigaction orig_cont;
|
|||
static struct sigaction orig_winch;
|
||||
static struct termios orig_termios;
|
||||
static char *history[LINENOISE_MAX_HISTORY];
|
||||
static linenoiseXlatCallback *xlatCallback;
|
||||
static linenoiseHintsCallback *hintsCallback;
|
||||
static linenoiseFreeHintsCallback *freeHintsCallback;
|
||||
static linenoiseCompletionCallback *completionCallback;
|
||||
|
@ -422,12 +423,19 @@ static char HasPendingInput(int fd) {
|
|||
return poll((struct pollfd[]){{fd, POLLIN}}, 1, 0) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns UNICODE CJK Monospace Width of string.
|
||||
*
|
||||
* Control codes and ANSI sequences have a width of zero. We only parse
|
||||
* a limited subset of ANSI here since we don't store ANSI codes in the
|
||||
* linenoiseState::buf, but we do encourage CSI color codes in prompts.
|
||||
*/
|
||||
static size_t GetMonospaceWidth(const char *p, size_t n, char *out_haswides) {
|
||||
int c, d;
|
||||
size_t i, w;
|
||||
struct rune r;
|
||||
char haswides;
|
||||
enum { kAscii, kUtf8, kEsc, kCsi1, kCsi2, kSs, kNf, kStr, kStr2 } t;
|
||||
enum { kAscii, kUtf8, kEsc, kCsi1, kCsi2 } t;
|
||||
for (haswides = r.c = r.n = t = w = i = 0; i < n; ++i) {
|
||||
c = p[i] & 255;
|
||||
switch (t) {
|
||||
|
@ -451,87 +459,26 @@ static size_t GetMonospaceWidth(const char *p, size_t n, char *out_haswides) {
|
|||
r.c <<= 6;
|
||||
r.c |= c & 077;
|
||||
if (!--r.n) {
|
||||
switch (r.c) {
|
||||
case 033:
|
||||
t = kEsc;
|
||||
break;
|
||||
case 0x9b:
|
||||
t = kCsi1;
|
||||
break;
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
t = kSs;
|
||||
break;
|
||||
case 0x90:
|
||||
case 0x98:
|
||||
case 0x9d:
|
||||
case 0x9e:
|
||||
case 0x9f:
|
||||
t = kStr;
|
||||
break;
|
||||
default:
|
||||
d = wcwidth(r.c);
|
||||
d = MAX(0, d);
|
||||
w += d;
|
||||
haswides |= d > 1;
|
||||
t = kAscii;
|
||||
break;
|
||||
}
|
||||
d = wcwidth(r.c);
|
||||
d = MAX(0, d);
|
||||
w += d;
|
||||
haswides |= d > 1;
|
||||
t = kAscii;
|
||||
}
|
||||
} else {
|
||||
goto Whoopsie;
|
||||
}
|
||||
break;
|
||||
case kEsc:
|
||||
if (0x20 <= c && c <= 0x2f) {
|
||||
t = kNf;
|
||||
} else if (0x30 <= c && c <= 0x3f) {
|
||||
t = kAscii;
|
||||
} else if (0x20 <= c && c <= 0x5F) {
|
||||
switch (c) {
|
||||
case '[':
|
||||
t = kCsi1;
|
||||
break;
|
||||
case 'N':
|
||||
case 'O':
|
||||
t = kSs;
|
||||
break;
|
||||
case 'P':
|
||||
case 'X':
|
||||
case ']':
|
||||
case '^':
|
||||
case '_':
|
||||
t = kStr;
|
||||
break;
|
||||
case '\\':
|
||||
goto Whoopsie;
|
||||
default:
|
||||
t = kAscii;
|
||||
break;
|
||||
}
|
||||
} else if (0x60 <= c && c <= 0x7e) {
|
||||
t = kAscii;
|
||||
} else if (c == 033) {
|
||||
if (i == 3) t = kAscii;
|
||||
if (c == '[') {
|
||||
t = kCsi1;
|
||||
} else {
|
||||
t = kAscii;
|
||||
}
|
||||
break;
|
||||
case kSs:
|
||||
t = kAscii;
|
||||
break;
|
||||
case kNf:
|
||||
if (0x30 <= c && c <= 0x7e) {
|
||||
t = kAscii;
|
||||
} else if (!(0x20 <= c && c <= 0x2f)) {
|
||||
goto Whoopsie;
|
||||
}
|
||||
break;
|
||||
case kCsi1:
|
||||
if (0x20 <= c && c <= 0x2f) {
|
||||
t = kCsi2;
|
||||
} else if (c == '[' && i == 3) {
|
||||
/* linux function keys */
|
||||
} else if (0x40 <= c && c <= 0x7e) {
|
||||
t = kAscii;
|
||||
} else if (!(0x30 <= c && c <= 0x3f)) {
|
||||
|
@ -545,31 +492,6 @@ static size_t GetMonospaceWidth(const char *p, size_t n, char *out_haswides) {
|
|||
goto Whoopsie;
|
||||
}
|
||||
break;
|
||||
case kStr:
|
||||
switch (c) {
|
||||
case '\a':
|
||||
t = kAscii;
|
||||
break;
|
||||
case 0033:
|
||||
case 0302:
|
||||
t = kStr2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kStr2:
|
||||
switch (c) {
|
||||
case '\a':
|
||||
case '\\':
|
||||
case 0234:
|
||||
t = kAscii;
|
||||
break;
|
||||
default:
|
||||
t = kStr;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -1745,8 +1667,10 @@ static void linenoiseEditCtrlq(struct linenoiseState *l) {
|
|||
static ssize_t linenoiseEdit(int stdin_fd, int stdout_fd, const char *prompt,
|
||||
char **obuf) {
|
||||
ssize_t rc;
|
||||
uint64_t w;
|
||||
size_t nread;
|
||||
char *p, seq[16];
|
||||
struct rune rune;
|
||||
struct linenoiseState l;
|
||||
bzero(&l, sizeof(l));
|
||||
if (!(l.buf = malloc((l.buflen = 32)))) return -1;
|
||||
|
@ -1914,6 +1838,14 @@ static ssize_t linenoiseEdit(int stdin_fd, int stdout_fd, const char *prompt,
|
|||
break;
|
||||
default:
|
||||
if (!iswcntrl(seq[0])) { /* only sees canonical c0 */
|
||||
if (xlatCallback) {
|
||||
rune = GetUtf8(seq, nread);
|
||||
w = tpenc(xlatCallback(rune.c));
|
||||
nread = 0;
|
||||
do {
|
||||
seq[nread++] = w;
|
||||
} while ((w >>= 8));
|
||||
}
|
||||
linenoiseEditInsert(&l, seq, nread);
|
||||
}
|
||||
break;
|
||||
|
@ -2200,6 +2132,13 @@ void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
|
|||
freeHintsCallback = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets character translation callback.
|
||||
*/
|
||||
void linenoiseSetXlatCallback(linenoiseXlatCallback *fn) {
|
||||
xlatCallback = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds completion.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue