Segfault are often repeated massively. This adds a repeat_printf function that will not reprint the line but count them if repeated.
This commit is contained in:
parent
67cc618a16
commit
9159153caf
@ -154,7 +154,7 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Warning: Skipping SEGFAULT %X\n", *code);
|
||||
repeat_printf("Warning: Skipping SEGFAULT %X\n", *code);
|
||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||
// abort();
|
||||
}
|
||||
@ -1027,3 +1027,105 @@ char *__strdup(const char *string)
|
||||
}
|
||||
return ___strdup(string);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Prints formatted text in a way that avoids spamming identical lines.
|
||||
*
|
||||
* This function behaves similarly to printf, but tracks the last printed message.
|
||||
* If the newly formatted string is identical to the last one, the previous console
|
||||
* line is overwritten and a repetition counter "(xN)" is appended instead of
|
||||
* printing a new line.
|
||||
*
|
||||
* @details
|
||||
* Usage:
|
||||
* 1. Call `repeat_printf("Some message");` as you would call printf(...).
|
||||
* 2. If the next call uses the exact same message, the console line updates
|
||||
* to "... (x2)", then "... (x3)", etc.
|
||||
* 3. If the next call uses a different message, the old message is finalized
|
||||
* (a newline is printed) and the new message is printed on a fresh line.
|
||||
* 4. Calling `live_printf("")` or `repeat_printf(NULL)` finalizes the current
|
||||
* message (if any) and resets the internal state.
|
||||
*
|
||||
* If the message ends with a newline ('\n'), the cursor is moved up one line
|
||||
* after printing. This allows consecutive identical lines that end with '\n'
|
||||
* to be updated in place, though note it may be visually confusing if your
|
||||
* terminal is at the top line.
|
||||
*
|
||||
* @param format A printf-style format string, or NULL. If NULL or an empty
|
||||
* string results from formatting, the current tracked message
|
||||
* is finalized (a newline is printed, and the internal state
|
||||
* is reset).
|
||||
* @param ... Variadic arguments for the format string.
|
||||
*
|
||||
* @return (void) No return value.
|
||||
*/
|
||||
void repeat_printf(const char *format, ...)
|
||||
{
|
||||
static char last_msg[256] = {0};
|
||||
static u_int repeat_count = 0;
|
||||
|
||||
// If format is NULL, treat it as an empty string to trigger finalization.
|
||||
if (format == NULL) {
|
||||
format = "";
|
||||
}
|
||||
|
||||
// Construct the new message using vsnprintf (like printf).
|
||||
char msg[256];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
va_end(args);
|
||||
|
||||
// If the constructed message is empty, finalize and reset.
|
||||
if (msg[0] == '\0') {
|
||||
if (repeat_count > 0) {
|
||||
// Finalize the previous message with a newline.
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
// Reset tracking variables.
|
||||
last_msg[0] = '\0';
|
||||
repeat_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the new message is the same as the last one.
|
||||
if (strcmp(last_msg, msg) == 0) {
|
||||
// Same message => increment counter, overwrite the line.
|
||||
repeat_count++;
|
||||
|
||||
// If the message ends with new line, we go up one line
|
||||
size_t len = strlen(msg);
|
||||
int ends_with_newline = 0;
|
||||
if (len > 0 && msg[len - 1] == '\n') {
|
||||
printf("\033[1A");
|
||||
ends_with_newline = 1;
|
||||
msg[len - 1] = '\0'; // Remove the trailing '\n'
|
||||
}
|
||||
// Move cursor to the start of the line and clear it.
|
||||
printf("\r\033[K");
|
||||
// Print the message with the updated repeat count if > 1
|
||||
if (repeat_count > 1) {
|
||||
printf("%s (x%d)", msg, repeat_count);
|
||||
} else {
|
||||
// If repeat_count == 1, it means the first time for this message
|
||||
// on this call. (Normally we shouldn't enter here with == 1 though.)
|
||||
printf("%s", msg);
|
||||
}
|
||||
if (ends_with_newline) {
|
||||
// Print a newline, then move cursor up one line
|
||||
printf("\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
} else {
|
||||
// Track the new message.
|
||||
strncpy(last_msg, msg, sizeof(last_msg) - 1);
|
||||
last_msg[sizeof(last_msg) - 1] = '\0';
|
||||
repeat_count = 1;
|
||||
|
||||
// Print the new message on a fresh line.
|
||||
printf("%s", msg);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
@ -2,3 +2,4 @@
|
||||
#include <stddef.h>
|
||||
|
||||
uint32_t get_crc32(const char *s, size_t n);
|
||||
void repeat_printf(const char *format, ...);
|
||||
|
Loading…
x
Reference in New Issue
Block a user