diff --git a/315stack-debug.subx b/315stack-debug.subx new file mode 100644 index 00000000..9734fd7a --- /dev/null +++ b/315stack-debug.subx @@ -0,0 +1,51 @@ +# The stack shouldn't grow into the code area. + +== code + +check-stack: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + # + 89/<- %eax 4/r32/esp + 81 7/subop/compare %eax 0x48600/imm32 + { + 7f/jump-if-> break/disp8 + (abort "stack overflow") + } +$check-stack:end: + # . restore registers + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +show-stack-state: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + # + 89/<- %edx 4/r32/esp + # save old cursor position + (cursor-position 0) # => eax, ecx + # print at top-right + (set-cursor-position 0 0x70 0) + (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 0xf 0xc) + # restore cursor position + (set-cursor-position %eax %ecx) +$check-stack:end: + # . restore registers + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/400.mu b/400.mu index a31edbb6..a5064018 100644 --- a/400.mu +++ b/400.mu @@ -23,6 +23,10 @@ sig string-equal? s: (addr array byte), benchmark: (addr array byte) -> _/eax: b sig string-starts-with? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean sig check-strings-equal s: (addr array byte), expected: (addr array byte), msg: (addr array byte) +# debugging +sig check-stack +sig show-stack-state + # streams sig clear-stream f: (addr stream _) sig rewind-stream f: (addr stream _) diff --git a/shell/evaluate.mu b/shell/evaluate.mu index fa8610c7..8dd794db 100644 --- a/shell/evaluate.mu +++ b/shell/evaluate.mu @@ -2,6 +2,9 @@ # we never modify `in` or `env` # ignore 'screen-cell' on a first reading; it's a hack for sandboxes fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) { + # stack overflow? + check-stack + show-stack-state # errors? skip { compare trace, 0