diff --git a/include/libweston/weston-log.h b/include/libweston/weston-log.h index 3a437b27..88c0d1a8 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 d1d7c8bc..1a209340 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,27 +186,38 @@ weston_log_flight_recorder_map_memory(struct weston_debug_log_flight_recorder *f flight_rec->rb.buf[i] = 0xff; } -WL_EXPORT void -weston_log_subscriber_display_flight_rec(struct weston_log_subscriber *sub) +static void +weston_log_subscriber_display_flight_rec_data(struct weston_ring_buffer *rb, + FILE *file) { - struct weston_debug_log_flight_recorder *flight_rec = - to_flight_recorder(sub); - struct weston_ring_buffer *rb = &flight_rec->rb; + 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, rb->file); + fwrite(rb->buf, sizeof(char), rb->append_pos, file_d); else - fwrite(rb->buf, sizeof(char), rb->size, rb->file); + 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, rb->file); + rb->size - rb->append_pos, file_d); /* from 0 to append_pos */ - fwrite(rb->buf, sizeof(char), rb->append_pos, rb->file); + fwrite(rb->buf, sizeof(char), rb->append_pos, file_d); } } +WL_EXPORT void +weston_log_subscriber_display_flight_rec(struct weston_log_subscriber *sub) +{ + struct weston_debug_log_flight_recorder *flight_rec = + to_flight_recorder(sub); + struct weston_ring_buffer *rb = &flight_rec->rb; + + weston_log_subscriber_display_flight_rec_data(rb, rb->file); +} + /** Create a flight recorder type of subscriber * * Allocates both the flight recorder and the underlying ring buffer. Use @@ -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); +}