tracing/events: record the size of dynamic arrays
When a dynamic array is defined, we add __data_loc_foo in trace_entry to record the offset of the array, but the size of the array is not recorded, which causes 2 problems: - the event filter just compares the first 2 chars of the strings. - parsers can't parse dynamic arrays. So we encode the size of each dynamic array in the higher 16 bits of __data_loc_foo, while the offset is in lower 16 bits. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> LKML-Reference: <4A5E964A.9000403@cn.fujitsu.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
Родитель
68fd60a8c8
Коммит
7d536cb3fb
|
@ -25,7 +25,7 @@
|
|||
#define __array(type, item, len) type item[len];
|
||||
|
||||
#undef __dynamic_array
|
||||
#define __dynamic_array(type, item, len) unsigned short __data_loc_##item;
|
||||
#define __dynamic_array(type, item, len) u32 __data_loc_##item;
|
||||
|
||||
#undef __string
|
||||
#define __string(item, src) __dynamic_array(char, item, -1)
|
||||
|
@ -51,13 +51,14 @@
|
|||
* Include the following:
|
||||
*
|
||||
* struct ftrace_data_offsets_<call> {
|
||||
* int <item1>;
|
||||
* int <item2>;
|
||||
* u32 <item1>;
|
||||
* u32 <item2>;
|
||||
* [...]
|
||||
* };
|
||||
*
|
||||
* The __dynamic_array() macro will create each int <item>, this is
|
||||
* The __dynamic_array() macro will create each u32 <item>, this is
|
||||
* to keep the offset of each array from the beginning of the event.
|
||||
* The size of an array is also encoded, in the higher 16 bits of <item>.
|
||||
*/
|
||||
|
||||
#undef __field
|
||||
|
@ -67,7 +68,7 @@
|
|||
#define __array(type, item, len)
|
||||
|
||||
#undef __dynamic_array
|
||||
#define __dynamic_array(type, item, len) int item;
|
||||
#define __dynamic_array(type, item, len) u32 item;
|
||||
|
||||
#undef __string
|
||||
#define __string(item, src) __dynamic_array(char, item, -1)
|
||||
|
@ -207,7 +208,7 @@ ftrace_format_##call(struct trace_seq *s) \
|
|||
|
||||
#undef __get_dynamic_array
|
||||
#define __get_dynamic_array(field) \
|
||||
((void *)__entry + __entry->__data_loc_##field)
|
||||
((void *)__entry + (__entry->__data_loc_##field & 0xffff))
|
||||
|
||||
#undef __get_str
|
||||
#define __get_str(field) (char *)__get_dynamic_array(field)
|
||||
|
@ -325,6 +326,7 @@ ftrace_define_fields_##call(void) \
|
|||
#define __dynamic_array(type, item, len) \
|
||||
__data_offsets->item = __data_size + \
|
||||
offsetof(typeof(*entry), __data); \
|
||||
__data_offsets->item |= (len * sizeof(type)) << 16; \
|
||||
__data_size += (len) * sizeof(type);
|
||||
|
||||
#undef __string
|
||||
|
|
|
@ -176,11 +176,13 @@ static int filter_pred_string(struct filter_pred *pred, void *event,
|
|||
static int filter_pred_strloc(struct filter_pred *pred, void *event,
|
||||
int val1, int val2)
|
||||
{
|
||||
unsigned short str_loc = *(unsigned short *)(event + pred->offset);
|
||||
u32 str_item = *(u32 *)(event + pred->offset);
|
||||
int str_loc = str_item & 0xffff;
|
||||
int str_len = str_item >> 16;
|
||||
char *addr = (char *)(event + str_loc);
|
||||
int cmp, match;
|
||||
|
||||
cmp = strncmp(addr, pred->str_val, pred->str_len);
|
||||
cmp = strncmp(addr, pred->str_val, str_len);
|
||||
|
||||
match = (!cmp) ^ pred->not;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче