Short answer: In the process of making a test case, I found the issue.
Longer answer: Below, I pass in *dbg_pkt, which is already a pointer, and then proceed to use &dbg_pkt in the encode.
dbms_result_e dbms_client_debug_write(dbms_client_ctx_t *ctx, int tag, dbms_debug_cmd_packet_t *dbg_pkt) {
dbms_comm_packet_t comm_pkt;
bool ok;
dbg_pkt->which_cmds = tag;
fprintf(stderr, "debug tag is %02X\n", tag);
memset(&comm_pkt, 0xAA, sizeof(comm_pkt));
pb_ostream_t dbg_os = pb_ostream_from_buffer(&comm_pkt.regs.debug_info, sizeof(comm_pkt.regs.debug_info));
// pb_ostream_t dbg_os = PB_OSTREAM_SIZING;
fprintf(stderr, "max_size: %d\n", dbg_os.max_size);
ok = pb_encode_ex(&dbg_os, dbms_debug_cmd_packet_t_fields, &dbg_pkt, PB_ENCODE_DELIMITED);
// ok = pb_encode_ex(&dbg_os, dbms_debug_cmd_packet_t_fields, &dbg_pkt, 0);
fprintf(stderr, "bytes encoded: %d\n", dbg_os.bytes_written);
if (!ok) {
fprintf(stderr, "encode debug packet error: %s\n", PB_GET_ERROR(&dbg_os));
return DBMS_RESULT_PB_ERR;
}
return dbms_client_write_reg(ctx, DBMS_DEBUG_INFO, &comm_pkt);