# udebug - OpenWrt debugging infrastructure udebug assists whole-system debugging by making it easy to provide ring buffers with debug data and make them accessible through a unified API. Through the CLI, you can either create snapshots of data with a specific duration, or stream data in real time. The data itself is stored in .pcapng files, which can contain a mix of packets and log messages. ## Notes on using Wireshark In order to parse log messages in .pcapng files, you need to change the Wireshark configuration. Under `Preferences` -> `Protocols` -> `DLT_USER` -> `Encapsulations Table`, add an entry for `User 0 (DLT=147)` with Payload protocol `syslog`. ## libudebug C API #### `void udebug_init(struct udebug *ctx)` Initializes the udebug context. Must be called before adding buffers. #### `int udebug_connect(struct udebug *ctx, const char *path)` Connect to udebugd and submit any buffers that were added using `udebug_buf_add`. #### `void udebug_auto_connect(struct udebug *ctx, const char *path)` Connects and automatically reconnects to udebugd. Uses uloop and calls `udebug_add_uloop`. #### `void udebug_free(struct udebug *ctx)` Frees the udebug context and all added created buffers. #### `int udebug_buf_init(struct udebug_buf *buf, size_t entries, size_t size)` Allocates a buffer with a given size. Entries and size are rounded up internally to the nearest power-of-2. #### `int udebug_buf_add(struct udebug *ctx, struct udebug_buf *buf, const struct udebug_buf_meta *meta);` Submits the buffer to udebugd and makes it visible. #### `void udebug_buf_free(struct udebug_buf *buf)` Removes the buffer from udebugd and frees it. #### `void udebug_entry_init(struct udebug_buf *buf)` Initializes a new entry on the ring buffer. #### `void *udebug_entry_append(struct udebug_buf *buf, const void *data, uint32_t len)` Appends data to the ring buffer. When called with data == NULL, space is only reserved, and the return value provides a pointer with len bytes that can be written to. #### `int udebug_entry_printf(struct udebug_buf *buf, const char *fmt, ...)` Appends a string to the buffer, based on format string + arguments (like printf) #### `int udebug_entry_vprintf(struct udebug_buf *buf, const char *fmt, va_list ap)` Like `udebug_entry_printf()` #### `void udebug_entry_add(struct udebug_buf *buf)` Finalizes and publishes the entry on the ring buffer. ### Simple example ``` static struct udebug ud; static struct udebug_buf udb; /* ... */ uloop_init(); udebug_init(&ud); udebug_auto_connect(&ud, NULL); static const struct udebug_buf_meta buf_meta = { .name = "counter", .format = UDEBUG_FORMAT_STRING, }; int entries = 128; int data_size = 1024; udebug_buf_init(&udb, entries, data_size); udebug_buf_add(&ud, &udb, &buf_meta); /* ... */ udebug_entry_init(&udb); // initialize entry udebug_entry_printf(&udb, "count=%d", count++); udebug_entry_add(&udb); // finalize the entry ``` ## udebug CLI ``` Usage: udebug-cli [] [] Options: -f Ignore errors on opening rings -d : Only fetch data up to seconds old -o |- Set output file for snapshot/stream (or '-' for stdout) -i [:] Select debug buffer for snapshot/stream -s Use udebug socket -q Suppress warnings/error messages Commands: list: List available debug buffers snapshot: Create a pcapng snapshot of debug buffers set_flag [=0|1 ...] Set ring buffer flags get_flags Get ring buffer flags ```