From b1f5f8076abe588d3e4873898cc99351a653b355 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Thu, 18 Jul 2019 17:04:37 +0300 Subject: [PATCH] weston-log-flight-rec: Add a global variable to access the ring buffer With it add also a function which can be used in an assert()-like situation to display the contents of the ring buffer. Within gdb this call also be called if the program is loaded/still loaded into memory. The global variable will be used in a later patch to be accessed from a python gdb script. Signed-off-by: Marius Vlad --- include/libweston/weston-log.h | 3 ++ libweston/weston-log-flight-rec.c | 59 ++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/include/libweston/weston-log.h b/include/libweston/weston-log.h index 3a437b270..88c0d1a8a 100644 --- a/include/libweston/weston-log.h +++ b/include/libweston/weston-log.h @@ -126,6 +126,9 @@ struct weston_log_subscription * weston_log_subscription_iterate(struct weston_log_scope *scope, struct weston_log_subscription *sub_iter); +void +weston_log_flight_recorder_display_buffer(FILE *file); + #ifdef __cplusplus } #endif diff --git a/libweston/weston-log-flight-rec.c b/libweston/weston-log-flight-rec.c index d1d7c8bc1..1a2093403 100644 --- a/libweston/weston-log-flight-rec.c +++ b/libweston/weston-log-flight-rec.c @@ -46,6 +46,10 @@ struct weston_ring_buffer { bool overlap; /**< in case buff overlaps, hint from where to print buf contents */ }; +/** allows easy access to the ring buffer in case of a core dump + */ +WL_EXPORT struct weston_ring_buffer *weston_primary_flight_recorder_ring_buffer = NULL; + /** A black box type of stream, used to aggregate data continuously, and * when needed, to dump its contents for inspection. */ @@ -182,6 +186,28 @@ weston_log_flight_recorder_map_memory(struct weston_debug_log_flight_recorder *f flight_rec->rb.buf[i] = 0xff; } +static void +weston_log_subscriber_display_flight_rec_data(struct weston_ring_buffer *rb, + FILE *file) +{ + FILE *file_d = stderr; + if (file) + file_d = file; + + if (rb->append_pos <= rb->size && !rb->overlap) { + if (rb->append_pos) + fwrite(rb->buf, sizeof(char), rb->append_pos, file_d); + else + fwrite(rb->buf, sizeof(char), rb->size, file_d); + } else { + /* from append_pos to size */ + fwrite(&rb->buf[rb->append_pos], sizeof(char), + rb->size - rb->append_pos, file_d); + /* from 0 to append_pos */ + fwrite(rb->buf, sizeof(char), rb->append_pos, file_d); + } +} + WL_EXPORT void weston_log_subscriber_display_flight_rec(struct weston_log_subscriber *sub) { @@ -189,18 +215,7 @@ weston_log_subscriber_display_flight_rec(struct weston_log_subscriber *sub) to_flight_recorder(sub); struct weston_ring_buffer *rb = &flight_rec->rb; - if (rb->append_pos <= rb->size && !rb->overlap) { - if (rb->append_pos) - fwrite(rb->buf, sizeof(char), rb->append_pos, rb->file); - else - fwrite(rb->buf, sizeof(char), rb->size, rb->file); - } else { - /* from append_pos to size */ - fwrite(&rb->buf[rb->append_pos], sizeof(char), - rb->size - rb->append_pos, rb->file); - /* from 0 to append_pos */ - fwrite(rb->buf, sizeof(char), rb->append_pos, rb->file); - } + weston_log_subscriber_display_flight_rec_data(rb, rb->file); } /** Create a flight recorder type of subscriber @@ -234,6 +249,7 @@ weston_log_subscriber_create_flight_rec(size_t size) } weston_ring_buffer_init(&flight_rec->rb, size, weston_rb); + weston_primary_flight_recorder_ring_buffer = &flight_rec->rb; /* write some data to the rb such that the memory gets mapped */ weston_log_flight_recorder_map_memory(flight_rec); @@ -254,3 +270,22 @@ weston_log_subscriber_destroy_flight_rec(struct weston_log_subscriber *sub) free(flight_rec->rb.buf); free(flight_rec); } + +/** Retrieve flight recorder ring buffer contents, could be useful when + * implementing an assert()-like wrapper. + * + * @param file a FILE type already opened. Can also pass stderr/stdout under gdb + * if the program is loaded into memory. + * + * Uses the global exposed weston_primary_flight_recorder_ring_buffer. + * + */ +WL_EXPORT void +weston_log_flight_recorder_display_buffer(FILE *file) +{ + if (!weston_primary_flight_recorder_ring_buffer) + return; + + weston_log_subscriber_display_flight_rec_data(weston_primary_flight_recorder_ring_buffer, + file); +}