On Wed, 12 May 2021 16:52:05 +0000 Chuck Lever III <chuck.lever@xxxxxxxxxx> wrote: > The underlying need is to support non-NUL-terminated C strings. > > I assumed that since the commentary around 9a6944fee68e claims > the proper way to trace C strings is to use __string and friends, > and those do not support non-NUL-terminated strings, that such > strings are really not first-class citizens. Thus I concluded > that my use of '%.*s' was incorrect. > > Having some __string-style helpers that can deal with such > strings would be valuable. I guess the best I can do is a strncpy version, that will add the '\0' in the ring buffer. That way we don't need to save the length as well (length would need to be at least 4 bytes, where as '\0' is one). Something like this? I added "__string_len()" and "__assign_str_len()". You use them just like __string() and __assign_str() but add a max length that you want to use (although, it will always allocate "len" regardless if the string is smaller). Then use __get_str() just like you use __string(). Would something like that work? -- Steve diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h index 8268bf747d6f..7ab23535a0c8 100644 --- a/include/trace/trace_events.h +++ b/include/trace/trace_events.h @@ -102,6 +102,9 @@ TRACE_MAKE_SYSTEM_STR(); #undef __string #define __string(item, src) __dynamic_array(char, item, -1) +#undef __string_len +#define __string_len(item, src, len) __dynamic_array(char, item, -1) + #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(char, item, -1) @@ -197,6 +200,9 @@ TRACE_MAKE_SYSTEM_STR(); #undef __string #define __string(item, src) __dynamic_array(char, item, -1) +#undef __string_len +#define __string_len(item, src, len) __dynamic_array(char, item, -1) + #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) @@ -444,6 +450,9 @@ static struct trace_event_functions trace_event_type_funcs_##call = { \ #undef __string #define __string(item, src) __dynamic_array(char, item, -1) +#undef __string_len +#define __string_len(item, src, len) __dynamic_array(char, item, -1) + #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) @@ -492,6 +501,9 @@ static struct trace_event_fields trace_event_fields_##call[] = { \ #define __string(item, src) __dynamic_array(char, item, \ strlen((src) ? (const char *)(src) : "(null)") + 1) +#undef __string_len +#define __string_len(item, src, len) __dynamic_array(char, item, (len) + 1) + /* * __bitmask_size_in_bytes_raw is the number of bytes needed to hold * num_possible_cpus(). @@ -655,10 +667,18 @@ static inline notrace int trace_event_get_offsets_##call( \ #undef __string #define __string(item, src) __dynamic_array(char, item, -1) +#undef __string_len +#define __string_len(item, src, len) __dynamic_array(char, item, -1) + #undef __assign_str #define __assign_str(dst, src) \ strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); +#undef __assign_str_len +#define __assign_str_len(dst, src, len) \ + strncpy(__get_str(dst), (src) ? (const char *)(src) : "(null)", len); \ + __get_str(dst)[len] = '\0'; + #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)