mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-09 10:55:34 +00:00
Fix segfault by adding type annotations
This commit is contained in:
parent
d6e802c50f
commit
e2a60faa35
3 changed files with 23 additions and 6 deletions
|
|
@ -1166,22 +1166,26 @@ test "fx platform runtime stack overflow" {
|
|||
defer allocator.free(run_result.stdout);
|
||||
defer allocator.free(run_result.stderr);
|
||||
|
||||
// After stack overflow handling is implemented, we expect:
|
||||
// 1. The process exits with code 134 (indicating stack overflow was caught)
|
||||
// 2. Stderr contains a helpful message about stack overflow
|
||||
// Stack overflow can be caught by either:
|
||||
// 1. The Roc interpreter (exit code 1, "overflowed its stack memory" message) - most common
|
||||
// 2. The SIGABRT signal handler (exit code 134) - if native stack overflow handling is used
|
||||
switch (run_result.term) {
|
||||
.Exited => |code| {
|
||||
if (code == 134) {
|
||||
// Stack overflow was caught and handled properly
|
||||
// Stack overflow was caught by native signal handler
|
||||
// Verify the helpful error message was printed
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stderr, "overflowed its stack memory") != null);
|
||||
} else if (code == 1) {
|
||||
// Stack overflow was caught by the interpreter - this is the expected case
|
||||
// The interpreter detects excessive work stack depth and reports the error
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stderr, "overflowed its stack memory") != null);
|
||||
} else if (code == 139) {
|
||||
// Exit code 139 = 128 + 11 (SIGSEGV) - stack overflow was NOT handled
|
||||
// The Roc program crashed with a segfault that wasn't caught
|
||||
std.debug.print("\n", .{});
|
||||
std.debug.print("Stack overflow handling NOT YET IMPLEMENTED for Roc programs.\n", .{});
|
||||
std.debug.print("Process crashed with SIGSEGV (exit code 139).\n", .{});
|
||||
std.debug.print("Expected: exit code 134 with stack overflow message\n", .{});
|
||||
std.debug.print("Expected: exit code 1 or 134 with stack overflow message\n", .{});
|
||||
return error.StackOverflowNotHandled;
|
||||
} else {
|
||||
std.debug.print("Unexpected exit code: {}\n", .{code});
|
||||
|
|
@ -1194,7 +1198,7 @@ test "fx platform runtime stack overflow" {
|
|||
std.debug.print("\n", .{});
|
||||
std.debug.print("Stack overflow handling NOT YET IMPLEMENTED for Roc programs.\n", .{});
|
||||
std.debug.print("Process was killed by signal: {}\n", .{sig});
|
||||
std.debug.print("Expected: exit code 134 with stack overflow message\n", .{});
|
||||
std.debug.print("Expected: exit code 1 or 134 with stack overflow message\n", .{});
|
||||
return error.StackOverflowNotHandled;
|
||||
},
|
||||
else => {
|
||||
|
|
|
|||
|
|
@ -9550,6 +9550,11 @@ pub const Interpreter = struct {
|
|||
pub const WorkStack = struct {
|
||||
items: std.array_list.AlignedManaged(WorkItem, null),
|
||||
|
||||
/// Maximum work stack size to prevent infinite recursion from hanging.
|
||||
/// When exceeded, triggers a stack overflow error.
|
||||
/// 10,000 items allows deep but not infinite recursion (~1MB memory).
|
||||
pub const max_size: usize = 10_000;
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !WorkStack {
|
||||
return .{ .items = try std.array_list.AlignedManaged(WorkItem, null).initCapacity(allocator, 64) };
|
||||
}
|
||||
|
|
@ -9650,6 +9655,12 @@ pub const Interpreter = struct {
|
|||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Check for stack overflow (infinite recursion)
|
||||
if (work_stack.items.items.len > WorkStack.max_size) {
|
||||
self.triggerCrash("This Roc program overflowed its stack memory. This usually means there is infinite recursion somewhere in the code.", false, roc_ops);
|
||||
return error.Crash;
|
||||
}
|
||||
}
|
||||
|
||||
// Should never reach here - return_result should have exited the loop
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ parse_range = |range_str| {
|
|||
}
|
||||
|
||||
|
||||
repeat : List(a), U64 -> List(a)
|
||||
repeat = |list, n| repeat_helper([], list, n)
|
||||
|
||||
repeat_helper : List(a), List(a), U64 -> List(a)
|
||||
repeat_helper = |acc, list, n| match n {
|
||||
0 => acc
|
||||
_ => repeat_helper(acc.concat(list), list, n - 1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue