Skip to content

Commit 883b4ae

Browse files
rostedtchucklever
authored andcommitted
tracing: Add trace_event helper macros __string_len() and __assign_str_len()
There's a few cases that a string that is to be recorded in a trace event, does not have a terminating 'nul' character, and instead, the tracepoint passes in the length of the string to record. Add two helper macros to the trace event code that lets this work easier, than tricks with "%.*s" logic. __string_len() which is similar to __string() for declaration, but takes a length argument. __assign_str_len() which is similar to __assign_str() for assiging the string, but it too takes a length argument. Note, the TRACE_EVENT() macro will allocate the location on the ring buffer to 'len + 1', that will be used to store the string into. It is a requirement that the 'len' used for this is a most the length of the string being recorded. This string can still use __get_str() just like strings created with __string() can use to retrieve the string. Link: https://lore.kernel.org/linux-nfs/[email protected]/ Tested-by: Chuck Lever <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 496d83c commit 883b4ae

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

include/trace/trace_events.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ TRACE_MAKE_SYSTEM_STR();
102102
#undef __string
103103
#define __string(item, src) __dynamic_array(char, item, -1)
104104

105+
#undef __string_len
106+
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
107+
105108
#undef __bitmask
106109
#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
107110

@@ -197,6 +200,9 @@ TRACE_MAKE_SYSTEM_STR();
197200
#undef __string
198201
#define __string(item, src) __dynamic_array(char, item, -1)
199202

203+
#undef __string_len
204+
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
205+
200206
#undef __bitmask
201207
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
202208

@@ -459,6 +465,9 @@ static struct trace_event_functions trace_event_type_funcs_##call = { \
459465
#undef __string
460466
#define __string(item, src) __dynamic_array(char, item, -1)
461467

468+
#undef __string_len
469+
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
470+
462471
#undef __bitmask
463472
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
464473

@@ -507,6 +516,9 @@ static struct trace_event_fields trace_event_fields_##call[] = { \
507516
#define __string(item, src) __dynamic_array(char, item, \
508517
strlen((src) ? (const char *)(src) : "(null)") + 1)
509518

519+
#undef __string_len
520+
#define __string_len(item, src, len) __dynamic_array(char, item, (len) + 1)
521+
510522
/*
511523
* __bitmask_size_in_bytes_raw is the number of bytes needed to hold
512524
* num_possible_cpus().
@@ -670,10 +682,20 @@ static inline notrace int trace_event_get_offsets_##call( \
670682
#undef __string
671683
#define __string(item, src) __dynamic_array(char, item, -1)
672684

685+
#undef __string_len
686+
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
687+
673688
#undef __assign_str
674689
#define __assign_str(dst, src) \
675690
strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
676691

692+
#undef __assign_str_len
693+
#define __assign_str_len(dst, src, len) \
694+
do { \
695+
memcpy(__get_str(dst), (src), (len)); \
696+
__get_str(dst)[len] = '\0'; \
697+
} while(0)
698+
677699
#undef __bitmask
678700
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
679701

samples/trace_events/trace-events-sample.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,33 @@
141141
* In most cases, the __assign_str() macro will take the same
142142
* parameters as the __string() macro had to declare the string.
143143
*
144+
* __string_len: This is a helper to a __dynamic_array, but it understands
145+
* that the array has characters in it, and with the combined
146+
* use of __assign_str_len(), it will allocate 'len' + 1 bytes
147+
* in the ring buffer and add a '\0' to the string. This is
148+
* useful if the string being saved has no terminating '\0' byte.
149+
* It requires that the length of the string is known as it acts
150+
* like a memcpy().
151+
*
152+
* Declared with:
153+
*
154+
* __string_len(foo, bar, len)
155+
*
156+
* To assign this string, use the helper macro __assign_str_len().
157+
*
158+
* __assign_str(foo, bar, len);
159+
*
160+
* Then len + 1 is allocated to the ring buffer, and a nul terminating
161+
* byte is added. This is similar to:
162+
*
163+
* memcpy(__get_str(foo), bar, len);
164+
* __get_str(foo)[len] = 0;
165+
*
166+
* The advantage of using this over __dynamic_array, is that it
167+
* takes care of allocating the extra byte on the ring buffer
168+
* for the '\0' terminating byte, and __get_str(foo) can be used
169+
* in the TP_printk().
170+
*
144171
* __bitmask: This is another kind of __dynamic_array, but it expects
145172
* an array of longs, and the number of bits to parse. It takes
146173
* two parameters (name, nr_bits), where name is the name of the

0 commit comments

Comments
 (0)