11#include " test_common.h"
2+ #include < poll.h>
3+ #include < signal.h>
4+ #include < sys/wait.h>
5+ #include < unistd.h>
26TEST_START
37
48extern " C" uint32_t stack_spSizeFree (Stack* stack);
9+ extern " C" void _stack_overflow_handler (Stack* stack, size_t stack_require);
510
611TEST (stack, size_array_capacity) {
712 Stack stack = {0 };
@@ -14,6 +19,63 @@ TEST(stack, size_array_capacity) {
1419 EXPECT_EQ (pikaMemNow (), 0 );
1520}
1621
22+ TEST (stack, fatal_overflow_reports_before_stopping) {
23+ int output_pipe[2 ] = {-1 , -1 };
24+ ASSERT_EQ (pipe (output_pipe), 0 );
25+ fflush (stdout);
26+
27+ pid_t child = fork ();
28+ ASSERT_NE (child, -1 );
29+ if (child == 0 ) {
30+ close (output_pipe[0 ]);
31+ if (dup2 (output_pipe[1 ], STDOUT_FILENO ) == -1 ) {
32+ _exit (100 );
33+ }
34+ close (output_pipe[1 ]);
35+
36+ static char output_buffer[1024 ];
37+ setvbuf (stdout, output_buffer, _IOFBF, sizeof (output_buffer));
38+ Stack stack = {0 };
39+ stack.stack_totle_size = 64 ;
40+ _stack_overflow_handler (&stack, 80 );
41+ _exit (101 );
42+ }
43+
44+ close (output_pipe[1 ]);
45+ struct pollfd output = {output_pipe[0 ], POLLIN , 0 };
46+ char report[1024 ] = {0 };
47+ size_t report_size = 0 ;
48+ for (int retry = 0 ; retry < 100 ; retry++) {
49+ int poll_result = poll (&output, 1 , 10 );
50+ if (poll_result == 1 ) {
51+ ssize_t size =
52+ read (output_pipe[0 ], report + report_size,
53+ sizeof (report) - report_size - 1 );
54+ if (size > 0 ) {
55+ report_size += (size_t )size;
56+ }
57+ }
58+ if (strstr (report, " execution stopped" ) != nullptr ) {
59+ break ;
60+ }
61+ }
62+ EXPECT_GT (report_size, 0 );
63+ EXPECT_NE (strstr (report, " FatalError: VM stack exhausted" ), nullptr );
64+ EXPECT_NE (strstr (report, " 80/64 bytes, PIKA_STACK_BUFF_SIZE" ), nullptr );
65+ EXPECT_NE (strstr (report, " execution stopped" ), nullptr );
66+
67+ int status = 0 ;
68+ pid_t wait_result = waitpid (child, &status, WNOHANG );
69+ EXPECT_EQ (wait_result, 0 );
70+ if (wait_result == 0 ) {
71+ EXPECT_EQ (kill (child, SIGKILL ), 0 );
72+ EXPECT_EQ (waitpid (child, &status, 0 ), child);
73+ EXPECT_TRUE (WIFSIGNALED (status));
74+ EXPECT_EQ (WTERMSIG (status), SIGKILL );
75+ }
76+ close (output_pipe[0 ]);
77+ }
78+
1779TEST_RUN_LINES_EXCEPT_OUTPUT (
1880 issue,
1981 issue356_top_level_function_refs,
0 commit comments