mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-23 21:23:06 +00:00
Emit long string values without truncation
There are few long options (`bin_shards` and `slab_sizes` for example) when they are specified and we emit statistics value gets truncated. Moved emitting logic for strings into separate `emitter_emit_str` function. It will try to emit string same way as before and if value is too long will fallback emiting rest partially with chunks of `BUF_SIZE`. Justification for long strings (longer than `BUF_SIZE`) is not supported.
This commit is contained in:
@@ -118,6 +118,37 @@ emitter_gen_fmt(char *out_fmt, size_t out_size, const char *fmt_specifier,
|
|||||||
return out_fmt;
|
return out_fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
emitter_emit_str(emitter_t *emitter, emitter_justify_t justify, int width,
|
||||||
|
char *fmt, size_t fmt_size, const char *str) {
|
||||||
|
#define BUF_SIZE 256
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
size_t str_written = malloc_snprintf(buf, BUF_SIZE, "\"%s\"", str);
|
||||||
|
emitter_printf(emitter,
|
||||||
|
emitter_gen_fmt(fmt, fmt_size, "%s", justify, width), buf);
|
||||||
|
if (str_written < BUF_SIZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* There is no support for long string justification at the moment as
|
||||||
|
* we output them partially with multiple malloc_snprintf calls and
|
||||||
|
* justufication will work correctly only withing one call.
|
||||||
|
* Fortunately this is not a big concern as we don't use justufication
|
||||||
|
* with long strings right now.
|
||||||
|
*
|
||||||
|
* We emitted leading quotation mark and trailing '\0', hence need to
|
||||||
|
* exclude extra characters from str shift.
|
||||||
|
*/
|
||||||
|
str += BUF_SIZE - 2;
|
||||||
|
do {
|
||||||
|
str_written = malloc_snprintf(buf, BUF_SIZE, "%s\"", str);
|
||||||
|
str += str_written >= BUF_SIZE ? BUF_SIZE - 1 : str_written;
|
||||||
|
emitter_printf(emitter,
|
||||||
|
emitter_gen_fmt(fmt, fmt_size, "%s", justify, width), buf);
|
||||||
|
} while (str_written >= BUF_SIZE);
|
||||||
|
#undef BUF_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal. Emit the given value type in the relevant encoding (so that the
|
* Internal. Emit the given value type in the relevant encoding (so that the
|
||||||
* bool true gets mapped to json "true", but the string "true" gets mapped to
|
* bool true gets mapped to json "true", but the string "true" gets mapped to
|
||||||
@@ -128,8 +159,6 @@ emitter_gen_fmt(char *out_fmt, size_t out_size, const char *fmt_specifier,
|
|||||||
static inline void
|
static inline void
|
||||||
emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
||||||
emitter_type_t value_type, const void *value) {
|
emitter_type_t value_type, const void *value) {
|
||||||
size_t str_written;
|
|
||||||
#define BUF_SIZE 256
|
|
||||||
#define FMT_SIZE 10
|
#define FMT_SIZE 10
|
||||||
/*
|
/*
|
||||||
* We dynamically generate a format string to emit, to let us use the
|
* We dynamically generate a format string to emit, to let us use the
|
||||||
@@ -138,7 +167,6 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
|||||||
* cases.
|
* cases.
|
||||||
*/
|
*/
|
||||||
char fmt[FMT_SIZE];
|
char fmt[FMT_SIZE];
|
||||||
char buf[BUF_SIZE];
|
|
||||||
|
|
||||||
#define EMIT_SIMPLE(type, format) \
|
#define EMIT_SIMPLE(type, format) \
|
||||||
emitter_printf(emitter, \
|
emitter_printf(emitter, \
|
||||||
@@ -167,15 +195,8 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
|||||||
EMIT_SIMPLE(size_t, "%zu")
|
EMIT_SIMPLE(size_t, "%zu")
|
||||||
break;
|
break;
|
||||||
case emitter_type_string:
|
case emitter_type_string:
|
||||||
str_written = malloc_snprintf(buf, BUF_SIZE, "\"%s\"",
|
emitter_emit_str(emitter, justify, width, fmt, FMT_SIZE,
|
||||||
*(const char *const *)value);
|
*(const char *const *)value);
|
||||||
/*
|
|
||||||
* We control the strings we output; we shouldn't get anything
|
|
||||||
* anywhere near the fmt size.
|
|
||||||
*/
|
|
||||||
assert(str_written < BUF_SIZE);
|
|
||||||
emitter_printf(emitter,
|
|
||||||
emitter_gen_fmt(fmt, FMT_SIZE, "%s", justify, width), buf);
|
|
||||||
break;
|
break;
|
||||||
case emitter_type_uint32:
|
case emitter_type_uint32:
|
||||||
EMIT_SIMPLE(uint32_t, "%" FMTu32)
|
EMIT_SIMPLE(uint32_t, "%" FMTu32)
|
||||||
@@ -189,7 +210,6 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
|||||||
default:
|
default:
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
#undef BUF_SIZE
|
|
||||||
#undef FMT_SIZE
|
#undef FMT_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,6 +222,17 @@ emit_types(emitter_t *emitter) {
|
|||||||
ssize_t zd = -456;
|
ssize_t zd = -456;
|
||||||
size_t zu = 456;
|
size_t zu = 456;
|
||||||
const char *str = "string";
|
const char *str = "string";
|
||||||
|
const char *long_str =
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz";
|
||||||
uint32_t u32 = 789;
|
uint32_t u32 = 789;
|
||||||
uint64_t u64 = 10000000000ULL;
|
uint64_t u64 = 10000000000ULL;
|
||||||
|
|
||||||
@@ -232,8 +243,9 @@ emit_types(emitter_t *emitter) {
|
|||||||
emitter_kv(emitter, "k4", "K4", emitter_type_ssize, &zd);
|
emitter_kv(emitter, "k4", "K4", emitter_type_ssize, &zd);
|
||||||
emitter_kv(emitter, "k5", "K5", emitter_type_size, &zu);
|
emitter_kv(emitter, "k5", "K5", emitter_type_size, &zu);
|
||||||
emitter_kv(emitter, "k6", "K6", emitter_type_string, &str);
|
emitter_kv(emitter, "k6", "K6", emitter_type_string, &str);
|
||||||
emitter_kv(emitter, "k7", "K7", emitter_type_uint32, &u32);
|
emitter_kv(emitter, "k7", "K7", emitter_type_string, &long_str);
|
||||||
emitter_kv(emitter, "k8", "K8", emitter_type_uint64, &u64);
|
emitter_kv(emitter, "k8", "K8", emitter_type_uint32, &u32);
|
||||||
|
emitter_kv(emitter, "k9", "K9", emitter_type_uint64, &u64);
|
||||||
/*
|
/*
|
||||||
* We don't test the title type, since it's only used for tables. It's
|
* We don't test the title type, since it's only used for tables. It's
|
||||||
* tested in the emitter_table_row tests.
|
* tested in the emitter_table_row tests.
|
||||||
@@ -249,8 +261,18 @@ static const char *types_json =
|
|||||||
"\t\"k4\": -456,\n"
|
"\t\"k4\": -456,\n"
|
||||||
"\t\"k5\": 456,\n"
|
"\t\"k5\": 456,\n"
|
||||||
"\t\"k6\": \"string\",\n"
|
"\t\"k6\": \"string\",\n"
|
||||||
"\t\"k7\": 789,\n"
|
"\t\"k7\": \"abcdefghijklmnopqrstuvwxyz "
|
||||||
"\t\"k8\": 10000000000\n"
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz\",\n"
|
||||||
|
"\t\"k8\": 789,\n"
|
||||||
|
"\t\"k9\": 10000000000\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
static const char *types_json_compact =
|
static const char *types_json_compact =
|
||||||
"{"
|
"{"
|
||||||
@@ -260,8 +282,18 @@ static const char *types_json_compact =
|
|||||||
"\"k4\":-456,"
|
"\"k4\":-456,"
|
||||||
"\"k5\":456,"
|
"\"k5\":456,"
|
||||||
"\"k6\":\"string\","
|
"\"k6\":\"string\","
|
||||||
"\"k7\":789,"
|
"\"k7\":\"abcdefghijklmnopqrstuvwxyz "
|
||||||
"\"k8\":10000000000"
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz\","
|
||||||
|
"\"k8\":789,"
|
||||||
|
"\"k9\":10000000000"
|
||||||
"}";
|
"}";
|
||||||
static const char *types_table =
|
static const char *types_table =
|
||||||
"K1: false\n"
|
"K1: false\n"
|
||||||
@@ -270,8 +302,18 @@ static const char *types_table =
|
|||||||
"K4: -456\n"
|
"K4: -456\n"
|
||||||
"K5: 456\n"
|
"K5: 456\n"
|
||||||
"K6: \"string\"\n"
|
"K6: \"string\"\n"
|
||||||
"K7: 789\n"
|
"K7: \"abcdefghijklmnopqrstuvwxyz "
|
||||||
"K8: 10000000000\n";
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz "
|
||||||
|
"abcdefghijklmnopqrstuvwxyz\"\n"
|
||||||
|
"K8: 789\n"
|
||||||
|
"K9: 10000000000\n";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_modal(emitter_t *emitter) {
|
emit_modal(emitter_t *emitter) {
|
||||||
|
|||||||
Reference in New Issue
Block a user