From: Mathieu Desnoyers Date: Wed, 16 Jan 2013 22:56:46 +0000 (-0500) Subject: Merge branch 'master' into bindings/python X-Git-Tag: v1.2.0-rc1~89 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=71dd417a2b700c2315ef9919104572df1bc83f7a;hp=bb919dd077169b5ee049ba3fc82f8555648cb22e Merge branch 'master' into bindings/python Signed-off-by: Mathieu Desnoyers --- diff --git a/.gitignore b/.gitignore index d7b0ca1b..e4562869 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /tests/test-bitfield *~ +/tests/lib/test-seeks *.o *.a *.la diff --git a/ChangeLog b/ChangeLog index 1ad948ea..a62ebebf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +2012-01-11 Babeltrace 1.0.2 + * Fix: add tests/lib missing files to Makefile.am + +2012-01-11 Babeltrace 1.0.1 + * Provides a basic pkg-config file for libbabeltrace + * Fix erroneous warning/error messages + * Fix comment in context.h + * Cleanup: Remove whitespace at EOL from mit-license.txt + * Add missing permission notice in each source file + * Adding a test which do a sequence of seek BEGIN, LAST, BEGIN, LAST + * Run seek tests on a second trace file + * Add #define _GNU_SOURCE to remove warning about asprintf + * Include a test for SEEK_BEGIN and SEEK_LAST + * Fix: Report success even if we find at least one valid stream in find_max_timestamp_ctf_stream_class + * Fix SEEK_BEGIN for streams that do not contain any event + +2012-10-27 Babeltrace 1.0.0 + * tests: add test traces to distribution tarball + * Document bash requirement for make check in README + * Add tests to make check + * Fix: add missing header size validation + * callbacks.c: handle extract_ctf_stream_event return value + * Cleanup: fix cppcheck warning + * Cleanup: fix cppcheck warnings + * fix double-free on error path + +2012-10-18 Babeltrace 1.0.0-rc6 + * Add valgrind suppression file for libpopt + * Fix: unplug memory leak that causes popt-0.13 to segfault + * Fix: test all close/fclose ret val, fix double close + * Cleanup: add missing newline + * Fix: fd leak on trace close + * Fix memory leaks induced by lack of libpopt documentation + * babeltrace: fix poptGetOptArg memleak + * plugins: implement plugin unregister + * Doc: valgrind with babeltrace (glib workaround) + * callsites: fix memory leak + * Fix: free all the metadata-related memory + * Fix : Free the iterator callback arrays + * Fix : cleanup teardown of context + * Fix : protect static float and double declarations + * callsite: support instruction pointer field + * Document that list.h is LGPLv2.1, but entirely trivial + * Fix: callsite support: list multiple callsites + * Add callsite support + * Fix: Allow 64-bit packet offset + * Fix: emf uri: surround by " " + * Handle model.emf.uri event info + * Fix: Documentation cleanup + * Fix: misplaced C++ ifdef + * Fix babeltrace-log get big line when the input file last line don't have enter + * API Fix: bt_ctf_iter_read_event_flags + * Fix: get encoding for char arrays and sequences + * Fix: access to declaration from declaration_field + * Fix: get_declaration_* should not cast to field + * Fix babeltrace-log uninitialized memory (v2) + * Revert "Fix babeltrace-log uninitialized memory" + * Fix babeltrace-log uninitialized memory + * Fix: access field properties by declaration + * Fix: check return value of get_char_array + * Fix: C++ support to API header files + 2012-08-27 Babeltrace 1.0.0-rc5 * Change default printout to add host, process names and vpid * Add support for trace:hostname field diff --git a/LICENSE b/LICENSE index d4af9bbf..816d185e 100644 --- a/LICENSE +++ b/LICENSE @@ -13,3 +13,10 @@ in both free and proprietary software. See mit-license.txt for details. Library test code is distributed under the GPLv2 license, as specified in the per-file license. See gpl-2.0.txt for details. + +* LGPLv2.1 + +The file include/babeltrace/list.h is licensed under LGPLv2.1. It only +contains trivial static inline functions and macros, and, therefore, +including it does not make babeltrace a derivative work on this header. +Please refer to the LGPLv2.1 license for details. diff --git a/Makefile.am b/Makefile.am index 6584c5d2..d28fbc0f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,9 +2,12 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = include types lib formats converter bindings tests doc +SUBDIRS = include types lib formats converter bindings tests doc extras dist_doc_DATA = ChangeLog LICENSE mit-license.txt gpl-2.0.txt \ std-ext-lib.txt dist_noinst_DATA = CodingStyle + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = babeltrace.pc diff --git a/README b/README index 1687075b..9df02e70 100644 --- a/README +++ b/README @@ -67,3 +67,5 @@ compile the git repository tree : If you get the tree from the repository, you will need to use the "bootstrap" script in the root of the tree. It calls all the GNU tools needed to prepare the tree configuration. + +Running "make check": bash is required. diff --git a/babeltrace.pc.in b/babeltrace.pc.in new file mode 100644 index 00000000..12349dd9 --- /dev/null +++ b/babeltrace.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Babeltrace +Description: libbabeltrace provides a reader for trace files, reading mainly the +Common Trace Format (CTF). +Version: @PACKAGE_VERSION@ +Requires: +Requires.private: uuid popt +Libs: -L${libdir} -lbabeltrace -lbabeltrace-ctf +Cflags: -I${includedir} + diff --git a/configure.ac b/configure.ac index 24ee2a62..aab61999 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([babeltrace],[1.0.0-rc5],[mathieu dot desnoyers at efficios dot com]) +AC_INIT([babeltrace],[1.0.2],[mathieu dot desnoyers at efficios dot com]) AC_CONFIG_AUX_DIR([config]) AC_CANONICAL_TARGET AC_CANONICAL_HOST @@ -143,5 +143,9 @@ AC_CONFIG_FILES([ bindings/Makefile bindings/python/Makefile tests/Makefile + tests/lib/Makefile + extras/Makefile + extras/valgrind/Makefile + babeltrace.pc ]) AC_OUTPUT diff --git a/converter/babeltrace-log.c b/converter/babeltrace-log.c index 6ac94e69..21487119 100644 --- a/converter/babeltrace-log.c +++ b/converter/babeltrace-log.c @@ -17,6 +17,14 @@ * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * * Depends on glibc 2.10 for getline(). */ @@ -33,6 +41,7 @@ #include #include #include +#include #include #include @@ -53,6 +62,7 @@ static const char metadata_fmt[] = "/* CTF 1.8 */\n" "typealias integer { size = 8; align = 8; signed = false; } := uint8_t;\n" "typealias integer { size = 32; align = 32; signed = false; } := uint32_t;\n" +"typealias integer { size = 64; align = 64; signed = false; } := uint64_t;\n" "\n" "trace {\n" " major = %u;\n" /* major (e.g. 0) */ @@ -67,8 +77,8 @@ static const char metadata_fmt[] = "\n" "stream {\n" " packet.context := struct {\n" -" uint32_t content_size;\n" -" uint32_t packet_size;\n" +" uint64_t content_size;\n" +" uint64_t packet_size;\n" " };\n" "%s" /* Stream event header (opt.) */ "};\n" @@ -136,24 +146,24 @@ void write_packet_context(struct ctf_stream_pos *pos) /* content_size */ ctf_dummy_pos(pos, &dummy); - ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); - ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); + ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); + ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); - ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT); - *(uint32_t *) ctf_get_pos_addr(pos) = -1U; /* Not known yet */ - pos->content_size_loc = (uint32_t *) ctf_get_pos_addr(pos); - ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT); + ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); + *(uint64_t *) ctf_get_pos_addr(pos) = ~0ULL; /* Not known yet */ + pos->content_size_loc = (uint64_t *) ctf_get_pos_addr(pos); + ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); /* packet_size */ ctf_dummy_pos(pos, &dummy); - ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); - ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); + ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); + ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); - ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT); - *(uint32_t *) ctf_get_pos_addr(pos) = pos->packet_size; - ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT); + ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); + *(uint64_t *) ctf_get_pos_addr(pos) = pos->packet_size; + ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); } static @@ -162,13 +172,14 @@ void write_event_header(struct ctf_stream_pos *pos, char *line, uint64_t *ts) { unsigned long sec, usec; - int ret; if (!s_timestamp) return; /* Only need to be executed on first pass (dummy) */ if (pos->dummy) { + int ret; + /* Extract time from input line */ ret = sscanf(line, "[%lu.%lu] ", &sec, &usec); if (ret == 2) { @@ -199,21 +210,25 @@ void trace_string(char *line, struct ctf_stream_pos *pos, size_t len) uint64_t ts = 0; printf_debug("read: %s\n", line); -retry: - ctf_dummy_pos(pos, &dummy); - write_event_header(&dummy, line, &tline, len, &tlen, &ts); - ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT); - ctf_move_pos(&dummy, tlen * CHAR_BIT); - if (ctf_pos_packet(&dummy)) { - ctf_pos_pad_packet(pos); - write_packet_header(pos, s_uuid); - write_packet_context(pos); - if (attempt++ == 1) { - fprintf(stderr, "[Error] Line too large for packet size (%zukB) (discarded)\n", - pos->packet_size / CHAR_BIT / 1024); - return; + + for (;;) { + ctf_dummy_pos(pos, &dummy); + write_event_header(&dummy, line, &tline, len, &tlen, &ts); + ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT); + ctf_move_pos(&dummy, tlen * CHAR_BIT); + if (ctf_pos_packet(&dummy)) { + ctf_pos_pad_packet(pos); + write_packet_header(pos, s_uuid); + write_packet_context(pos); + if (attempt++ == 1) { + fprintf(stderr, "[Error] Line too large for packet size (%" PRIu64 "kB) (discarded)\n", + pos->packet_size / CHAR_BIT / 1024); + return; + } + continue; + } else { + break; } - goto retry; } write_event_header(pos, line, &tline, len, &tlen, &ts); @@ -229,9 +244,14 @@ void trace_text(FILE *input, int output) ssize_t len; char *line = NULL, *nl; size_t linesize; + int ret; - ctf_init_pos(&pos, output, O_RDWR); - + memset(&pos, 0, sizeof(pos)); + ret = ctf_init_pos(&pos, output, O_RDWR); + if (ret) { + fprintf(stderr, "Error in ctf_init_pos\n"); + return; + } write_packet_header(&pos, s_uuid); write_packet_context(&pos); for (;;) { @@ -239,11 +259,17 @@ void trace_text(FILE *input, int output) if (len < 0) break; nl = strrchr(line, '\n'); - if (nl) + if (nl) { *nl = '\0'; - trace_string(line, &pos, nl - line + 1); + trace_string(line, &pos, nl - line + 1); + } else { + trace_string(line, &pos, strlen(line) + 1); + } + } + ret = ctf_fini_pos(&pos); + if (ret) { + fprintf(stderr, "Error in ctf_fini_pos\n"); } - ctf_fini_pos(&pos); } static @@ -341,7 +367,9 @@ int main(int argc, char **argv) print_metadata(metadata_fp); trace_text(stdin, fd); - close(fd); + ret = close(fd); + if (ret) + perror("close"); exit(EXIT_SUCCESS); /* error handling */ diff --git a/converter/babeltrace.c b/converter/babeltrace.c index b8caa6a0..fe7d39fa 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #define _GNU_SOURCE @@ -47,12 +55,18 @@ #define PARTIAL_ERROR_SLEEP 3 /* 3 seconds */ #define DEFAULT_FILE_ARRAY_SIZE 1 + static char *opt_input_format, *opt_output_format; -/* Pointer into const argv */ -static const char *opt_input_format_arg, *opt_output_format_arg; +/* + * We are not freeing opt_input_paths ipath elements when exiting from + * main() for backward compatibility with libpop 0.13, which does not + * allocate copies for arguments returned by poptGetArg(), and for + * general compatibility with the documented behavior. This is known to + * cause a small memory leak with libpop 0.16. + */ static GPtrArray *opt_input_paths; -static const char *opt_output_path; +static char *opt_output_path; static struct format *fmt_read; @@ -67,6 +81,9 @@ void strlower(char *str) enum { OPT_NONE = 0, + OPT_OUTPUT_PATH, + OPT_INPUT_FORMAT, + OPT_OUTPUT_FORMAT, OPT_HELP, OPT_LIST, OPT_VERBOSE, @@ -82,11 +99,19 @@ enum { OPT_CLOCK_FORCE_CORRELATE, }; +/* + * We are _not_ using POPT_ARG_STRING ability to store directly into + * variables, because we want to cast the return to non-const, which is + * not possible without using poptGetOptArg explicitly. This helps us + * controlling memory allocation correctly without making assumptions + * about undocumented behaviors. poptGetOptArg is documented as + * requiring the returned const char * to be freed by the caller. + */ static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ - { "output", 'w', POPT_ARG_STRING, &opt_output_path, OPT_NONE, NULL, NULL }, - { "input-format", 'i', POPT_ARG_STRING, &opt_input_format_arg, OPT_NONE, NULL, NULL }, - { "output-format", 'o', POPT_ARG_STRING, &opt_output_format_arg, OPT_NONE, NULL, NULL }, + { "output", 'w', POPT_ARG_STRING, NULL, OPT_NONE, NULL, NULL }, + { "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL }, + { "output-format", 'o', POPT_ARG_STRING, NULL, OPT_OUTPUT_FORMAT, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL }, { "list", 'l', POPT_ARG_NONE, NULL, OPT_LIST, NULL, NULL }, { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL }, @@ -134,7 +159,7 @@ static void usage(FILE *fp) fprintf(fp, " (default: payload,context)\n"); fprintf(fp, " -f, --fields name1<,name2,...> Print additional fields:\n"); fprintf(fp, " all, trace, trace:hostname, trace:domain,\n"); - fprintf(fp, " trace:procname, trace:vpid, loglevel.\n"); + fprintf(fp, " trace:procname, trace:vpid, loglevel, emf, callsite.\n"); fprintf(fp, " (default: trace:hostname,trace:procname,trace:vpid)\n"); fprintf(fp, " --clock-cycles Timestamp in cycles\n"); fprintf(fp, " --clock-offset seconds Clock offset in seconds\n"); @@ -151,6 +176,7 @@ static void usage(FILE *fp) static int get_names_args(poptContext *pc) { char *str, *strlist, *strctx; + int ret = 0; opt_payload_field_names = 0; opt_context_field_names = 0; @@ -178,15 +204,20 @@ static int get_names_args(poptContext *pc) opt_payload_field_names = 0; } else { fprintf(stderr, "[error] unknown field name type %s\n", str); - return -EINVAL; + free(strlist); + ret = -EINVAL; + goto end; } } while ((str = strtok_r(NULL, ",", &strctx))); - return 0; +end: + free(strlist); + return ret; } static int get_fields_args(poptContext *pc) { char *str, *strlist, *strctx; + int ret = 0; strlist = (char *) poptGetOptArg(*pc); if (!strlist) { @@ -209,12 +240,19 @@ static int get_fields_args(poptContext *pc) opt_trace_vpid_field = 1; else if (!strcmp(str, "loglevel")) opt_loglevel_field = 1; + else if (!strcmp(str, "emf")) + opt_emf_field = 1; + else if (!strcmp(str, "callsite")) + opt_callsite_field = 1; else { fprintf(stderr, "[error] unknown field type %s\n", str); - return -EINVAL; + ret = -EINVAL; + goto end; } } while ((str = strtok_r(NULL, ",", &strctx))); - return 0; +end: + free(strlist); + return ret; } /* @@ -241,6 +279,27 @@ static int parse_options(int argc, char **argv) while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { + case OPT_OUTPUT_PATH: + opt_output_path = (char *) poptGetOptArg(pc); + if (!opt_output_path) { + ret = -EINVAL; + goto end; + } + break; + case OPT_INPUT_FORMAT: + opt_input_format = (char *) poptGetOptArg(pc); + if (!opt_input_format) { + ret = -EINVAL; + goto end; + } + break; + case OPT_OUTPUT_FORMAT: + opt_output_format = (char *) poptGetOptArg(pc); + if (!opt_output_format) { + ret = -EINVAL; + goto end; + } + break; case OPT_HELP: usage(stdout); ret = 1; /* exit cleanly */ @@ -275,10 +334,10 @@ static int parse_options(int argc, char **argv) break; case OPT_CLOCK_OFFSET: { - const char *str; + char *str; char *endptr; - str = poptGetOptArg(pc); + str = (char *) poptGetOptArg(pc); if (!str) { fprintf(stderr, "[error] Missing --clock-offset argument\n"); ret = -EINVAL; @@ -289,8 +348,10 @@ static int parse_options(int argc, char **argv) if (*endptr != '\0' || str == endptr || errno != 0) { fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str); ret = -EINVAL; + free(str); goto end; } + free(str); break; } case OPT_CLOCK_SECONDS: @@ -385,6 +446,7 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb, return 0; } + /* * bt_context_add_traces_recursive: Open a trace recursively * @@ -405,7 +467,6 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path, GArray *trace_ids; int ret = 0; - int i; /* Should lock traversed_paths mutex here if used in multithread */ @@ -416,6 +477,8 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path, /* Process the array if ntfw did not return a fatal error */ if (ret >= 0) { + int i; + for (i = 0; i < traversed_paths->len; i++) { GString *trace_path = g_ptr_array_index(traversed_paths, i); @@ -436,6 +499,7 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path, g_string_free(trace_path, TRUE); } } + g_ptr_array_free(traversed_paths, TRUE); traversed_paths = NULL; @@ -511,22 +575,10 @@ int main(int argc, char **argv) printf_verbose("Verbose mode active.\n"); printf_debug("Debug mode active.\n"); - if (opt_input_format_arg) { - opt_input_format = strdup(opt_input_format_arg); - if (!opt_input_format) { - partial_error = 1; - goto end; - } + if (opt_input_format) strlower(opt_input_format); - } - if (opt_output_format_arg) { - opt_output_format = strdup(opt_output_format_arg); - if (!opt_output_format) { - partial_error = 1; - goto end; - } + if (opt_output_format) strlower(opt_output_format); - } printf_verbose("Converting from directory(ies):\n"); for (i = 0; i < opt_input_paths->len; i++) { @@ -634,6 +686,7 @@ error_td_read: end: free(opt_input_format); free(opt_output_format); + free(opt_output_path); g_ptr_array_free(opt_input_paths, TRUE); if (partial_error) exit(EXIT_FAILURE); diff --git a/doc/API.txt b/doc/API.txt index 5c06198e..e13e6adf 100644 --- a/doc/API.txt +++ b/doc/API.txt @@ -28,6 +28,20 @@ TERMINOLOGY * A "trace handle" is a unique identifier representing a trace file. It allows the user to manipulate a trace directly. +* The "declaration" of a field or an event, is the structure which contains + the representaion of an object as declared in the metadata. All the + declarations of all events and fields can be accessed as soon as the trace is + open, but of course they contain no trace data, just the layout. + +* The "definition" of a field or an event is the structure in which the actual + trace data is contained. When we read an event in the trace, we access its + definition and we can access all the field definitions contained in all the + scopes of this event to the get the actual data. + +* "Scopes" allow specifying the level at which the information about the + current event must be fetched: event header, event payload, event context, + stream context. Compound-type (arrays, structures, sequences and variants) + fields are relative scopes which contain fields. USAGE @@ -76,6 +90,14 @@ creation will return NULL. The previous iterator must be destroyed before creation of the new iterator. In the future, creation of multiples iterators will be allowed. +The bt_ctf_iter_read_event_flags() function has the same behaviour as +bt_ctf_iter_read_event() but takes an additionnal flag pointer. This flag is +used to inform the user if a special condition occured while reading the event. +As of now, only the BT_ITER_LOST_EVENTS is handled, it informs the user that +some events were discarded by the tracer. To get the number of events lost +immediately prior to the last event read, the user can call the +bt_ctf_get_lost_events_count() function. + Finally, we have the bt_ctf_get_iter() function which returns a struct bt_iter with which the iterator can be moved using one of these functions: bt_iter_next(), moves the iterator to the next event @@ -117,8 +139,13 @@ variant) For more information on each scope, see the CTF specifications. -The function to get a field list is the bt_ctf_get_field_list(). The function -to get the definition of a specific field is bt_ctf_get_field(). +The bt_ctf_get_field_list() function gives access to the list of fields in the +current event. The bt_ctf_get_field() function gives acces to of a specific +field of an event. + +The bt_ctf_get_event_decl_list() and bt_ctf_get_decl_fields() functions give +respectively access to the list of the events declared in a trace and the list +of the fields declared in an event. Once the field is obtained, we can obtain its name and type using the bt_ctf_field_name() and bt_ctf_field_type() functions respectively. The @@ -135,8 +162,8 @@ possible types are defined in the ctf_type_id enum: CTF_TYPE_SEQUENCE, NR_CTF_TYPES. -Depending on the field type, we can get informations about the field with these -functions: +Depending on the field type, we can get informations about the field with the +following functions: * bt_ctf_get_index() return the element at the index position of an array of a sequence; @@ -158,7 +185,13 @@ functions: CTF_STRING_ASCII, CTF_STRING_UNKNOWN. -These functions give access to the value associated with a field : +All of these functions require a field declaration as parameter, depending on +the source type of data (struct definition* or struct bt_ctf_field_decl*), the +user might have to call bt_ctf_get_decl_from_def() or +bt_ctf_get_decl_from_field_decl(). + +The following functions give access to the value associated with a field +defintion: * bt_ctf_get_uint64(); * bt_ctf_get_int64(); * bt_ctf_get_char_array(); diff --git a/doc/Makefile.am b/doc/Makefile.am index 597c43e7..6077f623 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,3 +1,5 @@ dist_man_MANS = babeltrace.1 babeltrace-log.1 dist_doc_DATA = API.txt + +EXTRA_DIST = development.txt diff --git a/doc/development.txt b/doc/development.txt new file mode 100644 index 00000000..7b6c9e35 --- /dev/null +++ b/doc/development.txt @@ -0,0 +1,21 @@ +This document describes some principles that should be respected when +developing in Babeltrace. + +Memory usage : + +Since Babeltrace exports a library, we need to make sure that all allocated +memory is freed, we do not want any memory leaks. +Since Babeltrace uses the glib, it is necessary to assist a little valgrind +when trying to identify memory leaks. + +libpopt has issues with inconsistency between versions. Namely, libpopt +0.16 allocates memory for the string returned by poptgetArg(), but not +libpopt 0.13. Therefore, we are providing a warning suppression file +that covers this case in the extras/ directory of the source code. + +So the proper invocation of Babeltrace with Valgrind is : + +G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full \ + --suppressions=path_to_babeltrace_src/extras/valgrind/popt.supp \ + babeltrace diff --git a/extras/Makefile.am b/extras/Makefile.am new file mode 100644 index 00000000..3e142d45 --- /dev/null +++ b/extras/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = valgrind diff --git a/extras/valgrind/Makefile.am b/extras/valgrind/Makefile.am new file mode 100644 index 00000000..47dcc332 --- /dev/null +++ b/extras/valgrind/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = popt.supp diff --git a/extras/valgrind/popt.supp b/extras/valgrind/popt.supp new file mode 100644 index 00000000..61b5465a --- /dev/null +++ b/extras/valgrind/popt.supp @@ -0,0 +1,8 @@ +{ + + Memcheck:Leak + fun:malloc + fun:poptGetNextOpt + fun:main +} + diff --git a/formats/bt-dummy/bt-dummy.c b/formats/bt-dummy/bt-dummy.c index 2e94421f..b55dd696 100644 --- a/formats/bt-dummy/bt-dummy.c +++ b/formats/bt-dummy/bt-dummy.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -50,12 +58,13 @@ struct trace_descriptor *bt_dummy_open_trace(const char *path, int flags, } static -void bt_dummy_close_trace(struct trace_descriptor *td) +int bt_dummy_close_trace(struct trace_descriptor *td) { struct ctf_text_stream_pos *pos = container_of(td, struct ctf_text_stream_pos, trace_descriptor); free(pos); + return 0; } static @@ -74,4 +83,8 @@ void __attribute__((constructor)) bt_dummy_init(void) assert(!ret); } -/* TODO: finalize */ +static +void __attribute__((destructor)) bt_dummy_exit(void) +{ + bt_unregister_format(&bt_dummy_format); +} diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c index 7211c97f..d344c1c0 100644 --- a/formats/ctf-text/ctf-text.c +++ b/formats/ctf-text/ctf-text.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -49,6 +57,8 @@ int opt_all_field_names, opt_trace_hostname_field, opt_trace_default_fields = 1, opt_loglevel_field, + opt_emf_field, + opt_callsite_field, opt_delta_field = 1; enum field_item { @@ -76,11 +86,12 @@ enum bt_loglevel { BT_LOGLEVEL_DEBUG = 14, }; - +static struct trace_descriptor *ctf_text_open_trace(const char *path, int flags, void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp); -void ctf_text_close_trace(struct trace_descriptor *descriptor); +static +int ctf_text_close_trace(struct trace_descriptor *descriptor); static rw_dispatch write_dispatch_table[] = { @@ -116,6 +127,14 @@ void __attribute__((constructor)) init_quarks(void) Q_STREAM_PACKET_CONTEXT_PACKET_SIZE = g_quark_from_static_string("stream.packet.context.packet_size"); } +static +struct ctf_callsite_dups *ctf_trace_callsite_lookup(struct ctf_trace *trace, + GQuark callsite_name) +{ + return g_hash_table_lookup(trace->callsites, + (gpointer) (unsigned long) callsite_name); +} + int print_field(struct definition *definition) { /* Print all fields in verbose mode */ @@ -385,6 +404,55 @@ int ctf_text_write_event(struct stream_pos *ppos, struct ctf_stream_definition * fprintf(pos->fp, ", "); dom_print = 1; } + if ((opt_emf_field || opt_all_fields) && event_class->model_emf_uri) { + set_field_names_print(pos, ITEM_HEADER); + if (pos->print_names) { + fprintf(pos->fp, "model.emf.uri = "); + } else if (dom_print) { + fprintf(pos->fp, ":"); + } + fprintf(pos->fp, "\"%s\"", + g_quark_to_string(event_class->model_emf_uri)); + if (pos->print_names) + fprintf(pos->fp, ", "); + dom_print = 1; + } + if ((opt_callsite_field || opt_all_fields)) { + struct ctf_callsite_dups *cs_dups; + struct ctf_callsite *callsite; + + cs_dups = ctf_trace_callsite_lookup(stream_class->trace, + event_class->name); + if (cs_dups) { + int i = 0; + + set_field_names_print(pos, ITEM_HEADER); + if (pos->print_names) { + fprintf(pos->fp, "callsite = "); + } else if (dom_print) { + fprintf(pos->fp, ":"); + } + fprintf(pos->fp, "["); + bt_list_for_each_entry(callsite, &cs_dups->head, node) { + if (i != 0) + fprintf(pos->fp, ","); + if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) { + fprintf(pos->fp, "%s@0x%" PRIx64 ":%s:%" PRIu64 "", + callsite->func, callsite->ip, callsite->file, + callsite->line); + } else { + fprintf(pos->fp, "%s:%s:%" PRIu64 "", + callsite->func, callsite->file, + callsite->line); + } + i++; + } + fprintf(pos->fp, "]"); + if (pos->print_names) + fprintf(pos->fp, ", "); + dom_print = 1; + } + } if (dom_print && !pos->print_names) fprintf(pos->fp, " "); set_field_names_print(pos, ITEM_HEADER); @@ -486,7 +554,7 @@ error: return ret; } - +static struct trace_descriptor *ctf_text_open_trace(const char *path, int flags, void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) @@ -523,14 +591,22 @@ error: return NULL; } -void ctf_text_close_trace(struct trace_descriptor *td) +static +int ctf_text_close_trace(struct trace_descriptor *td) { + int ret; struct ctf_text_stream_pos *pos = container_of(td, struct ctf_text_stream_pos, trace_descriptor); - fclose(pos->fp); + ret = fclose(pos->fp); + if (ret) { + perror("Error on fclose"); + return -1; + } g_free(pos); + return 0; } +static void __attribute__((constructor)) ctf_text_init(void) { int ret; @@ -540,4 +616,8 @@ void __attribute__((constructor)) ctf_text_init(void) assert(!ret); } -/* TODO: finalize */ +static +void __attribute__((destructor)) ctf_text_exit(void) +{ + bt_unregister_format(&ctf_text_format); +} diff --git a/formats/ctf-text/types/array.c b/formats/ctf-text/types/array.c index 3aaa6331..97b557f1 100644 --- a/formats/ctf-text/types/array.c +++ b/formats/ctf-text/types/array.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf-text/types/enum.c b/formats/ctf-text/types/enum.c index b973d494..9df8da84 100644 --- a/formats/ctf-text/types/enum.c +++ b/formats/ctf-text/types/enum.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -30,7 +38,7 @@ int ctf_text_enum_write(struct stream_pos *ppos, struct definition *definition) enum_definition->integer; struct ctf_text_stream_pos *pos = ctf_text_pos(ppos); GArray *qs; - int i, ret; + int ret; int field_nr_saved; if (!print_field(definition)) @@ -53,6 +61,8 @@ int ctf_text_enum_write(struct stream_pos *ppos, struct definition *definition) qs = enum_definition->value; if (qs) { + int i; + for (i = 0; i < qs->len; i++) { GQuark q = g_array_index(qs, GQuark, i); const char *str = g_quark_to_string(q); diff --git a/formats/ctf-text/types/float.c b/formats/ctf-text/types/float.c index 77651124..199b0133 100644 --- a/formats/ctf-text/types/float.c +++ b/formats/ctf-text/types/float.c @@ -17,6 +17,14 @@ * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * * Reference: ISO C99 standard 5.2.4 */ diff --git a/formats/ctf-text/types/integer.c b/formats/ctf-text/types/integer.c index f56a753b..0886b062 100644 --- a/formats/ctf-text/types/integer.c +++ b/formats/ctf-text/types/integer.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf-text/types/sequence.c b/formats/ctf-text/types/sequence.c index 3fe5ff17..20345cce 100644 --- a/formats/ctf-text/types/sequence.c +++ b/formats/ctf-text/types/sequence.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf-text/types/string.c b/formats/ctf-text/types/string.c index 1ac38c46..44aeb40d 100644 --- a/formats/ctf-text/types/string.c +++ b/formats/ctf-text/types/string.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf-text/types/struct.c b/formats/ctf-text/types/struct.c index a10e4da1..8a9344eb 100644 --- a/formats/ctf-text/types/struct.c +++ b/formats/ctf-text/types/struct.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf-text/types/variant.c b/formats/ctf-text/types/variant.c index da069c8a..89d518a9 100644 --- a/formats/ctf-text/types/variant.c +++ b/formats/ctf-text/types/variant.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/callbacks.c b/formats/ctf/callbacks.c index 0c221f9d..71e32488 100644 --- a/formats/ctf/callbacks.c +++ b/formats/ctf/callbacks.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -188,6 +196,8 @@ void process_callbacks(struct bt_ctf_iter *iter, assert(iter && stream); ret = extract_ctf_stream_event(stream, &ctf_data); + if (ret) + goto end; /* process all events callback first */ if (iter->main_callbacks.callback) { diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index f43fe917..18a56013 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -86,7 +94,7 @@ void ctf_set_handle(struct trace_descriptor *descriptor, struct bt_trace_handle *handle); static -void ctf_close_trace(struct trace_descriptor *descriptor); +int ctf_close_trace(struct trace_descriptor *descriptor); static uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor, struct bt_trace_handle *handle, enum bt_clock_type type); @@ -548,7 +556,7 @@ error: return ret; } -void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags) +int ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags) { pos->fd = fd; if (fd >= 0) { @@ -578,27 +586,29 @@ void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags) default: assert(0); } + return 0; } -void ctf_fini_pos(struct ctf_stream_pos *pos) +int ctf_fini_pos(struct ctf_stream_pos *pos) { - int ret; - if (pos->prot == PROT_WRITE && pos->content_size_loc) *pos->content_size_loc = pos->offset; if (pos->base_mma) { + int ret; + /* unmap old base */ ret = munmap_align(pos->base_mma); if (ret) { fprintf(stderr, "[error] Unable to unmap old base: %s.\n", strerror(errno)); - assert(0); + return -1; } } if (pos->packet_cycles_index) (void) g_array_free(pos->packet_cycles_index, TRUE); if (pos->packet_real_index) (void) g_array_free(pos->packet_real_index, TRUE); + return 0; } /* @@ -699,6 +709,9 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence) break; } case SEEK_SET: + packet_index = &g_array_index(pos->packet_cycles_index, + struct packet_index, index); + pos->last_events_discarded = packet_index->events_discarded; pos->cur_index = index; file_stream->parent.prev_real_timestamp = 0; file_stream->parent.prev_real_timestamp_end = 0; @@ -897,6 +910,9 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, return -EINVAL; } + if ((header.content_size / CHAR_BIT) < header_sizeof(header)) + return -EINVAL; + toread = (header.content_size / CHAR_BIT) - header_sizeof(header); for (;;) { @@ -970,11 +986,20 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, /* close to flush the buffer */ ret = babeltrace_close_memstream(buf, &size, out); if (ret < 0) { + int closeret; + perror("babeltrace_flush_memstream"); - fclose(in); - return -errno; + ret = -errno; + closeret = fclose(in); + if (closeret) { + perror("Error in fclose"); + } + return ret; + } + ret = fclose(in); + if (ret) { + perror("Error in fclose"); } - fclose(in); /* open for reading */ *fp = babeltrace_fmemopen(*buf, strlen(*buf), "rb"); if (!*fp) { @@ -993,7 +1018,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, struct ctf_file_stream *metadata_stream; FILE *fp; char *buf = NULL; - int ret = 0; + int ret = 0, closeret; metadata_stream = g_new0(struct ctf_file_stream, 1); metadata_stream->pos.last_offset = LAST_OFFSET_POISON; @@ -1003,7 +1028,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, } else { fprintf(stderr, "[error] packet_seek function undefined.\n"); ret = -1; - goto end_stream; + goto end_free; } if (metadata_fp) { @@ -1014,7 +1039,8 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, metadata_stream->pos.fd = openat(td->dirfd, "metadata", O_RDONLY); if (metadata_stream->pos.fd < 0) { fprintf(stderr, "Unable to open metadata.\n"); - return metadata_stream->pos.fd; + ret = -1; + goto end_free; } fp = fdopen(metadata_stream->pos.fd, "r"); @@ -1024,6 +1050,8 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td, ret = -errno; goto end_stream; } + /* fd now belongs to fp */ + metadata_stream->pos.fd = -1; } if (babeltrace_debug) yydebug = 1; @@ -1084,12 +1112,21 @@ end: ctf_scanner_free(scanner); end_scanner_alloc: end_packet_read: - if (fp) - fclose(fp); + if (fp) { + closeret = fclose(fp); + if (closeret) { + perror("Error on fclose"); + } + } free(buf); end_stream: - if (metadata_stream->pos.fd >= 0) - close(metadata_stream->pos.fd); + if (metadata_stream->pos.fd >= 0) { + closeret = close(metadata_stream->pos.fd); + if (closeret) { + perror("Error on metadata stream fd close"); + } + } +end_free: if (ret) g_free(metadata_stream); return ret; @@ -1264,6 +1301,7 @@ int create_stream_packet_index(struct ctf_trace *td, packet_index.timestamp_begin = 0; packet_index.timestamp_end = 0; packet_index.events_discarded = 0; + packet_index.events_discarded_len = 0; /* read and check header, set stream id (and check) */ if (file_stream->parent.trace_packet_header) { @@ -1478,7 +1516,7 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, void (*packet_seek)(struct stream_pos *pos, size_t index, int whence)) { - int ret, fd; + int ret, fd, closeret; struct ctf_file_stream *file_stream; struct stat statbuf; @@ -1512,7 +1550,9 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, goto error_def; } - ctf_init_pos(&file_stream->pos, fd, flags); + ret = ctf_init_pos(&file_stream->pos, fd, flags); + if (ret) + goto error_def; ret = create_trace_definitions(td, &file_stream->parent); if (ret) goto error_def; @@ -1532,11 +1572,17 @@ error_index: if (file_stream->parent.trace_packet_header) definition_unref(&file_stream->parent.trace_packet_header->p); error_def: - ctf_fini_pos(&file_stream->pos); + closeret = ctf_fini_pos(&file_stream->pos); + if (closeret) { + fprintf(stderr, "Error on ctf_fini_pos\n"); + } g_free(file_stream); fd_is_dir_ok: fstat_error: - close(fd); + closeret = close(fd); + if (closeret) { + perror("Error on fd close"); + } error: return ret; } @@ -1547,7 +1593,7 @@ int ctf_open_trace_read(struct ctf_trace *td, void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp) { - int ret; + int ret, closeret; struct dirent *dirent; struct dirent *diriter; size_t dirent_len; @@ -1620,9 +1666,15 @@ int ctf_open_trace_read(struct ctf_trace *td, readdir_error: free(dirent); error_metadata: - close(td->dirfd); + closeret = close(td->dirfd); + if (closeret) { + perror("Error on fd close"); + } error_dirfd: - closedir(td->dir); + closeret = closedir(td->dir); + if (closeret) { + perror("Error on closedir"); + } error: return ret; } @@ -1878,19 +1930,32 @@ int ctf_convert_index_timestamp(struct trace_descriptor *tdp) } static -void ctf_close_file_stream(struct ctf_file_stream *file_stream) +int ctf_close_file_stream(struct ctf_file_stream *file_stream) { - ctf_fini_pos(&file_stream->pos); - close(file_stream->pos.fd); + int ret; + + ret = ctf_fini_pos(&file_stream->pos); + if (ret) { + fprintf(stderr, "Error on ctf_fini_pos\n"); + return -1; + } + ret = close(file_stream->pos.fd); + if (ret) { + perror("Error closing file fd"); + return -1; + } + return 0; } static -void ctf_close_trace(struct trace_descriptor *tdp) +int ctf_close_trace(struct trace_descriptor *tdp) { struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent); - int i; + int ret; if (td->streams) { + int i; + for (i = 0; i < td->streams->len; i++) { struct ctf_stream_declaration *stream; int j; @@ -1900,37 +1965,27 @@ void ctf_close_trace(struct trace_descriptor *tdp) continue; for (j = 0; j < stream->streams->len; j++) { struct ctf_file_stream *file_stream; - file_stream = container_of(g_ptr_array_index(stream->streams, j), struct ctf_file_stream, parent); - ctf_close_file_stream(file_stream); + file_stream = container_of(g_ptr_array_index(stream->streams, j), + struct ctf_file_stream, parent); + ret = ctf_close_file_stream(file_stream); + if (ret) + return ret; } - - } - g_ptr_array_free(td->streams, TRUE); - } - - if (td->event_declarations) { - for (i = 0; i < td->event_declarations->len; i++) { - struct bt_ctf_event_decl *event; - - event = g_ptr_array_index(td->event_declarations, i); - if (event->context_decl) - g_ptr_array_free(event->context_decl, TRUE); - if (event->fields_decl) - g_ptr_array_free(event->fields_decl, TRUE); - if (event->packet_header_decl) - g_ptr_array_free(event->packet_header_decl, TRUE); - if (event->event_context_decl) - g_ptr_array_free(event->event_context_decl, TRUE); - if (event->event_header_decl) - g_ptr_array_free(event->event_header_decl, TRUE); - if (event->packet_context_decl) - g_ptr_array_free(event->packet_context_decl, TRUE); - g_free(event); } - g_ptr_array_free(td->event_declarations, TRUE); } - closedir(td->dir); + ctf_destroy_metadata(td); + ret = close(td->dirfd); + if (ret) { + perror("Error closing dirfd"); + return ret; + } + ret = closedir(td->dir); + if (ret) { + perror("Error closedir"); + return ret; + } g_free(td); + return 0; } static @@ -1953,6 +2008,7 @@ void ctf_set_handle(struct trace_descriptor *descriptor, td->handle = handle; } +static void __attribute__((constructor)) ctf_init(void) { int ret; @@ -1962,4 +2018,8 @@ void __attribute__((constructor)) ctf_init(void) assert(!ret); } -/* TODO: finalize */ +static +void __attribute__((destructor)) ctf_exit(void) +{ + bt_unregister_format(&ctf_format); +} diff --git a/formats/ctf/events-private.h b/formats/ctf/events-private.h index a3caf7ae..201b2b36 100644 --- a/formats/ctf/events-private.h +++ b/formats/ctf/events-private.h @@ -20,6 +20,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/events.c b/formats/ctf/events.c index c281db54..ac7dce46 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -41,8 +49,8 @@ __thread int bt_ctf_last_field_error = 0; const struct definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event, enum bt_ctf_scope scope) { - struct definition *tmp = NULL; - struct ctf_event_definition *event; + const struct definition *tmp = NULL; + const struct ctf_event_definition *event; if (!ctf_event) return NULL; @@ -92,7 +100,7 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, const struct definition *scope, const char *field) { - struct definition *def; + const struct definition *def; char *field_underscore; if (!ctf_event || !scope || !field) @@ -110,10 +118,10 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, def = lookup_definition(scope, field_underscore); g_free(field_underscore); } - if (bt_ctf_field_type(bt_ctf_get_field_decl(def)) == CTF_TYPE_VARIANT) { - struct definition_variant *variant_definition; + if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def)) == CTF_TYPE_VARIANT) { + const struct definition_variant *variant_definition; variant_definition = container_of(def, - struct definition_variant, p); + const struct definition_variant, p); return variant_definition->current_field; } return def; @@ -128,12 +136,12 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, if (!ctf_event || !field) return NULL; - if (bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_ARRAY) { + if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { struct definition_array *array_definition; array_definition = container_of(field, struct definition_array, p); ret = array_index(array_definition, index); - } else if (bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_SEQUENCE) { + } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) { struct definition_sequence *sequence_definition; sequence_definition = container_of(field, struct definition_sequence, p); @@ -144,9 +152,9 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event) { - struct ctf_event_declaration *event_class; - struct ctf_stream_declaration *stream_class; - struct ctf_event_definition *event; + const struct ctf_event_declaration *event_class; + const struct ctf_stream_declaration *stream_class; + const struct ctf_event_definition *event; if (!ctf_event) return NULL; @@ -182,7 +190,7 @@ int bt_ctf_get_field_list(const struct bt_ctf_event *ctf_event, if (!ctf_event || !scope || !list || !count) return -EINVAL; - switch (bt_ctf_field_type(bt_ctf_get_field_decl(scope))) { + switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope))) { case CTF_TYPE_INTEGER: case CTF_TYPE_FLOAT: case CTF_TYPE_STRING: @@ -270,15 +278,15 @@ error: struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event) { struct bt_context *ret = NULL; - struct ctf_file_stream *cfs; - struct ctf_trace *trace; - struct ctf_event_definition *event; + const struct ctf_file_stream *cfs; + const struct ctf_trace *trace; + const struct ctf_event_definition *event; if (!ctf_event) return NULL; event = ctf_event->parent; - cfs = container_of(event->stream, struct ctf_file_stream, + cfs = container_of(event->stream, const struct ctf_file_stream, parent); trace = cfs->parent.stream_class->trace; if (trace->ctx) @@ -290,15 +298,15 @@ struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event) { int ret = -1; - struct ctf_file_stream *cfs; - struct ctf_trace *trace; - struct ctf_event_definition *event; + const struct ctf_file_stream *cfs; + const struct ctf_trace *trace; + const struct ctf_event_definition *event; if (!ctf_event) return -EINVAL; event = ctf_event->parent; - cfs = container_of(event->stream, struct ctf_file_stream, + cfs = container_of(event->stream, const struct ctf_file_stream, parent); trace = cfs->parent.stream_class->trace; if (trace->handle) @@ -309,7 +317,7 @@ int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event) uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) { - struct ctf_event_definition *event; + const struct ctf_event_definition *event; if (!ctf_event) return -1ULL; @@ -323,7 +331,7 @@ uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) { - struct ctf_event_definition *event; + const struct ctf_event_definition *event; if (!ctf_event) return -1ULL; @@ -349,133 +357,110 @@ int bt_ctf_field_get_error(void) return ret; } -static struct declaration_integer *get_declaration_integer(const struct declaration *decl) +static const struct declaration_integer * +get_declaration_integer(const struct declaration *decl) { - struct declaration_field *field_decl; - struct declaration_integer *ret = NULL; - - if (decl && bt_ctf_field_type(decl) == CTF_TYPE_INTEGER) { - field_decl = (struct declaration_field *) decl; - ret = ((struct declaration_integer *) field_decl->declaration); - } - - return ret; + if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER) + return NULL; + return container_of(decl, const struct declaration_integer, p); } -static struct declaration_string *get_declaration_string(const struct declaration *decl) +static const struct declaration_string * +get_declaration_string(const struct declaration *decl) { - struct declaration_field *field_decl; - struct declaration_string *ret = NULL; - - if (decl && bt_ctf_field_type(decl) == CTF_TYPE_STRING) { - field_decl = (struct declaration_field *) decl; - ret = ((struct declaration_string *) field_decl->declaration); - } - - return ret; + if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING) + return NULL; + return container_of(decl, const struct declaration_string, p); } -static struct declaration_array *get_declaration_array(const struct declaration *decl) +static const struct declaration_array * +get_declaration_array(const struct declaration *decl) { - struct declaration_field *field_decl; - struct declaration_array *ret = NULL; - - if (decl && bt_ctf_field_type(decl) == CTF_TYPE_ARRAY) { - field_decl = (struct declaration_field *) decl; - ret = ((struct declaration_array *) field_decl->declaration); - } + if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY) + return NULL; + return container_of(decl, const struct declaration_array, p); +} - return ret; +static const struct declaration_sequence * +get_declaration_sequence(const struct declaration *decl) +{ + if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_SEQUENCE) + return NULL; + return container_of(decl, const struct declaration_sequence, p); } int bt_ctf_get_int_signedness(const struct declaration *decl) { - int ret; - struct declaration_integer *integer; + const struct declaration_integer *integer; integer = get_declaration_integer(decl); - if (integer) { - ret = integer->signedness; - } else { - ret = -EINVAL; + if (!integer) { bt_ctf_field_set_error(-EINVAL); + return -EINVAL; } - - return ret; + return integer->signedness; } int bt_ctf_get_int_base(const struct declaration *decl) { - int ret; - struct declaration_integer *integer; + const struct declaration_integer *integer; integer = get_declaration_integer(decl); - if (integer) { - ret = integer->base; - } else { - ret = -EINVAL; + if (!integer) { bt_ctf_field_set_error(-EINVAL); + return -EINVAL; } - - return ret; + return integer->base; } int bt_ctf_get_int_byte_order(const struct declaration *decl) { - int ret; - struct declaration_integer *integer; + const struct declaration_integer *integer; integer = get_declaration_integer(decl); - if (integer) { - ret = integer->byte_order; - } else { - ret = -EINVAL; + if (!integer) { bt_ctf_field_set_error(-EINVAL); + return -EINVAL; } - - return ret; + return integer->byte_order; } ssize_t bt_ctf_get_int_len(const struct declaration *decl) { - ssize_t ret; - struct declaration_integer *integer; + const struct declaration_integer *integer; integer = get_declaration_integer(decl); - if (integer) { - ret = (ssize_t) integer->len; - } else { - ret = -EINVAL; + if (!integer) { bt_ctf_field_set_error(-EINVAL); + return -EINVAL; } - - return ret; + return (ssize_t) integer->len; } const struct definition *bt_ctf_get_enum_int(const struct definition *field) { - struct definition_enum *def_enum; + const struct definition_enum *def_enum; - if (!field || bt_ctf_field_type(bt_ctf_get_field_decl(field)) != CTF_TYPE_ENUM) { + if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { bt_ctf_field_set_error(-EINVAL); return NULL; } - def_enum = container_of(field, struct definition_enum, p); + def_enum = container_of(field, const struct definition_enum, p); return &def_enum->integer->p; } const char *bt_ctf_get_enum_str(const struct definition *field) { - struct definition_enum *def_enum; - struct declaration_enum *decl_enum; + const struct definition_enum *def_enum; + const struct declaration_enum *decl_enum; GArray *array; const char *ret; - if (!field || bt_ctf_field_type(bt_ctf_get_field_decl(field)) != CTF_TYPE_ENUM) { + if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { bt_ctf_field_set_error(-EINVAL); return NULL; } - def_enum = container_of(field, struct definition_enum, p); + def_enum = container_of(field, const struct definition_enum, p); decl_enum = def_enum->declaration; if (get_int_signedness(&def_enum->integer->p)) { array = enum_int_to_quark_set(decl_enum, @@ -503,27 +488,49 @@ const char *bt_ctf_get_enum_str(const struct definition *field) enum ctf_string_encoding bt_ctf_get_encoding(const struct declaration *decl) { enum ctf_string_encoding ret = 0; - struct declaration_integer *integer; - struct declaration_string *string; + enum ctf_type_id type; + const struct declaration_integer *integer; + const struct declaration_string *string; + const struct declaration_array *array; + const struct declaration_sequence *sequence; if (!decl) goto error; - if (bt_ctf_field_type(decl) == CTF_TYPE_INTEGER) { - integer = get_declaration_integer(decl); - if (integer) { - ret = integer->encoding; - } else { + type = bt_ctf_field_type(decl); + + switch (type) { + case CTF_TYPE_ARRAY: + array = get_declaration_array(decl); + if (!array) goto error; - } - } else if (bt_ctf_field_type(decl) == CTF_TYPE_STRING) { + integer = get_declaration_integer(array->elem); + if (!integer) + goto error; + ret = integer->encoding; + break; + case CTF_TYPE_SEQUENCE: + sequence = get_declaration_sequence(decl); + if (!sequence) + goto error; + integer = get_declaration_integer(sequence->elem); + if (!integer) + goto error; + ret = integer->encoding; + break; + case CTF_TYPE_STRING: string = get_declaration_string(decl); - if (string) { - ret = string->encoding; - } else { + if (!string) goto error; - } - } else { + ret = string->encoding; + break; + case CTF_TYPE_INTEGER: + integer = get_declaration_integer(decl); + if (!integer) + goto error; + ret = integer->encoding; + break; + default: goto error; } return ret; @@ -535,21 +542,12 @@ error: int bt_ctf_get_array_len(const struct declaration *decl) { - int ret; - struct declaration_array *array; + const struct declaration_array *array; - if (decl && bt_ctf_field_type(decl) == CTF_TYPE_ARRAY) { - array = get_declaration_array(decl); - if (array) { - ret = array->len; - } else { - goto error; - } - } else { + array = get_declaration_array(decl); + if (!array) goto error; - } - - return ret; + return array->len; error: bt_ctf_field_set_error(-EINVAL); @@ -560,7 +558,7 @@ uint64_t bt_ctf_get_uint64(const struct definition *field) { uint64_t ret = 0; - if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_INTEGER) + if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) ret = get_unsigned_int(field); else bt_ctf_field_set_error(-EINVAL); @@ -572,13 +570,12 @@ int64_t bt_ctf_get_int64(const struct definition *field) { int64_t ret = 0; - if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_INTEGER) + if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) ret = get_signed_int(field); else bt_ctf_field_set_error(-EINVAL); return ret; - } char *bt_ctf_get_char_array(const struct definition *field) @@ -586,7 +583,7 @@ char *bt_ctf_get_char_array(const struct definition *field) char *ret = NULL; GString *char_array; - if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_ARRAY) { + if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { char_array = get_char_array(field); if (char_array) { ret = char_array->str; @@ -603,7 +600,7 @@ char *bt_ctf_get_string(const struct definition *field) { char *ret = NULL; - if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_STRING) + if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING) ret = get_string(field); else bt_ctf_field_set_error(-EINVAL); @@ -770,10 +767,19 @@ const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field) return rem_(g_quark_to_string(((struct declaration_field *) field)->name)); } -const struct declaration *bt_ctf_get_field_decl(const struct definition *def) +const struct declaration *bt_ctf_get_decl_from_def(const struct definition *def) { if (def) return def->declaration; return NULL; } + +const struct declaration *bt_ctf_get_decl_from_field_decl( + const struct bt_ctf_field_decl *field) +{ + if (field) + return ((struct declaration_field *) field)->declaration; + + return NULL; +} diff --git a/formats/ctf/iterator.c b/formats/ctf/iterator.c index ec74e590..0534d013 100644 --- a/formats/ctf/iterator.c +++ b/formats/ctf/iterator.c @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -47,7 +55,8 @@ struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx, g_free(iter); return NULL; } - iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks)); + iter->callbacks = g_array_new(FALSE, TRUE, + sizeof(struct bt_stream_callbacks)); iter->recalculate_dep_graph = 0; iter->main_callbacks.callback = NULL; iter->dep_gc = g_ptr_array_new(); @@ -81,6 +90,8 @@ void bt_ctf_iter_destroy(struct bt_ctf_iter *iter) } g_array_free(bt_stream_cb->per_id_callbacks, TRUE); } + g_array_free(iter->callbacks, TRUE); + g_ptr_array_free(iter->dep_gc, TRUE); bt_iter_fini(&iter->parent); g_free(iter); @@ -94,11 +105,13 @@ struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter) return &iter->parent; } -struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter) +struct bt_ctf_event *bt_ctf_iter_read_event_flags(struct bt_ctf_iter *iter, + int *flags) { struct ctf_file_stream *file_stream; struct bt_ctf_event *ret; struct ctf_stream_definition *stream; + struct packet_index *packet_index; /* * We do not want to fail for any other reason than end of @@ -116,6 +129,24 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter) ret->parent = g_ptr_array_index(stream->events_by_id, stream->event_id); + if (flags) + *flags = 0; + if (!file_stream->pos.packet_cycles_index) + packet_index = NULL; + else + packet_index = &g_array_index(file_stream->pos.packet_cycles_index, + struct packet_index, file_stream->pos.cur_index); + iter->events_lost = 0; + if (packet_index && packet_index->events_discarded > + file_stream->pos.last_events_discarded) { + if (flags) + *flags |= BT_ITER_FLAG_LOST_EVENTS; + iter->events_lost += packet_index->events_discarded - + file_stream->pos.last_events_discarded; + file_stream->pos.last_events_discarded = + packet_index->events_discarded; + } + if (ret->parent->stream->stream_id > iter->callbacks->len) goto end; @@ -126,3 +157,16 @@ end: stop: return NULL; } + +struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter) +{ + return bt_ctf_iter_read_event_flags(iter, NULL); +} + +uint64_t bt_ctf_get_lost_events_count(struct bt_ctf_iter *iter) +{ + if (!iter) + return -1ULL; + + return iter->events_lost; +} diff --git a/formats/ctf/memstream.h b/formats/ctf/memstream.h index 8b392079..d2a96cb5 100644 --- a/formats/ctf/memstream.h +++ b/formats/ctf/memstream.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #define _GNU_SOURCE diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h index 8d2e5d77..d5a0544a 100644 --- a/formats/ctf/metadata/ctf-ast.h +++ b/formats/ctf/metadata/ctf-ast.h @@ -41,6 +41,7 @@ enum node_type { NODE_ENV, NODE_TRACE, NODE_CLOCK, + NODE_CALLSITE, NODE_CTF_EXPRESSION, NODE_UNARY_EXPRESSION, @@ -91,6 +92,7 @@ struct ctf_node { struct bt_list_head stream; struct bt_list_head event; struct bt_list_head clock; + struct bt_list_head callsite; } root; struct { /* @@ -127,6 +129,13 @@ struct ctf_node { */ struct bt_list_head declaration_list; } clock; + struct { + /* + * Children nodes are ctf_expression, typedef, + * typealias and type_specifier_list. + */ + struct bt_list_head declaration_list; + } callsite; struct { struct bt_list_head left; /* Should be string */ struct bt_list_head right; /* Unary exp. or type */ @@ -298,5 +307,6 @@ int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node); int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node); int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace, int byte_order); +int ctf_destroy_metadata(struct ctf_trace *trace); #endif /* _CTF_AST_H */ diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l index bedda4ad..26aa1bce 100644 --- a/formats/ctf/metadata/ctf-lexer.l +++ b/formats/ctf/metadata/ctf-lexer.l @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -112,6 +120,7 @@ stream setstring(yyextra, yylval, yytext); return STREAM; string setstring(yyextra, yylval, yytext); return STRING; struct setstring(yyextra, yylval, yytext); return STRUCT; trace setstring(yyextra, yylval, yytext); return TRACE; +callsite setstring(yyextra, yylval, yytext); return CALLSITE; typealias setstring(yyextra, yylval, yytext); return TYPEALIAS; typedef setstring(yyextra, yylval, yytext); return TYPEDEF; unsigned setstring(yyextra, yylval, yytext); return UNSIGNED; diff --git a/formats/ctf/metadata/ctf-parser-test.c b/formats/ctf/metadata/ctf-parser-test.c index 72c45885..45dbe681 100644 --- a/formats/ctf/metadata/ctf-parser-test.c +++ b/formats/ctf/metadata/ctf-parser-test.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index 28b7bebe..e7dfd80c 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -72,6 +80,7 @@ static const char *node_type_to_str[] = { [ NODE_STREAM ] = "NODE_STREAM", [ NODE_TRACE ] = "NODE_TRACE", [ NODE_CLOCK ] = "NODE_CLOCK", + [ NODE_CALLSITE ] = "NODE_CALLSITE", [ NODE_CTF_EXPRESSION ] = "NODE_CTF_EXPRESSION", [ NODE_UNARY_EXPRESSION ] = "NODE_UNARY_EXPRESSION", [ NODE_TYPEDEF ] = "NODE_TYPEDEF", @@ -261,6 +270,9 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner, case NODE_CLOCK: BT_INIT_LIST_HEAD(&node->u.clock.declaration_list); break; + case NODE_CALLSITE: + BT_INIT_LIST_HEAD(&node->u.callsite.declaration_list); + break; case NODE_CTF_EXPRESSION: BT_INIT_LIST_HEAD(&node->u.ctf_expression.left); @@ -347,6 +359,9 @@ static int reparent_ctf_expression(struct ctf_node *node, case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_FLOATING_POINT: _bt_list_splice_tail(&node->tmp_head, &parent->u.floating_point.expressions); break; @@ -405,6 +420,9 @@ static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent) case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list); break; @@ -460,6 +478,9 @@ static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent) case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list); break; @@ -508,6 +529,7 @@ static int reparent_type_specifier(struct ctf_node *node, case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_VARIANT: case NODE_STRUCT: case NODE_TYPEDEF: @@ -557,6 +579,9 @@ static int reparent_type_specifier_list(struct ctf_node *node, case NODE_CLOCK: bt_list_add_tail(&node->siblings, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + bt_list_add_tail(&node->siblings, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: bt_list_add_tail(&node->siblings, &parent->u.variant.declaration_list); break; @@ -626,6 +651,7 @@ static int reparent_type_declarator(struct ctf_node *node, case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_VARIANT: case NODE_STRUCT: case NODE_TYPEALIAS: @@ -705,6 +731,13 @@ static int set_parent_node(struct ctf_node *node, return -EPERM; } break; + case NODE_CALLSITE: + if (parent->type == NODE_ROOT) { + _bt_list_splice_tail(&node->tmp_head, &parent->u.root.callsite); + } else { + return -EPERM; + } + break; case NODE_CTF_EXPRESSION: return reparent_ctf_expression(node, parent); @@ -825,6 +858,7 @@ static struct ctf_ast *ctf_ast_alloc(void) BT_INIT_LIST_HEAD(&ast->root.u.root.stream); BT_INIT_LIST_HEAD(&ast->root.u.root.event); BT_INIT_LIST_HEAD(&ast->root.u.root.clock); + BT_INIT_LIST_HEAD(&ast->root.u.root.callsite); return ast; } @@ -834,6 +868,7 @@ static void ctf_ast_free(struct ctf_ast *ast) bt_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc) free(node); + free(ast); } int ctf_scanner_append_ast(struct ctf_scanner *scanner) @@ -913,7 +948,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) */ %expect 2 %start file -%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN +%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CALLSITE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN %token IDENTIFIER ID_TYPE %token ERROR %union @@ -935,6 +970,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %type env_declaration %type trace_declaration %type clock_declaration +%type callsite_declaration %type integer_declaration_specifiers %type declaration_specifiers %type alias_declaration_specifiers @@ -1031,6 +1067,8 @@ keywords: { $$ = yylval.gs; } | CLOCK { $$ = yylval.gs; } + | CALLSITE + { $$ = yylval.gs; } | TOK_ALIGN { $$ = yylval.gs; } ; @@ -1232,6 +1270,8 @@ declaration: { $$ = $1; } | clock_declaration { $$ = $1; } + | callsite_declaration + { $$ = $1; } | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON { struct ctf_node *list; @@ -1399,6 +1439,29 @@ clock_declaration_end: { pop_scope(scanner); } ; +callsite_declaration: + CALLSITE callsite_declaration_begin callsite_declaration_end + { + $$ = make_node(scanner, NODE_CALLSITE); + } + | CALLSITE callsite_declaration_begin ctf_assignment_expression_list callsite_declaration_end + { + $$ = make_node(scanner, NODE_CALLSITE); + if (set_parent_node($3, $$)) + reparent_error(scanner, "trace_declaration"); + } + ; + +callsite_declaration_begin: + LBRAC + { push_scope(scanner); } + ; + +callsite_declaration_end: + RBRAC SEMICOLON + { pop_scope(scanner); } + ; + integer_declaration_specifiers: CONST { diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index ea8148b2..c32aa990 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -508,6 +516,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__); return NULL; } + declaration_unref(nested_declaration); declaration = &array_declaration->p; break; } @@ -520,9 +529,12 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope); if (!sequence_declaration) { fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__); + g_free(length_name); return NULL; } + declaration_unref(nested_declaration); declaration = &sequence_declaration->p; + g_free(length_name); break; } default: @@ -571,6 +583,7 @@ int ctf_struct_type_declarators_visit(FILE *fd, int depth, struct_declaration_add_field(struct_declaration, g_quark_to_string(field_name), field_declaration); + declaration_unref(field_declaration); } return 0; } @@ -604,10 +617,10 @@ int ctf_variant_type_declarators_visit(FILE *fd, int depth, return -EINVAL; } - untagged_variant_declaration_add_field(untagged_variant_declaration, g_quark_to_string(field_name), field_declaration); + declaration_unref(field_declaration); } return 0; } @@ -647,6 +660,7 @@ int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope, type_declaration->declaration_free(type_declaration); return ret; } + declaration_unref(type_declaration); } return 0; } @@ -711,6 +725,7 @@ int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope, err = register_declaration(alias_q, type_declaration, scope); if (err) goto error; + declaration_unref(type_declaration); return 0; error: @@ -816,7 +831,6 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, { struct declaration_struct *struct_declaration; struct ctf_node *iter; - int ret; /* * For named struct (without body), lookup in @@ -828,6 +842,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, struct_declaration = lookup_struct_declaration(g_quark_from_string(name), declaration_scope); + declaration_ref(&struct_declaration->p); return &struct_declaration->p; } else { uint64_t min_align_value = 0; @@ -843,6 +858,8 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, } } if (!bt_list_empty(min_align)) { + int ret; + ret = get_unary_unsigned(min_align, &min_align_value); if (ret) { fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__); @@ -853,12 +870,16 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, struct_declaration = struct_declaration_new(declaration_scope, min_align_value); bt_list_for_each_entry(iter, declaration_list, siblings) { + int ret; + ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, struct_declaration, trace); if (ret) goto error_free_declaration; } if (name) { + int ret; + ret = register_struct_declaration(g_quark_from_string(name), struct_declaration, declaration_scope); @@ -882,7 +903,6 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, struct declaration_untagged_variant *untagged_variant_declaration; struct declaration_variant *variant_declaration; struct ctf_node *iter; - int ret; /* * For named variant (without body), lookup in @@ -894,6 +914,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, untagged_variant_declaration = lookup_variant_declaration(g_quark_from_string(name), declaration_scope); + declaration_ref(&untagged_variant_declaration->p); } else { /* For unnamed variant, create type */ /* For named variant (with body), create type and add to declaration scope */ @@ -907,12 +928,16 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, } untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope); bt_list_for_each_entry(iter, declaration_list, siblings) { + int ret; + ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter, untagged_variant_declaration, trace); if (ret) goto error; } if (name) { + int ret; + ret = register_variant_declaration(g_quark_from_string(name), untagged_variant_declaration, declaration_scope); @@ -1042,7 +1067,6 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, struct last_enum_value last_value; struct ctf_node *iter; GQuark dummy_id; - int ret; /* * For named enum (without body), lookup in @@ -1054,6 +1078,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, enum_declaration = lookup_enum_declaration(g_quark_from_string(name), declaration_scope); + declaration_ref(&enum_declaration->p); return &enum_declaration->p; } else { /* For unnamed enum, create type */ @@ -1097,16 +1122,21 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, last_value.u.u = 0; } bt_list_for_each_entry(iter, enumerator_list, siblings) { + int ret; + ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration, &last_value); if (ret) goto error; } if (name) { + int ret; + ret = register_enum_declaration(g_quark_from_string(name), enum_declaration, declaration_scope); assert(!ret); + declaration_unref(&enum_declaration->p); } return &enum_declaration->p; } @@ -1134,6 +1164,7 @@ struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth, id_q = g_quark_from_string(str_c); g_free(str_c); declaration = lookup_declaration(id_q, declaration_scope); + declaration_ref(declaration); return declaration; } @@ -1741,6 +1772,23 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru } event->loglevel = (int) loglevel; CTF_EVENT_SET_FIELD(event, loglevel); + } else if (!strcmp(left, "model.emf.uri")) { + char *right; + + if (CTF_EVENT_FIELD_IS_SET(event, model_emf_uri)) { + fprintf(fd, "[error] %s: model.emf.uri already declared in event declaration\n", __func__); + ret = -EPERM; + goto error; + } + right = concatenate_unary_strings(&node->u.ctf_expression.right); + if (!right) { + fprintf(fd, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__); + ret = -EINVAL; + goto error; + } + event->model_emf_uri = g_quark_from_string(right); + g_free(right); + CTF_EVENT_SET_FIELD(event, model_emf_uri); } else { fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left); /* Fall-through after warning */ @@ -2416,6 +2464,176 @@ void clock_free(gpointer data) g_free(clock); } +static +int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node, + struct ctf_callsite *callsite, struct ctf_trace *trace) +{ + int ret = 0; + + switch (node->type) { + case NODE_CTF_EXPRESSION: + { + char *left; + + left = concatenate_unary_strings(&node->u.ctf_expression.left); + if (!strcmp(left, "name")) { + char *right; + + if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) { + fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__); + ret = -EPERM; + goto error; + } + right = concatenate_unary_strings(&node->u.ctf_expression.right); + if (!right) { + fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__); + ret = -EINVAL; + goto error; + } + callsite->name = g_quark_from_string(right); + g_free(right); + CTF_CALLSITE_SET_FIELD(callsite, name); + } else if (!strcmp(left, "func")) { + char *right; + + if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) { + fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__); + ret = -EPERM; + goto error; + } + right = concatenate_unary_strings(&node->u.ctf_expression.right); + if (!right) { + fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__); + ret = -EINVAL; + goto error; + } + callsite->func = right; + CTF_CALLSITE_SET_FIELD(callsite, func); + } else if (!strcmp(left, "file")) { + char *right; + + if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) { + fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__); + ret = -EPERM; + goto error; + } + right = concatenate_unary_strings(&node->u.ctf_expression.right); + if (!right) { + fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__); + ret = -EINVAL; + goto error; + } + callsite->file = right; + CTF_CALLSITE_SET_FIELD(callsite, file); + } else if (!strcmp(left, "line")) { + if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) { + fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__); + ret = -EPERM; + goto error; + } + ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line); + if (ret) { + fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__); + ret = -EINVAL; + goto error; + } + CTF_CALLSITE_SET_FIELD(callsite, line); + } else if (!strcmp(left, "ip")) { + if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) { + fprintf(fd, "[error] %s: ip already declared in callsite declaration\n", __func__); + ret = -EPERM; + goto error; + } + ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->ip); + if (ret) { + fprintf(fd, "[error] %s: unexpected unary expression for callsite ip\n", __func__); + ret = -EINVAL; + goto error; + } + CTF_CALLSITE_SET_FIELD(callsite, ip); + } else { + fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left); + } + +error: + g_free(left); + break; + } + default: + return -EPERM; + /* TODO: declaration specifier should be added. */ + } + + return ret; +} + +static +int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace) +{ + int ret = 0; + struct ctf_node *iter; + struct ctf_callsite *callsite; + struct ctf_callsite_dups *cs_dups; + + callsite = g_new0(struct ctf_callsite, 1); + bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { + ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace); + if (ret) + goto error; + } + if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) { + ret = -EPERM; + fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__); + goto error; + } + if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) { + ret = -EPERM; + fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__); + goto error; + } + if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) { + ret = -EPERM; + fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__); + goto error; + } + if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) { + ret = -EPERM; + fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__); + goto error; + } + + cs_dups = g_hash_table_lookup(trace->callsites, + (gpointer) (unsigned long) callsite->name); + if (!cs_dups) { + cs_dups = g_new0(struct ctf_callsite_dups, 1); + BT_INIT_LIST_HEAD(&cs_dups->head); + g_hash_table_insert(trace->callsites, + (gpointer) (unsigned long) callsite->name, cs_dups); + } + bt_list_add_tail(&callsite->node, &cs_dups->head); + return 0; + +error: + g_free(callsite->func); + g_free(callsite->file); + g_free(callsite); + return ret; +} + +static +void callsite_free(gpointer data) +{ + struct ctf_callsite_dups *cs_dups = data; + struct ctf_callsite *callsite, *cs_n; + + bt_list_for_each_entry_safe(callsite, cs_n, &cs_dups->head, node) { + g_free(callsite->func); + g_free(callsite->file); + g_free(callsite); + } + g_free(cs_dups); +} + static int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace) @@ -2458,6 +2676,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->procname, right, TRACER_ENV_LEN); env->procname[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.procname = \"%s\"\n", env->procname); + g_free(right); } else if (!strcmp(left, "hostname")) { char *right; @@ -2473,6 +2692,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->hostname, right, TRACER_ENV_LEN); env->hostname[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.hostname = \"%s\"\n", env->hostname); + g_free(right); } else if (!strcmp(left, "domain")) { char *right; @@ -2488,6 +2708,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->domain, right, TRACER_ENV_LEN); env->domain[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.domain = \"%s\"\n", env->domain); + g_free(right); } else if (!strcmp(left, "sysname")) { char *right; @@ -2503,6 +2724,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->sysname, right, TRACER_ENV_LEN); env->sysname[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.sysname = \"%s\"\n", env->sysname); + g_free(right); } else if (!strcmp(left, "kernel_release")) { char *right; @@ -2518,6 +2740,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->release, right, TRACER_ENV_LEN); env->release[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.release = \"%s\"\n", env->release); + g_free(right); } else if (!strcmp(left, "kernel_version")) { char *right; @@ -2533,12 +2756,14 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node, strncpy(env->version, right, TRACER_ENV_LEN); env->version[TRACER_ENV_LEN - 1] = '\0'; printf_verbose("env.version = \"%s\"\n", env->version); + g_free(right); } else { if (is_unary_string(&node->u.ctf_expression.right)) { char *right; right = concatenate_unary_strings(&node->u.ctf_expression.right); printf_verbose("env.%s = \"%s\"\n", left, right); + g_free(right); } else if (is_unary_unsigned(&node->u.ctf_expression.right)) { uint64_t v; int ret; @@ -2636,7 +2861,6 @@ int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struc return 0; } -/* TODO: missing metadata "destroy" (memory leak) */ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace, int byte_order) { @@ -2648,6 +2872,8 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, trace->byte_order = byte_order; trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, clock_free); + trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, callsite_free); retry: trace->root_declaration_scope = new_declaration_scope(NULL); @@ -2697,6 +2923,14 @@ retry: goto error; } } + bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) { + ret = ctf_callsite_visit(fd, depth + 1, iter, + trace); + if (ret) { + fprintf(fd, "[error] %s: callsite declaration error\n", __func__); + goto error; + } + } if (!trace->streams) { fprintf(fd, "[error] %s: missing trace declaration\n", __func__); ret = -EINVAL; @@ -2738,6 +2972,110 @@ retry: error: free_declaration_scope(trace->root_declaration_scope); + g_hash_table_destroy(trace->callsites); g_hash_table_destroy(trace->clocks); return ret; } + +int ctf_destroy_metadata(struct ctf_trace *trace) +{ + int i; + struct ctf_file_stream *metadata_stream; + + if (trace->streams) { + for (i = 0; i < trace->streams->len; i++) { + struct ctf_stream_declaration *stream; + int j; + + stream = g_ptr_array_index(trace->streams, i); + if (!stream) + continue; + for (j = 0; j < stream->streams->len; j++) { + struct ctf_stream_definition *stream_def; + int k; + + stream_def = g_ptr_array_index(stream->streams, j); + if (!stream_def) + continue; + for (k = 0; k < stream_def->events_by_id->len; k++) { + struct ctf_event_definition *event; + + event = g_ptr_array_index(stream_def->events_by_id, k); + if (!event) + continue; + if (&event->event_fields->p) + definition_unref(&event->event_fields->p); + if (&event->event_context->p) + definition_unref(&event->event_context->p); + g_free(event); + } + if (&stream_def->trace_packet_header->p) + definition_unref(&stream_def->trace_packet_header->p); + if (&stream_def->stream_event_header->p) + definition_unref(&stream_def->stream_event_header->p); + if (&stream_def->stream_packet_context->p) + definition_unref(&stream_def->stream_packet_context->p); + if (&stream_def->stream_event_context->p) + definition_unref(&stream_def->stream_event_context->p); + g_ptr_array_free(stream_def->events_by_id, TRUE); + g_free(stream_def); + } + if (stream->event_header_decl) + declaration_unref(&stream->event_header_decl->p); + if (stream->event_context_decl) + declaration_unref(&stream->event_context_decl->p); + if (stream->packet_context_decl) + declaration_unref(&stream->packet_context_decl->p); + g_ptr_array_free(stream->streams, TRUE); + g_ptr_array_free(stream->events_by_id, TRUE); + g_hash_table_destroy(stream->event_quark_to_id); + free_declaration_scope(stream->declaration_scope); + g_free(stream); + } + g_ptr_array_free(trace->streams, TRUE); + } + + if (trace->event_declarations) { + for (i = 0; i < trace->event_declarations->len; i++) { + struct bt_ctf_event_decl *event_decl; + struct ctf_event_declaration *event; + + event_decl = g_ptr_array_index(trace->event_declarations, i); + if (event_decl->context_decl) + g_ptr_array_free(event_decl->context_decl, TRUE); + if (event_decl->fields_decl) + g_ptr_array_free(event_decl->fields_decl, TRUE); + if (event_decl->packet_header_decl) + g_ptr_array_free(event_decl->packet_header_decl, TRUE); + if (event_decl->event_context_decl) + g_ptr_array_free(event_decl->event_context_decl, TRUE); + if (event_decl->event_header_decl) + g_ptr_array_free(event_decl->event_header_decl, TRUE); + if (event_decl->packet_context_decl) + g_ptr_array_free(event_decl->packet_context_decl, TRUE); + + event = &event_decl->parent; + if (event->fields_decl) + declaration_unref(&event->fields_decl->p); + if (event->context_decl) + declaration_unref(&event->context_decl->p); + free_declaration_scope(event->declaration_scope); + + g_free(event); + } + g_ptr_array_free(trace->event_declarations, TRUE); + } + if (trace->packet_header_decl) + declaration_unref(&trace->packet_header_decl->p); + + free_declaration_scope(trace->root_declaration_scope); + free_declaration_scope(trace->declaration_scope); + + g_hash_table_destroy(trace->callsites); + g_hash_table_destroy(trace->clocks); + + metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent); + g_free(metadata_stream); + + return 0; +} diff --git a/formats/ctf/metadata/ctf-visitor-parent-links.c b/formats/ctf/metadata/ctf-visitor-parent-links.c index 766ce42f..953727e8 100644 --- a/formats/ctf/metadata/ctf-visitor-parent-links.c +++ b/formats/ctf/metadata/ctf-visitor-parent-links.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -211,6 +219,12 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node) if (ret) return ret; } + bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(fd, depth + 1, iter); + if (ret) + return ret; + } break; case NODE_EVENT: @@ -253,6 +267,14 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node) return ret; } break; + case NODE_CALLSITE: + bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(fd, depth + 1, iter); + if (ret) + return ret; + } + break; case NODE_CTF_EXPRESSION: depth++; diff --git a/formats/ctf/metadata/ctf-visitor-semantic-validator.c b/formats/ctf/metadata/ctf-visitor-semantic-validator.c index 3db7fd77..13b2fc55 100644 --- a/formats/ctf/metadata/ctf-visitor-semantic-validator.c +++ b/formats/ctf/metadata/ctf-visitor-semantic-validator.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -110,6 +118,7 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node) case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_TYPEDEF: case NODE_TYPEALIAS_TARGET: case NODE_TYPEALIAS_ALIAS: @@ -214,6 +223,7 @@ int ctf_visitor_type_specifier_list(FILE *fd, int depth, struct ctf_node *node) case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_UNARY_EXPRESSION: case NODE_TYPEALIAS: case NODE_TYPE_SPECIFIER: @@ -255,6 +265,7 @@ int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node) case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_UNARY_EXPRESSION: case NODE_TYPEALIAS: case NODE_TYPE_SPECIFIER: @@ -337,6 +348,7 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node) case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_CTF_EXPRESSION: case NODE_UNARY_EXPRESSION: case NODE_TYPEALIAS: @@ -516,7 +528,20 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node) return ret; } break; + case NODE_CALLSITE: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(fd, depth + 1, iter); + if (ret) + return ret; + } + break; case NODE_CTF_EXPRESSION: switch (node->parent->type) { @@ -526,6 +551,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node) case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_FLOATING_POINT: case NODE_INTEGER: case NODE_STRING: @@ -593,6 +619,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node) case NODE_ENUMERATOR: case NODE_ENUM: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_ENV: default: goto errinval; @@ -699,6 +726,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node) case NODE_ENUMERATOR: case NODE_ENUM: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_ENV: default: goto errinval; diff --git a/formats/ctf/metadata/ctf-visitor-xml.c b/formats/ctf/metadata/ctf-visitor-xml.c index 428a8956..0276f836 100644 --- a/formats/ctf/metadata/ctf-visitor-xml.c +++ b/formats/ctf/metadata/ctf-visitor-xml.c @@ -14,6 +14,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -443,6 +451,17 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node) print_tabs(fd, depth); fprintf(fd, "\n"); break; + case NODE_CALLSITE: + print_tabs(fd, depth); + fprintf(fd, "\n"); + bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { + ret = ctf_visitor_print_xml(fd, depth + 1, iter); + if (ret) + return ret; + } + print_tabs(fd, depth); + fprintf(fd, "\n"); + break; case NODE_CTF_EXPRESSION: diff --git a/formats/ctf/types/array.c b/formats/ctf/types/array.c index e5b428cc..d5b6ed46 100644 --- a/formats/ctf/types/array.c +++ b/formats/ctf/types/array.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/enum.c b/formats/ctf/types/enum.c index e0a2b4d4..e4e7ac85 100644 --- a/formats/ctf/types/enum.c +++ b/formats/ctf/types/enum.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index 9ad4e602..0cf9caeb 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -17,6 +17,14 @@ * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * * Reference: ISO C99 standard 5.2.4 */ @@ -25,6 +33,7 @@ #include /* C99 floating point definitions */ #include /* C99 limits */ #include +#include /* * This library is limited to binary representation of floating point values. @@ -58,13 +67,35 @@ union doubleIEEE754 { #endif }; +/* + * This mutex protects the static temporary float and double + * declarations (static_float_declaration and static_double_declaration). + */ +static pthread_mutex_t float_mutex = PTHREAD_MUTEX_INITIALIZER; + static struct declaration_float *static_float_declaration, *static_double_declaration; struct pos_len { - size_t sign_start, exp_start, mantissa_start, len; + size_t len; }; +static void float_lock(void) +{ + int ret; + + ret = pthread_mutex_lock(&float_mutex); + assert(!ret); +} + +static void float_unlock(void) +{ + int ret; + + ret = pthread_mutex_unlock(&float_mutex); + assert(!ret); +} + int _ctf_float_copy(struct stream_pos *destp, struct definition_float *dest_definition, struct stream_pos *srcp, @@ -148,6 +179,7 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition) struct mmap_align mma; int ret; + float_lock(); switch (float_declaration->mantissa->len + 1) { case FLT_MANT_DIG: tmpdef = static_float_declaration->p.definition_new( @@ -160,7 +192,8 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition) NULL, 0, 0, "__tmpfloat"); break; default: - return -EINVAL; + ret = -EINVAL; + goto end; } tmpfloat = container_of(tmpdef, struct definition_float, p); memset(&destp, 0, sizeof(destp)); @@ -178,9 +211,14 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition) float_definition->value = u.vd; break; default: - return -EINVAL; + ret = -EINVAL; + goto end_unref; } + +end_unref: definition_unref(tmpdef); +end: + float_unlock(); return ret; } @@ -198,6 +236,7 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition) struct mmap_align mma; int ret; + float_lock(); switch (float_declaration->mantissa->len + 1) { case FLT_MANT_DIG: tmpdef = static_float_declaration->p.definition_new( @@ -210,7 +249,8 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition) NULL, 0, 0, "__tmpfloat"); break; default: - return -EINVAL; + ret = -EINVAL; + goto end; } tmpfloat = container_of(tmpdef, struct definition_float, p); ctf_init_pos(&srcp, -1, O_RDONLY); @@ -225,11 +265,16 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition) u.vd = float_definition->value; break; default: - return -EINVAL; + ret = -EINVAL; + goto end_unref; } ctf_align_pos(pos, float_declaration->p.alignment); ret = _ctf_float_copy(ppos, float_definition, &srcp.parent, tmpfloat); + +end_unref: definition_unref(tmpdef); +end: + float_unlock(); return ret; } diff --git a/formats/ctf/types/integer.c b/formats/ctf/types/integer.c index 71ac0f44..66036ae2 100644 --- a/formats/ctf/types/integer.c +++ b/formats/ctf/types/integer.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/sequence.c b/formats/ctf/types/sequence.c index 6aa5750c..7f12bbce 100644 --- a/formats/ctf/types/sequence.c +++ b/formats/ctf/types/sequence.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/string.c b/formats/ctf/types/string.c index 3b54a2df..357e273a 100644 --- a/formats/ctf/types/string.c +++ b/formats/ctf/types/string.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/struct.c b/formats/ctf/types/struct.c index adce6cba..21ce96f6 100644 --- a/formats/ctf/types/struct.c +++ b/formats/ctf/types/struct.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/formats/ctf/types/variant.c b/formats/ctf/types/variant.c index d2ef7714..297f26ff 100644 --- a/formats/ctf/types/variant.c +++ b/formats/ctf/types/variant.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/align.h b/include/babeltrace/align.h index c5589c43..f6a19662 100644 --- a/include/babeltrace/align.h +++ b/include/babeltrace/align.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/babeltrace-internal.h b/include/babeltrace/babeltrace-internal.h index 9f14177d..c567d395 100644 --- a/include/babeltrace/babeltrace-internal.h +++ b/include/babeltrace/babeltrace-internal.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include #include @@ -62,6 +70,8 @@ extern int opt_all_field_names, opt_trace_hostname_field, opt_trace_default_fields, opt_loglevel_field, + opt_emf_field, + opt_callsite_field, opt_delta_field, opt_clock_cycles, opt_clock_seconds, diff --git a/include/babeltrace/babeltrace.h b/include/babeltrace/babeltrace.h index 8eae5384..365382e5 100644 --- a/include/babeltrace/babeltrace.h +++ b/include/babeltrace/babeltrace.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/bitfield.h b/include/babeltrace/bitfield.h index d14d562d..40c11614 100644 --- a/include/babeltrace/bitfield.h +++ b/include/babeltrace/bitfield.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include /* C99 5.2.4.2 Numerical limits */ diff --git a/include/babeltrace/clock-internal.h b/include/babeltrace/clock-internal.h index 6fbc7c32..002cc7fd 100644 --- a/include/babeltrace/clock-internal.h +++ b/include/babeltrace/clock-internal.h @@ -20,6 +20,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ static inline diff --git a/include/babeltrace/clock-types.h b/include/babeltrace/clock-types.h index e1fbfb7d..8a3921aa 100644 --- a/include/babeltrace/clock-types.h +++ b/include/babeltrace/clock-types.h @@ -20,6 +20,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #ifdef __cplusplus diff --git a/include/babeltrace/compiler.h b/include/babeltrace/compiler.h index 2211fe3a..09189bce 100644 --- a/include/babeltrace/compiler.h +++ b/include/babeltrace/compiler.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include /* for offsetof */ diff --git a/include/babeltrace/context-internal.h b/include/babeltrace/context-internal.h index 95d629b8..17d62027 100644 --- a/include/babeltrace/context-internal.h +++ b/include/babeltrace/context-internal.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/context.h b/include/babeltrace/context.h index bc7de3a0..f29ccf08 100644 --- a/include/babeltrace/context.h +++ b/include/babeltrace/context.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -64,7 +72,7 @@ struct bt_context *bt_context_create(void); * * stream_list is a linked list of streams, it is used to open a trace where * the trace data is located in memory mapped areas instead of trace files, - * this argument should be set to NULL when path is NULL. + * this argument should be non-NULL when path is NULL. * * The metadata parameter acts as a metadata override when not NULL, otherwise * the format handles the metadata opening. diff --git a/include/babeltrace/ctf-ir/metadata.h b/include/babeltrace/ctf-ir/metadata.h index 63a6c2a9..fc555fdd 100644 --- a/include/babeltrace/ctf-ir/metadata.h +++ b/include/babeltrace/ctf-ir/metadata.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -32,6 +40,7 @@ struct ctf_trace; struct ctf_stream_declaration; struct ctf_event_declaration; struct ctf_clock; +struct ctf_callsite; struct ctf_stream_definition { struct ctf_stream_declaration *stream_class; @@ -101,6 +110,40 @@ struct ctf_clock { } field_mask; }; +#define CTF_CALLSITE_SET_FIELD(ctf_callsite, field) \ + do { \ + (ctf_callsite)->field_mask |= CTF_CALLSITE_ ## field; \ + } while (0) + +#define CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field) \ + ((ctf_callsite)->field_mask & CTF_CALLSITE_ ## field) + +#define CTF_CALLSITE_GET_FIELD(ctf_callsite, field) \ + ({ \ + assert(CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field)); \ + (ctf_callsite)->(field); \ + }) + +struct ctf_callsite { + GQuark name; /* event name associated with callsite */ + char *func; + char *file; + uint64_t line; + uint64_t ip; + struct bt_list_head node; + enum { /* Fields populated mask */ + CTF_CALLSITE_name = (1U << 0), + CTF_CALLSITE_func = (1U << 1), + CTF_CALLSITE_file = (1U << 2), + CTF_CALLSITE_line = (1U << 3), + CTF_CALLSITE_ip = (1U << 4), + } field_mask; +}; + +struct ctf_callsite_dups { + struct bt_list_head head; +}; + #define CTF_TRACE_SET_FIELD(ctf_trace, field) \ do { \ (ctf_trace)->field_mask |= CTF_TRACE_ ## field; \ @@ -141,6 +184,7 @@ struct ctf_trace { GPtrArray *streams; /* Array of struct ctf_stream_declaration pointers */ struct ctf_stream_definition *metadata; GHashTable *clocks; + GHashTable *callsites; struct ctf_clock *single_clock; /* currently supports only one clock */ struct trace_collection *collection; /* Container of this trace */ GPtrArray *event_declarations; /* Array of all the struct bt_ctf_event_decl */ @@ -237,12 +281,14 @@ struct ctf_event_declaration { uint64_t id; /* Numeric identifier within the stream */ uint64_t stream_id; int loglevel; + GQuark model_emf_uri; enum { /* Fields populated mask */ CTF_EVENT_name = (1 << 0), CTF_EVENT_id = (1 << 1), CTF_EVENT_stream_id = (1 << 2), CTF_EVENT_loglevel = (1 << 4), + CTF_EVENT_model_emf_uri = (1 << 5), } field_mask; }; diff --git a/include/babeltrace/ctf-text/types.h b/include/babeltrace/ctf-text/types.h index b9c9cc30..d69af905 100644 --- a/include/babeltrace/ctf-text/types.h +++ b/include/babeltrace/ctf-text/types.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h index b76f82e1..0390b9a4 100644 --- a/include/babeltrace/ctf/callbacks-internal.h +++ b/include/babeltrace/ctf/callbacks-internal.h @@ -19,6 +19,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/ctf/callbacks.h b/include/babeltrace/ctf/callbacks.h index 128d597b..c178767c 100644 --- a/include/babeltrace/ctf/callbacks.h +++ b/include/babeltrace/ctf/callbacks.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/ctf/events-internal.h b/include/babeltrace/ctf/events-internal.h index aaa09262..0356906f 100644 --- a/include/babeltrace/ctf/events-internal.h +++ b/include/babeltrace/ctf/events-internal.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -68,6 +76,7 @@ struct bt_ctf_iter { * bt_iter. */ GPtrArray *dep_gc; + uint64_t events_lost; }; #endif /*_BABELTRACE_CTF_EVENTS_INTERNAL_H */ diff --git a/include/babeltrace/ctf/events.h b/include/babeltrace/ctf/events.h index e63bae13..19d73612 100644 --- a/include/babeltrace/ctf/events.h +++ b/include/babeltrace/ctf/events.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -109,9 +117,9 @@ uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event); /* * bt_ctf_get_field_list: obtain the list of fields for compound type * - * This function can be used to obtain the list of fields - * contained within a compound type: array, sequence, - * structure, or variant. + * This function can be used to obtain the list of fields contained + * within a top-level scope of an event or a compound type: array, + * sequence, structure, or variant. * This function sets the "list" pointer to an array of definition * pointers and set count to the number of elements in the array. @@ -147,10 +155,17 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *event, const char *bt_ctf_field_name(const struct definition *def); /* - * bt_ctf_get_field_decl: return the declaration of a field or NULL - * on error + * bt_ctf_get_decl_from_def: return the declaration of a field from + * its definition or NULL on error + */ +const struct declaration *bt_ctf_get_decl_from_def(const struct definition *def); + +/* + * bt_ctf_get_decl_from_field_decl: return the declaration of a field from + * a field_decl or NULL on error */ -const struct declaration *bt_ctf_get_field_decl(const struct definition *def); +const struct declaration *bt_ctf_get_decl_from_field_decl( + const struct bt_ctf_field_decl *field); /* * bt_ctf_field_type: returns the type of a field or -1 if unknown @@ -184,7 +199,8 @@ int bt_ctf_get_int_byte_order(const struct declaration *decl); ssize_t bt_ctf_get_int_len(const struct declaration *decl); /* - * bt_ctf_get_encoding: return the encoding of an int or a string. + * bt_ctf_get_encoding: return the encoding of an int, a string, or of + * the integer contained in a char array or a sequence. * return a negative value on error */ enum ctf_string_encoding bt_ctf_get_encoding(const struct declaration *decl); @@ -224,10 +240,16 @@ char *bt_ctf_get_string(const struct definition *field); int bt_ctf_field_get_error(void); /* - * bt_ctf_get_event_decl_list: set list pointer to an array of bt_ctf_event_decl - * pointers and set count to the number of elements in the array. + * bt_ctf_get_event_decl_list: get a list of all the event declarations in + * a trace. + * + * The list array is pointed to the array of event declarations. + * The number of events in the array is written in count. * * Return 0 on success and a negative value on error. + * + * The content pointed to by "list" should *not* be freed. It stays + * valid as long as the trace is opened. */ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, struct bt_ctf_event_decl * const **list, @@ -239,10 +261,15 @@ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event); /* - * bt_ctf_get_decl_fields: set list pointer to an array of bt_ctf_field_decl - * pointers and set count to the number of elements in the array. + * bt_ctf_get_decl_fields: get all field declarations in a scope of an event + * + * The list array is pointed to the array of field declaration. + * The number of field declaration in the array is written in count. * * Returns 0 on success and a negative value on error + * + * The content pointed to by "list" should *not* be freed. It stays + * valid as long as the trace is opened. */ int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl, enum bt_ctf_scope scope, diff --git a/include/babeltrace/ctf/iterator.h b/include/babeltrace/ctf/iterator.h index 9370583a..ec6aac77 100644 --- a/include/babeltrace/ctf/iterator.h +++ b/include/babeltrace/ctf/iterator.h @@ -21,6 +21,14 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -74,6 +82,28 @@ void bt_ctf_iter_destroy(struct bt_ctf_iter *iter); */ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); +/* + * bt_ctf_iter_read_event_flags: Read the iterator's current event data. + * + * @iter: trace collection iterator (input). Should NOT be NULL. + * @flags: pointer passed by the user, in which the trace reader populates + * flags on special condition (BT_ITER_FLAG_*). + * + * Return current event on success, NULL on end of trace. + */ +struct bt_ctf_event *bt_ctf_iter_read_event_flags(struct bt_ctf_iter *iter, + int *flags); + +/* + * bt_ctf_get_lost_events_count: returns the number of events discarded + * immediately prior to the last event read + * + * @iter: trace collection iterator (input). Should NOT be NULL. + * + * Return the number of lost events or -1ULL on error. + */ +uint64_t bt_ctf_get_lost_events_count(struct bt_ctf_iter *iter); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace/ctf/metadata.h b/include/babeltrace/ctf/metadata.h index 5262f44a..1b78762b 100644 --- a/include/babeltrace/ctf/metadata.h +++ b/include/babeltrace/ctf/metadata.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 94231555..6b8752e2 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -29,21 +37,22 @@ #include #include #include +#include #include -#define LAST_OFFSET_POISON ((ssize_t) -1L) +#define LAST_OFFSET_POISON ((int64_t) ~0ULL) struct bt_stream_callbacks; struct packet_index { off_t offset; /* offset of the packet in the file, in bytes */ - off_t data_offset; /* offset of data within the packet, in bits */ + int64_t data_offset; /* offset of data within the packet, in bits */ uint64_t packet_size; /* packet size, in bits */ uint64_t content_size; /* content size, in bits */ uint64_t timestamp_begin; uint64_t timestamp_end; uint64_t events_discarded; - size_t events_discarded_len; /* length of the field, in bits */ + uint64_t events_discarded_len; /* length of the field, in bits */ }; /* @@ -60,13 +69,14 @@ struct ctf_stream_pos { /* Current position */ off_t mmap_offset; /* mmap offset in the file, in bytes */ off_t mmap_base_offset; /* offset of start of packet in mmap, in bytes */ - size_t packet_size; /* current packet size, in bits */ - size_t content_size; /* current content size, in bits */ - uint32_t *content_size_loc; /* pointer to current content size */ + uint64_t packet_size; /* current packet size, in bits */ + uint64_t content_size; /* current content size, in bits */ + uint64_t *content_size_loc; /* pointer to current content size */ struct mmap_align *base_mma;/* mmap base address */ - ssize_t offset; /* offset from base, in bits. EOF for end of file. */ - ssize_t last_offset; /* offset before the last read_event */ - size_t cur_index; /* current index in packet index */ + int64_t offset; /* offset from base, in bits. EOF for end of file. */ + int64_t last_offset; /* offset before the last read_event */ + uint64_t cur_index; /* current index in packet index */ + uint64_t last_events_discarded; /* last known amount of event discarded */ void (*packet_seek)(struct stream_pos *pos, size_t index, int whence); /* function called to switch packet */ @@ -97,8 +107,8 @@ int ctf_sequence_write(struct stream_pos *pos, struct definition *definition); void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence); -void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags); -void ctf_fini_pos(struct ctf_stream_pos *pos); +int ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags); +int ctf_fini_pos(struct ctf_stream_pos *pos); /* * move_pos - move position of a relative bit offset @@ -106,9 +116,9 @@ void ctf_fini_pos(struct ctf_stream_pos *pos); * TODO: allow larger files by updating base too. */ static inline -void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset) +void ctf_move_pos(struct ctf_stream_pos *pos, uint64_t bit_offset) { - printf_debug("ctf_move_pos test EOF: %zd\n", pos->offset); + printf_debug("ctf_move_pos test EOF: %" PRId64 "\n", pos->offset); if (unlikely(pos->offset == EOF)) return; @@ -121,16 +131,16 @@ void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset) */ if ((pos->prot == PROT_WRITE) && (unlikely(pos->offset + bit_offset >= pos->packet_size))) { - printf_debug("ctf_packet_seek (before call): %zd\n", + printf_debug("ctf_packet_seek (before call): %" PRId64 "\n", pos->offset); ctf_packet_seek(&pos->parent, 0, SEEK_CUR); - printf_debug("ctf_packet_seek (after call): %zd\n", + printf_debug("ctf_packet_seek (after call): %" PRId64 "\n", pos->offset); return; } } pos->offset += bit_offset; - printf_debug("ctf_move_pos after increment: %zd\n", pos->offset); + printf_debug("ctf_move_pos after increment: %" PRId64 "\n", pos->offset); } /* @@ -139,7 +149,7 @@ void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset) * TODO: allow larger files by updating base too. */ static inline -void ctf_align_pos(struct ctf_stream_pos *pos, size_t bit_offset) +void ctf_align_pos(struct ctf_stream_pos *pos, uint64_t bit_offset) { ctf_move_pos(pos, offset_align(pos->offset, bit_offset)); } @@ -180,7 +190,7 @@ void ctf_pos_pad_packet(struct ctf_stream_pos *pos) } static inline -int ctf_pos_access_ok(struct ctf_stream_pos *pos, size_t bit_len) +int ctf_pos_access_ok(struct ctf_stream_pos *pos, uint64_t bit_len) { if (unlikely(pos->offset == EOF)) return 0; @@ -198,10 +208,10 @@ void ctf_pos_get_event(struct ctf_stream_pos *pos) { assert(pos->offset <= pos->content_size); if (pos->offset == pos->content_size) { - printf_debug("ctf_packet_seek (before call): %zd\n", + printf_debug("ctf_packet_seek (before call): %" PRId64 "\n", pos->offset); pos->packet_seek(&pos->parent, 0, SEEK_CUR); - printf_debug("ctf_packet_seek (after call): %zd\n", + printf_debug("ctf_packet_seek (after call): %" PRId64 "\n", pos->offset); } } diff --git a/include/babeltrace/endian.h b/include/babeltrace/endian.h index 7df67f55..9eee0c1e 100644 --- a/include/babeltrace/endian.h +++ b/include/babeltrace/endian.h @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #ifdef __FreeBSD__ diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h index ef340da1..c6faca71 100644 --- a/include/babeltrace/format.h +++ b/include/babeltrace/format.h @@ -19,6 +19,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -62,7 +70,7 @@ struct format { void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp); - void (*close_trace)(struct trace_descriptor *descriptor); + int (*close_trace)(struct trace_descriptor *descriptor); void (*set_context)(struct trace_descriptor *descriptor, struct bt_context *ctx); void (*set_handle)(struct trace_descriptor *descriptor, @@ -77,8 +85,8 @@ struct format { extern struct format *bt_lookup_format(bt_intern_str qname); extern void bt_fprintf_format_list(FILE *fp); extern int bt_register_format(struct format *format); +extern void bt_unregister_format(struct format *format); -/* TBD: format unregistration */ #ifdef __cplusplus } #endif diff --git a/include/babeltrace/iterator-internal.h b/include/babeltrace/iterator-internal.h index 8000875e..2b0b2f23 100644 --- a/include/babeltrace/iterator-internal.h +++ b/include/babeltrace/iterator-internal.h @@ -19,6 +19,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/iterator.h b/include/babeltrace/iterator.h index 3f7984fb..360a9c70 100644 --- a/include/babeltrace/iterator.h +++ b/include/babeltrace/iterator.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -24,6 +32,11 @@ extern "C" { #endif +/* Flags for the iterator read_event */ +enum { + BT_ITER_FLAG_LOST_EVENTS = (1 << 0), +}; + /* Forward declarations */ struct bt_iter; struct bt_saved_pos; diff --git a/include/babeltrace/mmap-align.h b/include/babeltrace/mmap-align.h index d0e883a4..f7c18fa6 100644 --- a/include/babeltrace/mmap-align.h +++ b/include/babeltrace/mmap-align.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/prio_heap.h b/include/babeltrace/prio_heap.h index 347a2ced..90aec8f8 100644 --- a/include/babeltrace/prio_heap.h +++ b/include/babeltrace/prio_heap.h @@ -18,6 +18,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/trace-collection.h b/include/babeltrace/trace-collection.h index 0542d03c..2ac9ba6a 100644 --- a/include/babeltrace/trace-collection.h +++ b/include/babeltrace/trace-collection.h @@ -19,6 +19,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #ifdef __cplusplus diff --git a/include/babeltrace/trace-handle-internal.h b/include/babeltrace/trace-handle-internal.h index 36200822..2b5a5ae1 100644 --- a/include/babeltrace/trace-handle-internal.h +++ b/include/babeltrace/trace-handle-internal.h @@ -20,6 +20,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/trace-handle.h b/include/babeltrace/trace-handle.h index 426800d8..96e4a81b 100644 --- a/include/babeltrace/trace-handle.h +++ b/include/babeltrace/trace-handle.h @@ -20,6 +20,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -54,7 +62,7 @@ uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, /* * bt_trace_handle_get_timestamp_end : returns the destruction timestamp - * (in anoseconds or cycles depending on type) of the buffers of a trace + * (in nanoseconds or cycles depending on type) of the buffers of a trace * or -1ULL on error. */ uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index a0ad283d..b42ba03e 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -19,6 +19,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/babeltrace/uuid.h b/include/babeltrace/uuid.h index 4a020210..2ce74670 100644 --- a/include/babeltrace/uuid.h +++ b/include/babeltrace/uuid.h @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/lgpl-2.1.txt b/lgpl-2.1.txt new file mode 100644 index 00000000..84f55233 --- /dev/null +++ b/lgpl-2.1.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/lib/babeltrace.c b/lib/babeltrace.c index 82f01f9b..0bcfd1d2 100644 --- a/lib/babeltrace.c +++ b/lib/babeltrace.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/lib/context.c b/lib/context.c index 0f727a18..5516e494 100644 --- a/lib/context.c +++ b/lib/context.c @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -67,7 +75,7 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, struct trace_descriptor *td; struct format *fmt; struct bt_trace_handle *handle; - int ret; + int ret, closeret; if (!ctx || !format_name || (!path && !stream_list)) return -EINVAL; @@ -82,16 +90,16 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, if (path) { td = fmt->open_trace(path, O_RDONLY, packet_seek, NULL); if (!td) { - fprintf(stderr, "[warning] [Context] Cannot open_trace of the format %s .\n\n", - path); + fprintf(stderr, "[warning] [Context] Cannot open_trace of format %s at path %s.\n\n", + format_name, path); ret = -1; goto end; } } else { td = fmt->open_mmap_trace(stream_list, packet_seek, metadata); if (!td) { - fprintf(stderr, "[error] [Context] Cannot open_trace of the format %s .\n\n", - path); + fprintf(stderr, "[error] [Context] Cannot open_mmap_trace of format %s.\n\n", + format_name); ret = -1; goto end; } @@ -103,7 +111,7 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, fprintf(stderr, "[error] [Context] Creating trace handle %s .\n\n", path); ret = -1; - goto end; + goto error; } handle->format = fmt; handle->td = td; @@ -123,11 +131,11 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, handle); ret = trace_collection_add(ctx->tc, td); if (ret != 0) - goto end; + goto error; ret = fmt->convert_index_timestamp(td); if (ret < 0) - goto end; + goto error; handle->real_timestamp_begin = fmt->timestamp_begin(td, handle, BT_CLOCK_REAL); handle->real_timestamp_end = fmt->timestamp_end(td, handle, BT_CLOCK_REAL); @@ -135,6 +143,12 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, handle->cycles_timestamp_end = fmt->timestamp_end(td, handle, BT_CLOCK_CYCLES); return handle->id; + +error: + closeret = fmt->close_trace(td); + if (closeret) { + fprintf(stderr, "Error in close_trace callback\n"); + } end: return ret; } @@ -142,6 +156,7 @@ end: int bt_context_remove_trace(struct bt_context *ctx, int handle_id) { struct bt_trace_handle *handle; + int ret; if (!ctx) return -EINVAL; @@ -154,8 +169,11 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) /* Remove from containers */ trace_collection_remove(ctx->tc, handle->td); /* Close the trace */ - handle->format->close_trace(handle->td); - + ret = handle->format->close_trace(handle->td); + if (ret) { + fprintf(stderr, "Error in close_trace callback\n"); + return ret; + } /* Remove and free the handle */ g_hash_table_remove(ctx->trace_handles, (gpointer) (unsigned long) handle_id); @@ -168,7 +186,8 @@ void bt_context_destroy(struct bt_context *ctx) assert(ctx); finalize_trace_collection(ctx->tc); - /* Remote all traces. The g_hash_table_destroy will call + /* + * Remove all traces. The g_hash_table_destroy will call * bt_trace_handle_destroy on each elements. */ g_hash_table_destroy(ctx->trace_handles); diff --git a/lib/iterator.c b/lib/iterator.c index b57be035..41a46020 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -253,7 +261,7 @@ static int find_max_timestamp_ctf_stream_class( struct ctf_file_stream **cfsp, uint64_t *max_timestamp) { - int ret = EOF, i; + int ret = EOF, i, found = 0; for (i = 0; i < stream_class->streams->len; i++) { struct ctf_stream_definition *stream; @@ -272,9 +280,13 @@ static int find_max_timestamp_ctf_stream_class( if (current_max_ts >= *max_timestamp) { *max_timestamp = current_max_ts; *cfsp = cfs; + found = 1; } } assert(ret >= 0 || ret == EOF); + if (found) { + return 0; + } return ret; } @@ -381,8 +393,8 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) stream->prev_cycles_timestamp = 0; stream->prev_cycles_timestamp_end = 0; - printf_debug("restored to cur_index = %zd and " - "offset = %zd, timestamp = %" PRIu64 "\n", + printf_debug("restored to cur_index = %" PRId64 " and " + "offset = %" PRId64 ", timestamp = %" PRIu64 "\n", stream_pos->cur_index, stream_pos->offset, stream->real_timestamp); @@ -471,6 +483,10 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) if (ret != 0 && ret != EOF) { goto error; } + if (ret == EOF) { + /* Do not add EOF streams */ + continue; + } ret = heap_insert(iter->stream_heap, file_stream); if (ret) goto error; diff --git a/lib/prio_heap/prio_heap.c b/lib/prio_heap/prio_heap.c index 092f0095..43b4e8a4 100644 --- a/lib/prio_heap/prio_heap.c +++ b/lib/prio_heap/prio_heap.c @@ -15,6 +15,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/lib/registry.c b/lib/registry.c index 3cef63d9..28af184f 100644 --- a/lib/registry.c +++ b/lib/registry.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -29,16 +37,35 @@ struct walk_data { int iter; }; -static int init_done; -void __attribute__((constructor)) format_init(void); -void __attribute__((destructor)) format_finalize(void); - /* * Format registry hash table contains the registered formats. Format * registration is typically performed by a format plugin. - * TODO: support plugin unload (unregistration of formats). */ -GHashTable *format_registry; +static GHashTable *format_registry; +static int format_refcount; +static int init_done; + +static __attribute__((constructor)) void format_init(void); + +static +void format_refcount_inc(void) +{ + format_refcount++; +} + +static +void format_cleanup(void) +{ + if (format_registry) + g_hash_table_destroy(format_registry); +} + +static +void format_refcount_dec(void) +{ + if (!--format_refcount) + format_cleanup(); +} struct format *bt_lookup_format(bt_intern_str name) { @@ -87,22 +114,41 @@ int bt_register_format(struct format *format) if (bt_lookup_format(format->name)) return -EEXIST; + format_refcount_inc(); g_hash_table_insert(format_registry, (gpointer) (unsigned long) format->name, format); return 0; } +void bt_unregister_format(struct format *format) +{ + assert(bt_lookup_format(format->name)); + g_hash_table_remove(format_registry, + (gpointer) (unsigned long) format->name); + format_refcount_dec(); +} + +/* + * We cannot assume that the constructor and destructor order will be + * right: another library might be loaded before us, and initialize us + * from bt_register_format(). This is why we use a reference count to + * handle cleanup of this module. The format_finalize destructor + * refcount decrement matches format_init refcount increment. + */ +static __attribute__((constructor)) void format_init(void) { if (init_done) return; + format_refcount_inc(); format_registry = g_hash_table_new(g_direct_hash, g_direct_equal); assert(format_registry); init_done = 1; } +static __attribute__((destructor)) void format_finalize(void) { - g_hash_table_destroy(format_registry); + format_refcount_dec(); } diff --git a/lib/trace-collection.c b/lib/trace-collection.c index 9b60986f..4f1379c5 100644 --- a/lib/trace-collection.c +++ b/lib/trace-collection.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include #include diff --git a/lib/trace-handle.c b/lib/trace-handle.c index f981adda..0da565b0 100644 --- a/lib/trace-handle.c +++ b/lib/trace-handle.c @@ -17,6 +17,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -41,6 +49,7 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) void bt_trace_handle_destroy(struct bt_trace_handle *th) { + th->format->close_trace(th->td); g_free(th); } diff --git a/mit-license.txt b/mit-license.txt index 5ea7f89a..5f26899a 100644 --- a/mit-license.txt +++ b/mit-license.txt @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. diff --git a/tests/Makefile.am b/tests/Makefile.am index 642dd983..47891e90 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,12 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include +SUBDIRS = lib + noinst_PROGRAMS = test-bitfield test_bitfield_SOURCES = test-bitfield.c + +EXTRA_DIST = runall.sh ctf-traces/** + +check-am: + ./runall.sh diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/metadata b/tests/ctf-traces/succeed/wk-heartbeat-u/metadata new file mode 100755 index 00000000..e35f463e Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/metadata differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_0 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_0 new file mode 100755 index 00000000..3af2cdc1 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_0 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_1 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_1 new file mode 100755 index 00000000..7b74c035 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_1 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_2 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_2 new file mode 100755 index 00000000..13a69fc1 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_2 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_3 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_3 new file mode 100755 index 00000000..1cdde727 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_3 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_4 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_4 new file mode 100755 index 00000000..c1360344 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_4 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_5 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_5 new file mode 100755 index 00000000..a0a58817 Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_5 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_6 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_6 new file mode 100755 index 00000000..b1c8520e Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_6 differ diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_7 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_7 new file mode 100755 index 00000000..05f7393e Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_7 differ diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am new file mode 100644 index 00000000..f7e32c2b --- /dev/null +++ b/tests/lib/Makefile.am @@ -0,0 +1,18 @@ +AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include + +noinst_LIBRARIES = libtestcommon.a + +libtestcommon_a_SOURCES = tap.c tap.h common.c common.h + +test_seeks_LDADD = libtestcommon.a \ + $(top_builddir)/lib/libbabeltrace.la \ + $(top_builddir)/formats/ctf/libbabeltrace-ctf.la + +noinst_PROGRAMS = test-seeks + +test_seeks_SOURCES = test-seeks.c + +EXTRA_DIST = README.tap + +check-am: + ./runall.sh diff --git a/tests/lib/README.tap b/tests/lib/README.tap new file mode 100644 index 00000000..e99e7b2f --- /dev/null +++ b/tests/lib/README.tap @@ -0,0 +1,2 @@ +tap.c and tap.h were taken from +http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap diff --git a/tests/lib/common.c b/tests/lib/common.c new file mode 100644 index 00000000..25bf735e --- /dev/null +++ b/tests/lib/common.c @@ -0,0 +1,42 @@ +/* + * common.c + * + * Lib BabelTrace - Common function to all tests + * + * Copyright 2012 - Yannick Brosseau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#define _GNU_SOURCE + +#include +#include + +struct bt_context *create_context_with_path(const char *path) +{ + struct bt_context *ctx; + int ret; + + ctx = bt_context_create(); + if (!ctx) { + return NULL; + } + + ret = bt_context_add_trace(ctx, path, "ctf", NULL, NULL, NULL); + if (ret < 0) { + bt_context_put(ctx); + return NULL; + } + return ctx; +} diff --git a/tests/lib/common.h b/tests/lib/common.h new file mode 100644 index 00000000..25a02ffa --- /dev/null +++ b/tests/lib/common.h @@ -0,0 +1,28 @@ +/* + * common.h + * + * Lib BabelTrace - Common function to all tests + * + * Copyright 2012 - Yannick Brosseau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef _TESTS_COMMON_H +#define _TESTS_COMMON_H + +struct bt_context; + +struct bt_context *create_context_with_path(const char *path); + +#endif /* _TESTS_COMMON_H */ diff --git a/tests/lib/runall.sh b/tests/lib/runall.sh new file mode 100755 index 00000000..34503bbb --- /dev/null +++ b/tests/lib/runall.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# run Seeks tests +# With a trace than contains empty packets +./test-seeks ../ctf-traces/succeed/wk-heartbeat-u/ 1351532897586558519 1351532897591331194 +# With a bigger trace +./test-seeks ../ctf-traces/succeed/lttng-modules-2.0-pre5/ 61334174524234 61336381998396 \ No newline at end of file diff --git a/tests/lib/tap.c b/tests/lib/tap.c new file mode 100644 index 00000000..a4309511 --- /dev/null +++ b/tests/lib/tap.c @@ -0,0 +1,427 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "tap.h" + +static int no_plan = 0; +static int skip_all = 0; +static int have_plan = 0; +static unsigned int test_count = 0; /* Number of tests that have been run */ +static unsigned int e_tests = 0; /* Expected number of tests to run */ +static unsigned int failures = 0; /* Number of tests that failed */ +static char *todo_msg = NULL; +static char *todo_msg_fixed = "libtap malloc issue"; +static int todo = 0; +static int test_died = 0; + +/* Encapsulate the pthread code in a conditional. In the absence of + libpthread the code does nothing */ +#ifdef HAVE_LIBPTHREAD +#include +static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&M); +# define UNLOCK pthread_mutex_unlock(&M); +#else +# define LOCK +# define UNLOCK +#endif + +static void _expected_tests(unsigned int); +static void _tap_init(void); +static void _cleanup(void); + +/* + * Generate a test result. + * + * ok -- boolean, indicates whether or not the test passed. + * test_name -- the name of the test, may be NULL + * test_comment -- a comment to print afterwards, may be NULL + */ +unsigned int +_gen_result(int ok, const char *func, char *file, unsigned int line, + char *test_name, ...) +{ + va_list ap; + char *local_test_name = NULL; + char *c; + int name_is_digits; + + LOCK; + + test_count++; + + /* Start by taking the test name and performing any printf() + expansions on it */ + if(test_name != NULL) { + va_start(ap, test_name); + vasprintf(&local_test_name, test_name, ap); + va_end(ap); + + /* Make sure the test name contains more than digits + and spaces. Emit an error message and exit if it + does */ + if(local_test_name) { + name_is_digits = 1; + for(c = local_test_name; *c != '\0'; c++) { + if(!isdigit(*c) && !isspace(*c)) { + name_is_digits = 0; + break; + } + } + + if(name_is_digits) { + diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); + diag(" Very confusing."); + } + } + } + + if(!ok) { + printf("not "); + failures++; + } + + printf("ok %d", test_count); + + if(test_name != NULL) { + printf(" - "); + + /* Print the test name, escaping any '#' characters it + might contain */ + if(local_test_name != NULL) { + flockfile(stdout); + for(c = local_test_name; *c != '\0'; c++) { + if(*c == '#') + fputc('\\', stdout); + fputc((int)*c, stdout); + } + funlockfile(stdout); + } else { /* vasprintf() failed, use a fixed message */ + printf("%s", todo_msg_fixed); + } + } + + /* If we're in a todo_start() block then flag the test as being + TODO. todo_msg should contain the message to print at this + point. If it's NULL then asprintf() failed, and we should + use the fixed message. + + This is not counted as a failure, so decrement the counter if + the test failed. */ + if(todo) { + printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); + if(!ok) + failures--; + } + + printf("\n"); + + if(!ok) { + if(getenv("HARNESS_ACTIVE") != NULL) + fputs("\n", stderr); + + diag(" Failed %stest (%s:%s() at line %d)", + todo ? "(TODO) " : "", file, func, line); + } + free(local_test_name); + + UNLOCK; + + /* We only care (when testing) that ok is positive, but here we + specifically only want to return 1 or 0 */ + return ok ? 1 : 0; +} + +/* + * Initialise the TAP library. Will only do so once, however many times it's + * called. + */ +void +_tap_init(void) +{ + static int run_once = 0; + + if(!run_once) { + atexit(_cleanup); + + /* stdout needs to be unbuffered so that the output appears + in the same place relative to stderr output as it does + with Test::Harness */ + setbuf(stdout, 0); + run_once = 1; + } +} + +/* + * Note that there's no plan. + */ +int +plan_no_plan(void) +{ + + LOCK; + + _tap_init(); + + if(have_plan != 0) { + fprintf(stderr, "You tried to plan twice!\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + have_plan = 1; + no_plan = 1; + + UNLOCK; + + return 1; +} + +/* + * Note that the plan is to skip all tests + */ +int +plan_skip_all(char *reason) +{ + + LOCK; + + _tap_init(); + + skip_all = 1; + + printf("1..0"); + + if(reason != NULL) + printf(" # Skip %s", reason); + + printf("\n"); + + UNLOCK; + + exit(0); +} + +/* + * Note the number of tests that will be run. + */ +int +plan_tests(unsigned int tests) +{ + + LOCK; + + _tap_init(); + + if(have_plan != 0) { + fprintf(stderr, "You tried to plan twice!\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + if(tests == 0) { + fprintf(stderr, "You said to run 0 tests! You've got to run something.\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + have_plan = 1; + + _expected_tests(tests); + + UNLOCK; + + return e_tests; +} + +unsigned int +diag(char *fmt, ...) +{ + va_list ap; + + fputs("# ", stderr); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fputs("\n", stderr); + + return 0; +} + +void +_expected_tests(unsigned int tests) +{ + + printf("1..%d\n", tests); + e_tests = tests; +} + +int +skip(unsigned int n, char *fmt, ...) +{ + va_list ap; + char *skip_msg; + + LOCK; + + va_start(ap, fmt); + asprintf(&skip_msg, fmt, ap); + va_end(ap); + + while(n-- > 0) { + test_count++; + printf("ok %d # skip %s\n", test_count, + skip_msg != NULL ? + skip_msg : "libtap():malloc() failed"); + } + + free(skip_msg); + + UNLOCK; + + return 1; +} + +void +todo_start(char *fmt, ...) +{ + va_list ap; + + LOCK; + + va_start(ap, fmt); + vasprintf(&todo_msg, fmt, ap); + va_end(ap); + + todo = 1; + + UNLOCK; +} + +void +todo_end(void) +{ + + LOCK; + + todo = 0; + free(todo_msg); + + UNLOCK; +} + +int +exit_status(void) +{ + int r; + + LOCK; + + /* If there's no plan, just return the number of failures */ + if(no_plan || !have_plan) { + UNLOCK; + return failures; + } + + /* Ran too many tests? Return the number of tests that were run + that shouldn't have been */ + if(e_tests < test_count) { + r = test_count - e_tests; + UNLOCK; + return r; + } + + /* Return the number of tests that failed + the number of tests + that weren't run */ + r = failures + e_tests - test_count; + UNLOCK; + + return r; +} + +/* + * Cleanup at the end of the run, produce any final output that might be + * required. + */ +void +_cleanup(void) +{ + + LOCK; + + /* If plan_no_plan() wasn't called, and we don't have a plan, + and we're not skipping everything, then something happened + before we could produce any output */ + if(!no_plan && !have_plan && !skip_all) { + diag("Looks like your test died before it could output anything."); + UNLOCK; + return; + } + + if(test_died) { + diag("Looks like your test died just after %d.", test_count); + UNLOCK; + return; + } + + + /* No plan provided, but now we know how many tests were run, and can + print the header at the end */ + if(!skip_all && (no_plan || !have_plan)) { + printf("1..%d\n", test_count); + } + + if((have_plan && !no_plan) && e_tests < test_count) { + diag("Looks like you planned %d %s but ran %d extra.", + e_tests, e_tests == 1 ? "test" : "tests", test_count - e_tests); + UNLOCK; + return; + } + + if((have_plan || !no_plan) && e_tests > test_count) { + diag("Looks like you planned %d %s but only ran %d.", + e_tests, e_tests == 1 ? "test" : "tests", test_count); + UNLOCK; + return; + } + + if(failures) + diag("Looks like you failed %d %s of %d.", + failures, failures == 1 ? "test" : "tests", test_count); + + UNLOCK; +} diff --git a/tests/lib/tap.h b/tests/lib/tap.h new file mode 100644 index 00000000..0f059430 --- /dev/null +++ b/tests/lib/tap.h @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* '## __VA_ARGS__' is a gcc'ism. C99 doesn't allow the token pasting + and requires the caller to add the final comma if they've ommitted + the optional arguments */ +#ifdef __GNUC__ +# define ok(e, test, ...) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, \ + test, ## __VA_ARGS__) : \ + _gen_result(0, __func__, __FILE__, __LINE__, \ + test, ## __VA_ARGS__)) + +# define ok1(e) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ + _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) + +# define pass(test, ...) ok(1, test, ## __VA_ARGS__); +# define fail(test, ...) ok(0, test, ## __VA_ARGS__); + +# define skip_start(test, n, fmt, ...) \ + do { \ + if((test)) { \ + skip(n, fmt, ## __VA_ARGS__); \ + continue; \ + } +#elif __STDC_VERSION__ >= 199901L /* __GNUC__ */ +# define ok(e, ...) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, \ + __VA_ARGS__) : \ + _gen_result(0, __func__, __FILE__, __LINE__, \ + __VA_ARGS__)) + +# define ok1(e) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ + _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) + +# define pass(...) ok(1, __VA_ARGS__); +# define fail(...) ok(0, __VA_ARGS__); + +# define skip_start(test, n, ...) \ + do { \ + if((test)) { \ + skip(n, __VA_ARGS__); \ + continue; \ + } +#else /* __STDC_VERSION__ */ +# error "Needs gcc or C99 compiler for variadic macros." +#endif /* __STDC_VERSION__ */ + +#define skip_end() } while(0); + +unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...); + +int plan_no_plan(void); +int plan_skip_all(char *); +int plan_tests(unsigned int); + +unsigned int diag(char *, ...); + +int skip(unsigned int, char *, ...); + +void todo_start(char *, ...); +void todo_end(void); + +int exit_status(void); diff --git a/tests/lib/test-seeks.c b/tests/lib/test-seeks.c new file mode 100644 index 00000000..47bb42e2 --- /dev/null +++ b/tests/lib/test-seeks.c @@ -0,0 +1,249 @@ +/* + * test-seeks.c + * + * Lib BabelTrace - Seeks test program + * + * Copyright 2012 - Yannick Brosseau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" +#include "tap.h" + +#define NR_TESTS 23 + +void run_seek_begin(char *path, uint64_t expected_begin) +{ + struct bt_context *ctx; + struct bt_ctf_iter *iter; + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; + uint64_t timestamp_begin; + uint64_t timestamp_seek_begin; + + /* Open the trace */ + ctx = create_context_with_path(path); + if (!ctx) { + plan_skip_all("Cannot create valid context"); + } + + /* Create iterator with null begin and end */ + iter = bt_ctf_iter_create(ctx, NULL, NULL); + if (!iter) { + plan_skip_all("Cannot create valid iterator"); + } + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid"); + + /* Validate that the first timestamp is right */ + timestamp_begin = bt_ctf_get_timestamp(event); + + ok1(timestamp_begin == expected_begin); + + /* Validate that we get the same value after a seek begin */ + newpos.type = BT_SEEK_BEGIN; + ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos); + + ok(ret == 0, "Seek begin retval %d", ret); + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid"); + + timestamp_seek_begin = bt_ctf_get_timestamp(event); + + ok1(timestamp_begin == timestamp_seek_begin); + + bt_context_put(ctx); +} + + +void run_seek_last(char *path, uint64_t expected_last) +{ + struct bt_context *ctx; + struct bt_ctf_iter *iter; + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; + uint64_t timestamp_last; + + /* Open the trace */ + ctx = create_context_with_path(path); + if (!ctx) { + plan_skip_all("Cannot create valid context"); + } + + /* Create iterator with null last and end */ + iter = bt_ctf_iter_create(ctx, NULL, NULL); + if (!iter) { + plan_skip_all("Cannot create valid iterator"); + } + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at beginning"); + + /* Seek to last */ + newpos.type = BT_SEEK_LAST; + ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos); + + ok(ret == 0, "Seek last retval %d", ret); + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at last position"); + + timestamp_last = bt_ctf_get_timestamp(event); + + ok1(timestamp_last == expected_last); + + /* Try to read next event */ + ret = bt_iter_next(bt_ctf_get_iter(iter)); + + ok(ret == 0, "iter next should return an error"); + + event = bt_ctf_iter_read_event(iter); + + ok(event == 0, "Event after last should be invalid"); + + bt_context_put(ctx); +} + +void run_seek_cycles(char *path, + uint64_t expected_begin, + uint64_t expected_last) +{ + struct bt_context *ctx; + struct bt_ctf_iter *iter; + struct bt_ctf_event *event; + struct bt_iter_pos newpos; + int ret; + uint64_t timestamp; + + /* Open the trace */ + ctx = create_context_with_path(path); + if (!ctx) { + plan_skip_all("Cannot create valid context"); + } + + /* Create iterator with null last and end */ + iter = bt_ctf_iter_create(ctx, NULL, NULL); + if (!iter) { + plan_skip_all("Cannot create valid iterator"); + } + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at beginning"); + + /* Seek to last */ + newpos.type = BT_SEEK_LAST; + ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos); + + ok(ret == 0, "Seek last retval %d", ret); + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at last position"); + + timestamp = bt_ctf_get_timestamp(event); + + ok1(timestamp == expected_last); + + /* Try to read next event */ + ret = bt_iter_next(bt_ctf_get_iter(iter)); + + ok(ret == 0, "iter next should return an error"); + + event = bt_ctf_iter_read_event(iter); + + ok(event == 0, "Event after last should be invalid"); + + /* Seek to BEGIN */ + newpos.type = BT_SEEK_BEGIN; + ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos); + + ok(ret == 0, "Seek begin retval %d", ret); + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at first position"); + + timestamp = bt_ctf_get_timestamp(event); + + ok1(timestamp == expected_begin); + + /* Seek last again */ + newpos.type = BT_SEEK_LAST; + ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos); + + ok(ret == 0, "Seek last retval %d", ret); + + event = bt_ctf_iter_read_event(iter); + + ok(event, "Event valid at last position"); + + timestamp = bt_ctf_get_timestamp(event); + + ok1(timestamp == expected_last); + + bt_context_put(ctx); +} + +int main(int argc, char **argv) +{ + char *path; + uint64_t expected_begin; + uint64_t expected_last; + + plan_tests(NR_TESTS); + + if (argc < 4) { + plan_skip_all("Invalid arguments: need a trace path and the start and last timestamp"); + + } + + /* Parse arguments (Trace, begin timestamp) */ + path = argv[1]; + + expected_begin = strtoull(argv[2], NULL, 0); + if (ULLONG_MAX == expected_begin && errno == ERANGE) { + plan_skip_all("Invalid value for begin timestamp"); + } + + expected_last = strtoull(argv[3], NULL, 0); + if (ULLONG_MAX == expected_last && errno == ERANGE) { + plan_skip_all("Invalid value for last timestamp"); + } + + run_seek_begin(path, expected_begin); + run_seek_last(path, expected_last); + run_seek_cycles(path, expected_begin, expected_last); + + return exit_status(); +} diff --git a/tests/runall.sh b/tests/runall.sh new file mode 100755 index 00000000..b2af6564 --- /dev/null +++ b/tests/runall.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +TESTDIR=$(dirname $0) +DIR=$(readlink -f ${TESTDIR}) +BABELTRACE_BIN=${DIR}/../converter/babeltrace +CTF_TRACES=${DIR}/ctf-traces + +function print_ok () +{ + # Check if we are a terminal + if [ -t 1 ]; then + echo -e "\e[1;32mOK\e[0m" + else + echo -e "OK" + fi +} + +function print_fail () +{ + # Check if we are a terminal + if [ -t 1 ]; then + echo -e "\e[1;31mFAIL\e[0m" + else + echo -e "FAIL" + fi +} + +function test_check () +{ + if [ $? -ne 0 ] ; then + print_fail + return 1 + else + print_ok + return 0 + fi +} + +function test_check_fail () +{ + if [ $? -ne 1 ] ; then + print_fail + return 1 + else + print_ok + return 0 + fi +} + +function run_babeltrace () +{ + ${BABELTRACE_BIN} $* > /dev/null 2>&1 + return $? +} + +echo -e "Running test-bitfield..." +./test-bitfield +test_check +if [ $? -ne 0 ]; then + exit 1 +fi + +#run babeltrace expects success +echo -e "Running babeltrace without argument..." +run_babeltrace +test_check +if [ $? -ne 0 ]; then + exit 1 +fi + +for a in ${CTF_TRACES}/succeed/*; do + echo -e "Running babeltrace for trace ${a}..." + run_babeltrace ${a} + test_check + if [ $? -ne 0 ]; then + exit 1 + fi +done + +#run babeltrace expects failure +echo -e "Running babeltrace with bogus argument..." +run_babeltrace --bogusarg +test_check_fail +if [ $? -ne 0 ]; then + exit 1 +fi + +for a in ${CTF_TRACES}/fail/*; do + echo -e "Running babeltrace for trace ${a}..." + run_babeltrace ${a} + test_check_fail + if [ $? -ne 0 ]; then + exit 1 + fi +done + +exit 0 diff --git a/types/array.c b/types/array.c index 047adac2..3a92ef76 100644 --- a/types/array.c +++ b/types/array.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/types/enum.c b/types/enum.c index 4e3cc45c..ca0143d4 100644 --- a/types/enum.c +++ b/types/enum.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/types/float.c b/types/float.c index 3e49a4b1..028749bc 100644 --- a/types/float.c +++ b/types/float.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -83,7 +91,6 @@ struct definition * container_of(declaration, struct declaration_float, p); struct definition_float *_float; struct definition *tmp; - int ret; _float = g_new(struct definition_float, 1); declaration_ref(&float_declaration->p); @@ -121,6 +128,8 @@ struct definition * _float->p.name = field_name; _float->value = 0.0; if (parent_scope) { + int ret; + ret = register_field_definition(field_name, &_float->p, parent_scope); assert(!ret); diff --git a/types/integer.c b/types/integer.c index 212d8d48..337641d7 100644 --- a/types/integer.c +++ b/types/integer.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/types/sequence.c b/types/sequence.c index bd49d2a6..0e84b1d1 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -206,8 +214,8 @@ void _sequence_definition_free(struct definition *definition) field = g_ptr_array_index(sequence->elems, i); field->declaration->definition_free(field); } + (void) g_ptr_array_free(sequence->elems, TRUE); } - (void) g_ptr_array_free(sequence->elems, TRUE); definition_unref(len_definition); free_definition_scope(sequence->p.scope); declaration_unref(sequence->p.declaration); diff --git a/types/string.c b/types/string.c index daaeef5a..48607406 100644 --- a/types/string.c +++ b/types/string.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/types/struct.c b/types/struct.c index f360407c..138da167 100644 --- a/types/struct.c +++ b/types/struct.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -169,6 +177,7 @@ void _struct_definition_free(struct definition *definition) } free_definition_scope(_struct->p.scope); declaration_unref(_struct->p.declaration); + g_ptr_array_free(_struct->fields, TRUE); g_free(_struct); } diff --git a/types/types.c b/types/types.c index 450c93ba..55990271 100644 --- a/types/types.c +++ b/types/types.c @@ -18,6 +18,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -32,10 +40,13 @@ GQuark prefix_quark(const char *prefix, GQuark quark) { GQuark nq; GString *str; + char *quark_str; str = g_string_new(prefix); g_string_append(str, g_quark_to_string(quark)); - nq = g_quark_from_string(g_string_free(str, FALSE)); + quark_str = g_string_free(str, FALSE); + nq = g_quark_from_string(quark_str); + g_free(quark_str); return nq; } @@ -114,10 +125,10 @@ static int compare_paths(GArray *a, GArray *b, int len) static int is_path_child_of(GArray *path, GArray *maybe_parent) { - int i, ret; + int ret; if (babeltrace_debug) { - int need_dot = 0; + int i, need_dot = 0; printf_debug("Is path \""); for (i = 0; i < path->len; need_dot = 1, i++) @@ -494,7 +505,6 @@ GQuark new_definition_path(struct definition_scope *parent_scope, GQuark path; GString *str; gchar *c_str; - int i; int need_dot = 0; str = g_string_new(""); @@ -502,6 +512,8 @@ GQuark new_definition_path(struct definition_scope *parent_scope, g_string_append(str, root_name); need_dot = 1; } else if (parent_scope) { + int i; + for (i = 0; i < parent_scope->scope_path->len; i++) { GQuark q = g_array_index(parent_scope->scope_path, GQuark, i); diff --git a/types/variant.c b/types/variant.c index faf70dde..55b4b1f0 100644 --- a/types/variant.c +++ b/types/variant.c @@ -16,6 +16,14 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include @@ -90,8 +98,9 @@ void _variant_declaration_free(struct declaration *declaration) struct declaration_variant *variant_declaration = container_of(declaration, struct declaration_variant, p); - _untagged_variant_declaration_free(&variant_declaration->untagged_variant->p); + declaration_unref(&variant_declaration->untagged_variant->p); g_array_free(variant_declaration->tag_name, TRUE); + g_free(variant_declaration); } struct declaration_variant * @@ -244,6 +253,7 @@ void _variant_definition_free(struct definition *definition) definition_unref(variant->enum_tag); free_definition_scope(variant->p.scope); declaration_unref(variant->p.declaration); + g_ptr_array_free(variant->fields, TRUE); g_free(variant); }