> On May 13, 2021, at 10:50 AM, Steven Rostedt <rostedt@xxxxxxxxxxx> wrote: > > 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? That looks about right! With the caveat that a non-NUL-terminated string might contain a NUL. When displayed with '%s', such a string would be truncated. > 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) > > > -- Chuck Lever