[gk] Increase print buffer, add size check (#3826)

This should fix the crash when entering the freedom HQ elevator. It was
caused by a large number of prints, one for each process in the city
being killed by `check-for-rougue-process`, which would overflow the
print buffer. So I increased the print buffer.

Detecting buffer overflow here is hard because lots of things are
allowed to write to it, including the user's GOAL print methods. I added
a basic check that will assert when there's 1k or less space in the
buffer. It won't catch every overflow, but it would have caught this
one.

Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
water111
2025-01-05 11:05:09 -05:00
committed by GitHub
parent e30dc9ecc7
commit 79e4e36878
5 changed files with 24 additions and 1 deletions
+11
View File
@@ -32,6 +32,7 @@ Ptr<u8> OutputBufArea;
// Pointer to print buffer, the buffer for printing and string formatting.
Ptr<u8> PrintBufArea;
size_t PrintBufSize = 0;
// integer printing conversion table
char ConvertTable[16];
@@ -49,6 +50,7 @@ void kprint_init_globals_common() {
MessBufArea.offset = 0;
OutputBufArea.offset = 0;
PrintBufArea.offset = 0;
PrintBufSize = 0;
memcpy(ConvertTable, "0123456789abcdef", 16);
memset(AckBufArea, 0, sizeof(AckBufArea));
}
@@ -83,6 +85,7 @@ void init_output() {
KMALLOC_MEMSET | KMALLOC_ALIGN_256, "output-buf");
PrintBufArea = kmalloc(kdebugheap, DEBUG_PRINT_BUFFER_SIZE, KMALLOC_MEMSET | KMALLOC_ALIGN_256,
"print-buf");
PrintBufSize = DEBUG_PRINT_BUFFER_SIZE;
} else {
// no compiler connection, so we do not allocate buffers
MessBufArea = Ptr<u8>(0);
@@ -91,6 +94,7 @@ void init_output() {
// we still need a (small) print buffer for string maniuplation and debugging prints.
PrintBufArea =
kmalloc(kglobalheap, PRINT_BUFFER_SIZE, KMALLOC_MEMSET | KMALLOC_ALIGN_256, "print-buf");
PrintBufSize = PRINT_BUFFER_SIZE;
}
}
@@ -574,3 +578,10 @@ char* kitoa(char* buffer, s64 value, u64 base, s32 length, char pad, u32 flag) {
void kqtoa() {
ASSERT(false);
}
void assert_print_buffer_has_room(const u8* ptr) {
const size_t size_used = ptr - PrintBufArea.c();
if (size_used > (PrintBufSize - 1024)) {
lg::die("Print Buffer Overflow: size 0x{:x} of 0x{:x}", size_used, PrintBufSize);
}
}
+7 -1
View File
@@ -15,11 +15,12 @@ extern char ConvertTable[16]; // todo rm
extern Ptr<u8> MessBufArea;
extern Ptr<u8> OutputBufArea;
extern Ptr<u8> PrintBufArea;
extern size_t PrintBufSize; // added
constexpr u32 DEBUG_MESSAGE_BUFFER_SIZE = 0x80000;
constexpr u32 DEBUG_OUTPUT_BUFFER_SIZE = 0x80000;
constexpr u32 DEBUG_PRINT_BUFFER_SIZE = 0x200000;
constexpr u32 PRINT_BUFFER_SIZE = 0x8000; // upped from 0x2000 on PS2 because we ran out of memory
constexpr u32 PRINT_BUFFER_SIZE = 0x10000; // upped from 0x2000 on PS2 because we ran out of memory
struct format_struct {
char data[0x40];
@@ -142,3 +143,8 @@ char* kitoa(char* buffer, s64 value, u64 base, s32 length, char pad, u32 flag);
* getting a 128-bit integer in PS2 gcc's varargs doesn't work.
*/
void kqtoa();
/*!
* Make sure we have at least 1024 bytes left in the print buffer.
*/
void assert_print_buffer_has_room(const u8* ptr);
+2
View File
@@ -54,6 +54,7 @@ s32 format_impl_jak1(uint64_t* args) {
print_temp = PrintBufArea.cast<char>().c() + sizeof(ListenerMessageHeader);
}
PrintPending = make_ptr(strend(print_temp)).cast<u8>();
assert_print_buffer_has_room(PrintPending.c());
// what we write to
char* output_ptr = PrintPending.cast<char>().c();
@@ -498,6 +499,7 @@ s32 format_impl_jak1(uint64_t* args) {
// end
*output_ptr = 0;
output_ptr++;
assert_print_buffer_has_room((const u8*)output_ptr);
if (original_dest == s7.offset + FIX_SYM_TRUE) {
// do nothing, we're done
+2
View File
@@ -77,6 +77,7 @@ s32 format_impl_jak2(uint64_t* args) {
print_temp = PrintBufArea.cast<char>().c() + sizeof(ListenerMessageHeader);
}
PrintPending = make_ptr(strend(print_temp)).cast<u8>();
assert_print_buffer_has_room(PrintPending.c());
// what we write to
char* output_ptr = PrintPending.cast<char>().c();
@@ -535,6 +536,7 @@ s32 format_impl_jak2(uint64_t* args) {
// end
*output_ptr = 0;
output_ptr++;
assert_print_buffer_has_room((const u8*)output_ptr);
if (original_dest == s7.offset + FIX_SYM_TRUE) {
// #t means to put it in the print buffer
+2
View File
@@ -47,6 +47,7 @@ s32 format_impl_jak3(uint64_t* args) {
print_temp = PrintBufArea.cast<char>().c() + sizeof(ListenerMessageHeader);
}
PrintPending = make_ptr(strend(print_temp)).cast<u8>();
assert_print_buffer_has_room(PrintPending.c());
// what we write to
char* output_ptr = PrintPending.cast<char>().c();
@@ -505,6 +506,7 @@ s32 format_impl_jak3(uint64_t* args) {
// end
*output_ptr = 0;
output_ptr++;
assert_print_buffer_has_room((const u8*)output_ptr);
if (original_dest == s7.offset + FIX_SYM_TRUE) {
// #t means to put it in the print buffer