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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Warning: Skipping SEGFAULT %X\n", *code);
|
repeat_printf("Warning: Skipping SEGFAULT %X\n", *code);
|
||||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||||
// abort();
|
// abort();
|
||||||
}
|
}
|
||||||
@ -1027,3 +1027,105 @@ char *__strdup(const char *string)
|
|||||||
}
|
}
|
||||||
return ___strdup(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>
|
#include <stddef.h>
|
||||||
|
|
||||||
uint32_t get_crc32(const char *s, size_t n);
|
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