Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libtraceevent for openSUSE:Factory checked in at 2024-07-03 20:26:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libtraceevent (Old) and /work/SRC/openSUSE:Factory/.libtraceevent.new.18349 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "libtraceevent" Wed Jul 3 20:26:36 2024 rev:13 rq:1184269 version:1.8.2 Changes: -------- --- /work/SRC/openSUSE:Factory/libtraceevent/libtraceevent.changes 2023-06-21 22:37:23.341479225 +0200 +++ /work/SRC/openSUSE:Factory/.libtraceevent.new.18349/libtraceevent.changes 2024-07-03 20:28:48.169776637 +0200 @@ -1,0 +2,52 @@ +Mon Jun 17 12:55:41 UTC 2024 - Daniel Wagner <daniel.wagner@suse.com> + +- Update to 1.8.2 + * New APIs: + - tep_record_is_event() - A helper function that basically converts + int type= tep_data_type(event->tep, record); + if (event->id == type) { + /* do something */ + } + into: + if (tep_record_is_event(record, event)) { + /* do something */ + } + - tep_get_sub_buffer_commit_offset() - Add a function to return the + offset of where the "commit" is located on the subbuffer + so that the application can do its own direct reading of it. + - kbuffer_read_buffer() - Add the functionality to the kbuffer to + act like the read syscall of the ring buffer. That is, it + will load the passed in buffer with the events where the + kbuffer left off, and that passed in buffer can be loaded + into another kbuffer via kbuffer_load_subbuffer(). + - kbuffer_dup() - Create a new kbuffer with the same fields of an + existing kbuffer. This will allow traversing a subbuffer + without modifying the contents of another kbuffer that + points to the subbuffer. + - kbuffer_subbuffer() - Return the subbuffer that was loaded into + a kbuffer via kbuffer_load_subbuffer(). + - kbuffer_refresh() - In the case of the subbuffer that was loaded + into a kbuffer via kbuffer_load_subbuffer() that is still + active, this function will refresh the meta data to continue + reading events if more were written to it. + - Added tep_get_sub_buffer_data_size() helper function + * Updates: + - Add option to disable building documents for some environments + that do not have everything needed to build the documents to + not fail the build with meson. + - Bump meson version required to build to 0.58.0 as plugins use + str.replace that was introduced in that version. + - Have the sched_switch plugin parse the format field to figure out + what the correct mapping of the "prev_state" field is to produce + the proper string output. + * Fixes: + - Update the default sched_switch "prev_state" string array to match + what's been in the kernel for a while now. + - Fix tep_kbuffer() to fill in the long_size, otherwise it would default + to 32 bit longs and cause a lot of confusion to application developers + - Fix tep_kbuffer man page info + - Fix some meson dependency issues + - Fix kbuffer_read_buffer() timestamp being off in some cases + - Fix curr size in kbuffer_refresh() + +------------------------------------------------------------------- Old: ---- libtraceevent-1.7.3.tar.gz New: ---- libtraceevent-1.8.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libtraceevent.spec ++++++ --- /var/tmp/diff_new_pack.GHWPlV/_old 2024-07-03 20:28:48.881802697 +0200 +++ /var/tmp/diff_new_pack.GHWPlV/_new 2024-07-03 20:28:48.885802844 +0200 @@ -1,7 +1,7 @@ # # spec file for package libtraceevent # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -22,7 +22,7 @@ %define sodname %{dname}%{sonum} Name: libtraceevent -Version: 1.7.3 +Version: 1.8.2 Release: 0 Summary: Linux kernel trace event library License: GPL-2.0-only AND LGPL-2.1-only ++++++ libtraceevent-1.7.3.tar.gz -> libtraceevent-1.8.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent-event_find.txt new/libtraceevent-1.8.2/Documentation/libtraceevent-event_find.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent-event_find.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent-event_find.txt 2024-01-09 03:32:09.000000000 +0100 @@ -3,7 +3,7 @@ NAME ---- -tep_find_event,tep_find_event_by_name,tep_find_event_by_record - +tep_find_event,tep_find_event_by_name,tep_find_event_by_record, tep_record_is_event - Find events by given key. SYNOPSIS @@ -15,6 +15,7 @@ struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); +bool *tep_record_is_event*(struct tep_record pass:[*]record, struct tep_event pass:[*]event); -- DESCRIPTION @@ -31,12 +32,16 @@ event _name_, under the system _sys_. If the _sys_ is NULL (not specified), the first event with _name_ is returned. -The tep_find_event_by_record()* function searches for an event from a given +The *tep_find_event_by_record()* function searches for an event from a given _record_. +The *tep_record_is_event()* function tests if the given _record_ is of the type +of the _event_. This is normally used to know if the _record_ being processed is +of an _event_ where further processing should be done. + RETURN VALUE ------------ -All these functions return a pointer to the found event, or NULL if there is no +All these functions except *tep_record_is_event()* return a pointer to the found event, or NULL if there is no such event. EXAMPLE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent-handle.txt new/libtraceevent-1.8.2/Documentation/libtraceevent-handle.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent-handle.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent-handle.txt 2024-01-09 03:32:09.000000000 +0100 @@ -17,6 +17,7 @@ void *tep_ref*(struct tep_handle pass:[*]_tep_); void *tep_unref*(struct tep_handle pass:[*]_tep_); int *tep_get_ref*(struct tep_handle pass:[*]_tep_); +struct kbuffer pass:[*]*tep_kbuffer*(struct tep_handle pass:[*]_tep_); -- DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent-kbuffer-create.txt new/libtraceevent-1.8.2/Documentation/libtraceevent-kbuffer-create.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent-kbuffer-create.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent-kbuffer-create.txt 2024-01-09 03:32:09.000000000 +0100 @@ -3,7 +3,8 @@ NAME ---- -kbuffer_alloc, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer element to parse +kbuffer_alloc, kbuffer_dup, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer, +kbuffer_refresh, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer element to parse the Linux kernel tracing ring buffer SYNOPSIS @@ -28,10 +29,13 @@ struct tep_handle; struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); +struct kbuffer pass:[*]*kbuffer_dup*(struct kbuffer pass:[*]_kbuf_); void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); -int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf); +int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_refresh*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); +void pass:[*]*kbuffer_subbuffer*(struct kbuffer pass:[*]_kbuf); -- DESCRIPTION @@ -59,6 +63,11 @@ in it, it will be set to 8 byte long size and not 4 byte. This is because the ring buffer long size is dependent on the kernel and not user space. +The *kbuffer_dup()* function will duplicate an existing kbuffer structure with +an allocated new one. It will have all the properties of the passed in _kbuf_, +including pointing to the same subbuffer that was loaded in the _kbuf_. +It must be freed with *kbuffer_free()*. + The *kbuffer_free()* function will free the resources created by *kbuffer_alloc()*. The *kbuffer_load_subbuffer()* will take a _subbuffer_ which is a raw data blob @@ -70,9 +79,20 @@ The *kbuffer_subbuffer_size()* returns the location of the end of the last event on the sub-buffer. It does not return the size of the sub-buffer itself. +The *kbuffer_refresh()* is to be used if more writes were done on the loaded kbuffer +where the size of the kbuffer needs to be refreshed to be able to read the new +events that were written since the last *kbuffer_load_subbuffer()* was called on it. + +Note, no memory barriers are implemented with this function and any synchronization +with the writer is the responsibility of the application. + The *kbuffer_start_of_data()* function returns the offset of where the actual data load of the sub-buffer begins. +The *kbuffer_subbuffer()* function returns the pointer to the currently loaded +subbuffer. That is, the last subbuffer that was loaded by *kbuffer_load_subbuffer()*. +If no subbuffer was loaded NULL is returned. + RETURN VALUE ------------ *kbuffer_alloc()* returns an allocated kbuffer descriptor or NULL on error. @@ -86,6 +106,12 @@ *kbuffer_start_of_data()* returns the offset of where the data begins on the sub-buffer loaded in _kbuf_. +*kbuffer_subbuffer()* returns the last loaded subbuffer to _kbuf_ that was loaded +by *kbuffer_load_subbuffer()* or NULL if none was loaded. + +*kbuffer_refresh()* returns 0 on success and -1 if _kbuf_ is NULL or it does not +have a subbuffer loaded via *kbuffer_load_subbuffer()*. + EXAMPLE ------- [source,c] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent-kbuffer-read.txt new/libtraceevent-1.8.2/Documentation/libtraceevent-kbuffer-read.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent-kbuffer-read.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent-kbuffer-read.txt 2024-01-09 03:32:09.000000000 +0100 @@ -4,7 +4,7 @@ NAME ---- kbuffer_read_event, kbuffer_next_event, kbuffer_missed_events, kbuffer_event_size, kbuffer_curr_size, -kbuffer_curr_offset, kbuffer_curr_index - +kbuffer_curr_offset, kbuffer_curr_index, kbuffer_read_buffer - Functions to read through the kbuffer sub buffer. SYNOPSIS @@ -21,6 +21,7 @@ int *kbuffer_curr_size*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_curr_offset*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_curr_index*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_read_buffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_buffer_, int _len_); -- DESCRIPTION @@ -64,6 +65,18 @@ portion of the sub-buffer where the current evnet's meta data is located. The first event will likely be zero, but may not be if there's a timestamp attached to it. +The *kbuffer_read_buffer()* function will fill the given _buffer_ from the _kbuf_ the same +way the kernel would do a read system call. That is, if the length _len_ is less than the +sub buffer size, or the kbuffer current index is non-zero, it will start copying from the +_kbuf_ current event and create _buffer_ as a new sub buffer (with a timestamp +and commit header) with that event that was found and including all events after that can +fit within _len_. The _len_ must include the size of the sub buffer header as well as the +events to include. That is, _len_ is the allocate size of _buffer_ that can be filled. +The return from this function is the index of the end of the last event that was added. +If there are no more events then zero is returned, and if the buffer can not +copy any events because _len_ was too small, then -1 is returned. + + RETURN VALUE ------------ *kbuffer_read_event()* returns the event that the _kbuf_ descriptor is currently at, @@ -92,6 +105,10 @@ *kbuf_curr_index()* returns the index of the current record from the beginning of the _kbuf_ data section. +*kbuf_read_buffer()* returns the index of the end of the last event that was filled in +_buffer_. If there are no more events to copy from _start_ then 0 is returned. If _len_ +is not big enough to hold any events, then -1 is returned. + EXAMPLE ------- [source,c] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent-page_size.txt new/libtraceevent-1.8.2/Documentation/libtraceevent-page_size.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent-page_size.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent-page_size.txt 2024-01-09 03:32:09.000000000 +0100 @@ -3,7 +3,7 @@ NAME ---- -tep_get_page_size, tep_set_page_size, tep_get_sub_buffer_size - Get / set the size of a memory page on +tep_get_page_size, tep_set_page_size, tep_get_sub_buffer_data_size, tep_get_sub_buffer_size - Get / set the size of a memory page on the machine, where the trace is generated SYNOPSIS @@ -15,6 +15,8 @@ int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); int *tep_get_sub_buffer_size*(struct tep_handle pass:[*]_tep_); +int *tep_get_sub_buffer_data_size*(struct tep_handle pass:[*]_tep_); +int *tep_get_sub_buffer_commit_offset*(struct tep_handle pass:[*]_tep_); -- DESCRIPTION @@ -32,6 +34,14 @@ ring buffer. The Linux kernel ring buffer is broken up into sections called sub buffers. This returns the size of those buffers. +The *tep_get_sub_buffer_data_size()* returns the size of just the data portion +of the sub buffers. + +The *tep_get_sub_buffer_commit_offset()* returns the offset on the sub buffer +that holds the committed portion of data. This number contains the index from +the data portion of the sub buffer that is the end of the last element on the +sub buffer. + RETURN VALUE ------------ The *tep_get_page_size()* function returns size of the memory page, in bytes. @@ -39,6 +49,9 @@ The *tep_get_sub_buffer_size()* function returns the number of bytes each sub buffer is made up of. +The *tep_get_sub_buffer_commit_offset()* function returns the location on the +sub buffer that contains the index of the last element. + EXAMPLE ------- [source,c] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Documentation/libtraceevent.txt new/libtraceevent-1.8.2/Documentation/libtraceevent.txt --- old/libtraceevent-1.7.3/Documentation/libtraceevent.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Documentation/libtraceevent.txt 2024-01-09 03:32:09.000000000 +0100 @@ -27,11 +27,13 @@ int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); int *tep_get_sub_buffer_size*(struct tep_handle pass:[*]_tep_); + int *tep_get_sub_buffer_data_size*(struct tep_handle pass:[*]_tep_); + int *tep_get_sub_buffer_commit_offset*(struct tep_handle pass:[*]_tep_); int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); - struct kbuffer pass:[*]*tep_kbuffer*(struct tep_handle pass:[*]:_tep_); + struct kbuffer pass:[*]*tep_kbuffer*(struct tep_handle pass:[*]_tep_); Register / unregister APIs: int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); @@ -83,6 +85,7 @@ struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); + bool *tep_record_is_event*(struct tep_record pass:[*]record, struct tep_event pass:[*]event); Parsing of event files: int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); @@ -179,9 +182,12 @@ kbuffer parsing: #include <kbuffer.h> struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); + struct kbuffer pass:[*]*kbuffer_dup*(struct kbuffer pass:[*]_kbuf_); void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf); + void pass:[*]*kbuffer_subbuffer*(struct kbuffer pass:[*]_kbuf); + int *kbuffer_refresh*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); unsigned long long *kbuffer_timestamp*(struct kbuffer pass:[*]_kbuf_); unsigned long long *kbuffer_subbuf_timestamp*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuf_); @@ -193,6 +199,7 @@ int *kbuffer_curr_size*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_curr_offset*(struct kbuffer pass:[*]_kbuf_); int *kbuffer_curr_index*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_read_buffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_buffer_, int _start_, int _len_); -- DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/Makefile new/libtraceevent-1.8.2/Makefile --- old/libtraceevent-1.7.3/Makefile 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/Makefile 2024-01-09 03:32:09.000000000 +0100 @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # libtraceevent version EP_VERSION = 1 -EP_PATCHLEVEL = 7 -EP_EXTRAVERSION = 3 +EP_PATCHLEVEL = 8 +EP_EXTRAVERSION = 2 EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) MAKEFLAGS += --no-print-directory diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/include/traceevent/event-parse.h new/libtraceevent-1.8.2/include/traceevent/event-parse.h --- old/libtraceevent-1.7.3/include/traceevent/event-parse.h 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/include/traceevent/event-parse.h 2024-01-09 03:32:09.000000000 +0100 @@ -554,6 +554,8 @@ struct tep_cmdline *next); int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline); +bool tep_record_is_event(struct tep_record *record, struct tep_event *event); + void tep_print_field_content(struct trace_seq *s, void *data, int size, struct tep_format_field *field); void tep_record_print_fields(struct trace_seq *s, @@ -586,6 +588,8 @@ void tep_set_long_size(struct tep_handle *tep, int long_size); int tep_get_page_size(struct tep_handle *tep); int tep_get_sub_buffer_size(struct tep_handle *tep); +int tep_get_sub_buffer_data_size(struct tep_handle *tep); +int tep_get_sub_buffer_commit_offset(struct tep_handle *tep); void tep_set_page_size(struct tep_handle *tep, int _page_size); bool tep_is_file_bigendian(struct tep_handle *tep); void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/include/traceevent/kbuffer.h new/libtraceevent-1.8.2/include/traceevent/kbuffer.h --- old/libtraceevent-1.7.3/include/traceevent/kbuffer.h 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/include/traceevent/kbuffer.h 2024-01-09 03:32:09.000000000 +0100 @@ -31,8 +31,10 @@ struct kbuffer; struct kbuffer *kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian); +struct kbuffer *kbuffer_dup(struct kbuffer *kbuf); void kbuffer_free(struct kbuffer *kbuf); int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer); +int kbuffer_refresh(struct kbuffer *kbuf); void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts); void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts); unsigned long long kbuffer_timestamp(struct kbuffer *kbuf); @@ -42,6 +44,7 @@ void *kbuffer_translate_data(int swap, void *data, unsigned int *size); void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset, unsigned long long *ts); +int kbuffer_read_buffer(struct kbuffer *kbuf, void *buffer, int len); int kbuffer_curr_index(struct kbuffer *kbuf); @@ -50,6 +53,7 @@ int kbuffer_event_size(struct kbuffer *kbuf); int kbuffer_missed_events(struct kbuffer *kbuf); int kbuffer_subbuffer_size(struct kbuffer *kbuf); +void *kbuffer_subbuffer(struct kbuffer *kbuf); void kbuffer_set_old_format(struct kbuffer *kbuf); int kbuffer_start_of_data(struct kbuffer *kbuf); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/meson.build new/libtraceevent-1.8.2/meson.build --- old/libtraceevent-1.7.3/meson.build 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/meson.build 2024-01-09 03:32:09.000000000 +0100 @@ -4,9 +4,9 @@ project( 'libtraceevent', ['c'], - meson_version: '>= 0.50.0', + meson_version: '>= 0.58.0', license: 'LGPL-2.1', - version: '1.7.3', + version: '1.8.2', default_options: [ 'c_std=gnu99', 'buildtype=debug', @@ -45,6 +45,8 @@ subdir('utest') endif subdir('samples') + +if get_option('doc') subdir('Documentation') custom_target( @@ -52,3 +54,4 @@ output: 'docs', depends: [html, man], command: ['echo']) +endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/meson_options.txt new/libtraceevent-1.8.2/meson_options.txt --- old/libtraceevent-1.7.3/meson_options.txt 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/meson_options.txt 2024-01-09 03:32:09.000000000 +0100 @@ -16,3 +16,5 @@ description : 'enable bold literals') option('docbook-suppress-sp', type : 'boolean', value : false, description : 'docbook suppress sp') +option('doc', type : 'boolean', value: true, + description : 'produce documentation') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/plugins/plugin_sched_switch.c new/libtraceevent-1.8.2/plugins/plugin_sched_switch.c --- old/libtraceevent-1.7.3/plugins/plugin_sched_switch.c 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/plugins/plugin_sched_switch.c 2024-01-09 03:32:09.000000000 +0100 @@ -9,13 +9,143 @@ #include "event-parse.h" #include "trace-seq.h" -static void write_state(struct trace_seq *s, int val) +/* + * prev_state is of size long, which is 32 bits on 32 bit architectures. + * As it needs to have the same bits for both 32 bit and 64 bit architectures + * we can just assume that the flags we care about will all be within + * the 32 bits. + */ +#define MAX_STATE_BITS 32 + +static const char *convert_sym(struct tep_print_flag_sym *sym) { - const char states[] = "SDTtZXxW"; + static char save_states[MAX_STATE_BITS + 1]; + + memset(save_states, 0, sizeof(save_states)); + + /* This is the flags for the prev_state_field, now make them into a string */ + for (; sym; sym = sym->next) { + long bitmask = strtoul(sym->value, NULL, 0); + int i; + + for (i = 0; !(bitmask & 1); i++) + bitmask >>= 1; + + if (i >= MAX_STATE_BITS) + continue; + + save_states[i] = sym->str[0]; + } + + return save_states; +} + +static struct tep_print_arg_field * +find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) +{ + struct tep_print_arg_field *field; + + if (!arg) + return NULL; + + if (arg->type == TEP_PRINT_FIELD) + return &arg->field; + + if (arg->type == TEP_PRINT_OP) { + field = find_arg_field(prev_state_field, arg->op.left); + if (field && field->field == prev_state_field) + return field; + field = find_arg_field(prev_state_field, arg->op.right); + if (field && field->field == prev_state_field) + return field; + } + return NULL; +} + +static struct tep_print_flag_sym * +test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) +{ + struct tep_print_arg_field *field; + + field = find_arg_field(prev_state_field, arg->flags.field); + if (!field) + return NULL; + + return arg->flags.flags; +} + +static struct tep_print_flag_sym * +search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) +{ + struct tep_print_flag_sym *sym = NULL; + + if (!arg) + return NULL; + + if (arg->type == TEP_PRINT_OP) { + sym = search_op(prev_state_field, arg->op.left); + if (sym) + return sym; + + sym = search_op(prev_state_field, arg->op.right); + if (sym) + return sym; + } else if (arg->type == TEP_PRINT_FLAGS) { + sym = test_flags(prev_state_field, arg); + } + + return sym; +} + +static const char *get_states(struct tep_format_field *prev_state_field) +{ + struct tep_print_flag_sym *sym; + struct tep_print_arg *arg; + struct tep_event *event; + + event = prev_state_field->event; + + /* + * Look at the event format fields, and search for where + * the prev_state is parsed via the format flags. + */ + for (arg = event->print_fmt.args; arg; arg = arg->next) { + /* + * Currently, the __print_flags() for the prev_state + * is embedded in operations, so they too must be + * searched. + */ + sym = search_op(prev_state_field, arg); + if (sym) + return convert_sym(sym); + } + return NULL; +} + +static void write_state(struct trace_seq *s, struct tep_format_field *field, + struct tep_record *record) +{ + static struct tep_format_field *prev_state_field; + static const char *states; + unsigned long long val; int found = 0; + int len; int i; - for (i = 0; i < (sizeof(states) - 1); i++) { + if (!field) + return; + + if (!states || field != prev_state_field) { + states = get_states(field); + if (!states) + states = "SDTtXZPI"; + prev_state_field = field; + } + + tep_read_number_field(field, record->data, &val); + + len = strlen(states); + for (i = 0; i < len; i++) { if (!(val & (1 << i))) continue; @@ -99,8 +229,8 @@ if (tep_get_field_val(s, event, "prev_prio", record, &val, 1) == 0) trace_seq_printf(s, "[%d] ", (int) val); - if (tep_get_field_val(s, event, "prev_state", record, &val, 1) == 0) - write_state(s, val); + field = tep_find_any_field(event, "prev_state"); + write_state(s, field, record); trace_seq_puts(s, " ==> "); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/src/event-parse-api.c new/libtraceevent-1.8.2/src/event-parse-api.c --- old/libtraceevent-1.7.3/src/event-parse-api.c 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/src/event-parse-api.c 2024-01-09 03:32:09.000000000 +0100 @@ -263,6 +263,20 @@ } /** + * tep_get_sub_buffer_data_size - get the size of the data portion + * @tep: The handle to the tep to get the data size from + * + * Returns the size of the data portion of the sub buffer + */ +int tep_get_sub_buffer_data_size(struct tep_handle *tep) +{ + if (!tep) + return -1; + + return tep->header_page_data_size; +} + +/** * tep_get_sub_buffer_size - get the size of a trace buffer page * @tep: a handle to the tep_handle * @@ -278,6 +292,21 @@ } /** + * tep_get_sub_buffer_commit_offset - return offset of the commit location + * @tep: the handle to the tep_handle + * + * Returns the offset of where to find the "commit" field of the offset. + * Use tep_get_header_page_size() to find the size of the commit field. + */ +int tep_get_sub_buffer_commit_offset(struct tep_handle *tep) +{ + if (!tep) + return -1; + + return tep->header_page_size_offset; +} + +/** * tep_is_file_bigendian - return the endian of the file * @tep: a handle to the tep_handle * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/src/event-parse.c new/libtraceevent-1.8.2/src/event-parse.c --- old/libtraceevent-1.7.3/src/event-parse.c 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/src/event-parse.c 2024-01-09 03:32:09.000000000 +0100 @@ -6872,6 +6872,21 @@ return comm; } +/** + * tep_record_is_event - return true if the given record is the given event + * @record: The record to see is the @event + * @event: The event to test against @record + * + * Returns true if the record is of the given event, false otherwise + */ +bool tep_record_is_event(struct tep_record *record, struct tep_event *event) +{ + int type; + + type = tep_data_type(event->tep, record); + return event->id == type; +} + static struct tep_cmdline * pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/src/kbuffer-parse.c new/libtraceevent-1.8.2/src/kbuffer-parse.c --- old/libtraceevent-1.7.3/src/kbuffer-parse.c 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/src/kbuffer-parse.c 2024-01-09 03:32:09.000000000 +0100 @@ -86,6 +86,42 @@ ENDIAN_MASK; } +static unsigned long long swap_8(unsigned long data) +{ + return ((data & 0xffULL) << 56) | + ((data & (0xffULL << 8)) << 40) | + ((data & (0xffULL << 16)) << 24) | + ((data & (0xffULL << 24)) << 8) | + ((data & (0xffULL << 32)) >> 8) | + ((data & (0xffULL << 40)) >> 24) | + ((data & (0xffULL << 48)) >> 40) | + ((data & (0xffULL << 56)) >> 56); +} + +static unsigned int swap_4(unsigned int data) +{ + return ((data & 0xffULL) << 24) | + ((data & (0xffULL << 8)) << 8) | + ((data & (0xffULL << 16)) >> 8) | + ((data & (0xffULL << 24)) >> 24); +} + +static void write_8(bool do_swap, void *ptr, unsigned long long data) +{ + if (do_swap) + *(unsigned long long *)ptr = swap_8(data); + else + *(unsigned long long *)ptr = data; +} + +static void write_4(bool do_swap, void *ptr, unsigned int data) +{ + if (do_swap) + *(unsigned int *)ptr = swap_4(data); + else + *(unsigned int *)ptr = data; +} + static unsigned long long __read_8(void *ptr) { unsigned long long data = *(unsigned long long *)ptr; @@ -96,18 +132,8 @@ static unsigned long long __read_8_sw(void *ptr) { unsigned long long data = *(unsigned long long *)ptr; - unsigned long long swap; - swap = ((data & 0xffULL) << 56) | - ((data & (0xffULL << 8)) << 40) | - ((data & (0xffULL << 16)) << 24) | - ((data & (0xffULL << 24)) << 8) | - ((data & (0xffULL << 32)) >> 8) | - ((data & (0xffULL << 40)) >> 24) | - ((data & (0xffULL << 48)) >> 40) | - ((data & (0xffULL << 56)) >> 56); - - return swap; + return swap_8(data); } static unsigned int __read_4(void *ptr) @@ -120,14 +146,8 @@ static unsigned int __read_4_sw(void *ptr) { unsigned int data = *(unsigned int *)ptr; - unsigned int swap; - - swap = ((data & 0xffULL) << 24) | - ((data & (0xffULL << 8)) << 8) | - ((data & (0xffULL << 16)) >> 8) | - ((data & (0xffULL << 24)) >> 24); - return swap; + return swap_4(data); } static unsigned long long read_8(struct kbuffer *kbuf, void *ptr) @@ -160,6 +180,7 @@ return (unsigned long)ptr - (unsigned long)kbuf->data; } +static int next_event(struct kbuffer *kbuf); static int __next_event(struct kbuffer *kbuf); /* @@ -249,6 +270,26 @@ return kbuf; } +/** + * kbuffer_dup - duplicate a given kbuffer + * @kbuf_orig; The kbuffer to duplicate + * + * Allocates a new kbuffer based off of anothe kbuffer. + * Returns the duplicate on success or NULL on error. + */ +struct kbuffer *kbuffer_dup(struct kbuffer *kbuf_orig) +{ + struct kbuffer *kbuf; + + kbuf = malloc(sizeof(*kbuf)); + if (!kbuf) + return NULL; + + *kbuf = *kbuf_orig; + + return kbuf; +} + /** kbuffer_free - free an allocated kbuffer * @kbuf: The kbuffer to free * @@ -259,6 +300,33 @@ free(kbuf); } +/** + * kbuffer_refresh - update the meta data from the subbuffer + * @kbuf; The kbuffer to update + * + * If the loaded subbuffer changed its meta data (the commit) + * then update the pointers for it. + */ +int kbuffer_refresh(struct kbuffer *kbuf) +{ + unsigned long long flags; + unsigned int old_size; + + if (!kbuf || !kbuf->subbuffer) + return -1; + + old_size = kbuf->size; + + flags = read_long(kbuf, kbuf->subbuffer + 8); + kbuf->size = (unsigned int)flags & COMMIT_MASK; + + /* Update next to be the next element */ + if (kbuf->size != old_size && kbuf->curr == kbuf->next) + next_event(kbuf); + + return 0; +} + static unsigned int type4host(struct kbuffer *kbuf, unsigned int type_len_ts) { @@ -295,6 +363,13 @@ return type_len_ts >> 5; } +static void set_curr_to_end(struct kbuffer *kbuf) +{ + kbuf->curr = kbuf->size; + kbuf->next = kbuf->size; + kbuf->index = kbuf->size; +} + /* * Linux 2.6.30 and earlier (not much ealier) had a different * ring buffer format. It should be obsolete, but we handle it anyway. @@ -339,9 +414,7 @@ case OLD_RINGBUF_TYPE_TIME_STAMP: /* should never happen! */ - kbuf->curr = kbuf->size; - kbuf->next = kbuf->size; - kbuf->index = kbuf->size; + set_curr_to_end(kbuf); return -1; default: if (len) @@ -703,6 +776,17 @@ } /** + * kbuffer_subbuffer - the currently loaded subbuffer + * @kbuf: The kbuffer to read from + * + * Returns the currently loaded subbuffer. + */ +void *kbuffer_subbuffer(struct kbuffer *kbuf) +{ + return kbuf->subbuffer; +} + +/** * kbuffer_curr_index - Return the index of the record * @kbuf: The kbuffer to read from * @@ -846,3 +930,90 @@ return info; } + +/** + * kbuffer_read_buffer - read a buffer like the kernel would perform a read + * @kbuf: the kbuffer handle + * @buffer: where to write the data into + * @len; The length of @buffer + * + * This will read the saved sub buffer within @kbuf like the systemcall + * of read() to the trace_pipe_raw would do. That is, if either @len + * can not fit the entire buffer, or if the current index in @kbuf + * is non-zero, it will write to @buffer a new subbuffer that could be + * loaded into kbuffer_load_subbuffer(). That is, it will write into + * @buffer a legitimate sub-buffer with a header and all that has the + * proper timestamp and commit fields. + * + * Returns the index after the last element written. + * 0 if nothing was copied. + * -1 on error (which includes not having enough space in len to + * copy the subbuffer header or any of its content. In otherwords, + * do not try again! + * + * @kbuf current index will be set to the next element to read. + */ +int kbuffer_read_buffer(struct kbuffer *kbuf, void *buffer, int len) +{ + unsigned long long ts; + unsigned int type_len_ts; + bool do_swap = false; + int last_next; + int save_curr; + + /* Are we at the end of the buffer */ + if (kbuf->curr >= kbuf->size) + return 0; + + /* If we can not copy anyting, return -1 */ + if (len < kbuf->start) + return -1; + + /* Check if the first event can fit */ + if (len < (kbuf->next - kbuf->curr) + kbuf->start) + return -1; + + if (kbuf->read_8 == __read_8_sw) + do_swap = true; + + /* Have this subbuffer timestamp be the current timestamp */ + write_8(do_swap, buffer, kbuf->timestamp); + + len -= kbuf->start; + + save_curr = kbuf->curr; + + /* Due to timestamps, we must save the current next to use */ + last_next = kbuf->next; + + while (len >= kbuf->next - save_curr) { + last_next = kbuf->next; + if (!kbuffer_next_event(kbuf, &ts)) + break; + } + + len = last_next - save_curr; + /* No event was found? */ + if (!len) + return 0; + + memcpy(buffer + kbuf->start, kbuf->data + save_curr, len); + + /* Zero out the delta, as the sub-buffer has the timestamp */ + type_len_ts = read_4(kbuf, buffer + kbuf->start); + + if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN) + type_len_ts &= ~(((1 << 27) - 1)); + else + type_len_ts &= ((1 << 5) - 1); + + write_4(do_swap, buffer + kbuf->start, type_len_ts); + + /* Update the size */ + if (kbuf->read_long == __read_long_8) + write_8(do_swap, buffer + 8, len); + else + write_4(do_swap, buffer + 8, len); + + return last_next; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/src/meson.build new/libtraceevent-1.8.2/src/meson.build --- old/libtraceevent-1.7.3/src/meson.build 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/src/meson.build 2024-01-09 03:32:09.000000000 +0100 @@ -13,10 +13,14 @@ 'trace-seq.c', ] +cc = meson.get_compiler('c') +dl_dep = cc.find_library('dl') + libtraceevent = library( 'traceevent', sources, version: library_version, + dependencies: [dl_dep], include_directories: [incdir], install: true) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtraceevent-1.7.3/src/parse-utils.c new/libtraceevent-1.8.2/src/parse-utils.c --- old/libtraceevent-1.7.3/src/parse-utils.c 2023-06-07 21:49:02.000000000 +0200 +++ new/libtraceevent-1.8.2/src/parse-utils.c 2024-01-09 03:32:09.000000000 +0100 @@ -137,6 +137,11 @@ int long_size; long_size = tep_get_long_size(tep); + + /* If the long_size is not set, then use the commit size */ + if (!long_size) + long_size = tep_get_header_page_size(tep); + if (long_size == 8) long_size = KBUFFER_LSIZE_8; else