Re: [PATCH v2 01/25] NFSD: Fix TP_printk() format specifier in trace_nfsd_dirent()
From: Steven Rostedt <rostedt@goodmis.org>
Date: 2021-05-13 14:52:25
Subsystem:
the rest, tracing · Maintainers:
Linus Torvalds, Steven Rostedt, Masami Hiramatsu
On Wed, 12 May 2021 16:52:05 +0000 Chuck Lever III [off-list ref] 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)