wlroots/xwayland/trace.c
Uli Schlachter 744fa2e1b7 xwm: Add an X11 error tracing infrastructure
This adds some infrastructure that records the current X11 sequence
number, file name, and line number at various places. When an X11 error
later comes in, this tracing infrastructure can use the sequence number
of the error to figure out which piece of code caused this X11 error.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-01-09 13:28:30 +01:00

77 lines
2 KiB
C

#include "xwayland/trace.h"
#include <stdlib.h>
#include <wlr/util/log.h>
struct trace_event {
const char *file;
unsigned int line;
unsigned int sequence;
struct wl_list link;
};
static void trace_event_free(struct trace_event *event) {
wl_list_remove(&event->link);
free(event);
}
void wlr_x11_trace_init(struct wlr_x11_trace *trace) {
wl_list_init(&trace->trace_events);
}
void wlr_x11_trace_deinit(struct wlr_x11_trace *trace) {
struct trace_event *event, *next;
wl_list_for_each_safe(event, next, &trace->trace_events, link) {
trace_event_free(event);
}
}
void wlr_x11_trace_trace(struct wlr_x11_trace *trace, unsigned int sequence,
const char *file, unsigned int line) {
struct trace_event *event = malloc(sizeof(*event));
if (event == NULL) {
return;
}
event->file = file;
event->line = line;
event->sequence = sequence;
wl_list_insert(trace->trace_events.prev, &event->link);
}
// Remove entries from the event queue which are no longer needed.
//
// This removes all but one event with an older sequence number than the given
// event.
void wlr_x11_trace_received_event(struct wlr_x11_trace *trace, xcb_generic_event_t *event) {
struct trace_event *entry, *next, *prev = NULL;
wl_list_for_each_safe(entry, next, &trace->trace_events, link) {
if (prev) {
if (entry->sequence >= event->full_sequence) {
break;
}
trace_event_free(prev);
}
prev = entry;
}
}
void wlr_x11_trace_log_error_trace(struct wlr_x11_trace *trace, uint32_t sequence) {
struct trace_event *entry, *prev = NULL;
wl_list_for_each(entry, &trace->trace_events, link) {
if (entry->sequence >= sequence) {
if (prev) {
wlr_log(WLR_ERROR, "X11 error happened somewhere after %s:%d",
prev->file, prev->line);
}
wlr_log(WLR_ERROR, "X11 error happened somewhere before %s:%d",
entry->file, entry->line);
return;
}
prev = entry;
}
if (prev) {
wlr_log(WLR_ERROR, "X11 error happened somewhere after %s:%d",
prev->file, prev->line);
}
}