Add an assert-based segfault handler to etc.linux.memoryerror (#20643)

* Add an assert-based segfault handler to `etc.linux.memoryerror`

* Commit memoryAssertError review feedback

* Indent the MemoryErrorSupported version block

* Fix a bad ucontext_t in memoryerror.d

* Fix bad imports in memoryerror.d

* Use a module-scope version: in memoryerror.d

* Add a memoryerror.d unittest

* Prefer version-else-version... in memoryerror.d
This commit is contained in:
Jonas Meeuws 2025-01-18 22:38:54 +01:00 committed by GitHub
parent e49b67e969
commit d115713410
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 552 additions and 298 deletions

View file

@ -12,7 +12,8 @@ SED:=sed
GDB:=gdb
ifeq ($(OS),linux)
TESTS+=line_trace line_trace_21656 long_backtrace_trunc rt_trap_exceptions cpp_demangle
TESTS+=line_trace line_trace_21656 long_backtrace_trunc rt_trap_exceptions cpp_demangle \
memoryerror_null_read memoryerror_null_write memoryerror_null_call memoryerror_stackoverflow
line_trace_dflags:=-L--export-dynamic
endif
@ -88,6 +89,11 @@ $(ROOT)/rt_trap_exceptions.done: stderr_exp2="src/rt_trap_exceptions.d:8 main"
$(ROOT)/assert_fail.done: stderr_exp="success."
$(ROOT)/cpp_demangle.done: stderr_exp="thrower(int)"
$(ROOT)/message_with_null.done: stderr_exp=" world"
$(ROOT)/memoryerror_null_read.done: stderr_exp="segmentation fault: null pointer read/write operation"
$(ROOT)/memoryerror_null_write.done: stderr_exp="segmentation fault: null pointer read/write operation"
$(ROOT)/memoryerror_null_call.done: stderr_exp="segmentation fault: null pointer read/write operation"
$(ROOT)/memoryerror_null_call.done: stderr_exp2="uncaught exception reached top of stack"
$(ROOT)/memoryerror_stackoverflow.done: stderr_exp="segmentation fault: call stack overflow"
$(ROOT)/%.done: $(ROOT)/%$(DOTEXE)
@echo Testing $*

View file

@ -0,0 +1,9 @@
import etc.linux.memoryerror;
void function() foo = null;
void main()
{
registerMemoryAssertHandler;
foo();
}

View file

@ -0,0 +1,9 @@
import etc.linux.memoryerror;
int* x = null;
void main()
{
registerMemoryAssertHandler;
*x = 3;
}

View file

@ -0,0 +1,9 @@
import etc.linux.memoryerror;
int* x = null;
int main()
{
registerMemoryAssertHandler;
return *x;
}

View file

@ -0,0 +1,22 @@
import etc.linux.memoryerror;
pragma(inline, false):
void f(ref ubyte[1024] buf)
{
ubyte[1024] cpy = buf;
g(cpy);
}
void g(ref ubyte[1024] buf)
{
ubyte[1024] cpy = buf;
f(cpy);
}
void main()
{
registerMemoryAssertHandler;
ubyte[1024] buf;
f(buf);
}