gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo

Change the thread info related packets handling to support multiprocess
extension.

Add the CPUs class name in the extra info to help differentiate
them in multiprocess mode.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-8-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Luc Michel 2019-01-07 15:23:46 +00:00 committed by Peter Maydell
parent 8dbbe9ac7f
commit 7cf48f6752

View File

@ -1268,7 +1268,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
CPUState *cpu;
CPUClass *cc;
const char *p;
uint32_t thread;
uint32_t pid, tid;
int ch, reg_size, type, res;
uint8_t mem_buf[MAX_PACKET_LENGTH];
@ -1565,26 +1564,44 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
put_packet(s, buf);
break;
} else if (strcmp(p,"fThreadInfo") == 0) {
s->query_cpu = first_cpu;
s->query_cpu = gdb_first_attached_cpu(s);
goto report_cpuinfo;
} else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo:
if (s->query_cpu) {
snprintf(buf, sizeof(buf), "m%x", cpu_gdb_index(s->query_cpu));
snprintf(buf, sizeof(buf), "m%s",
gdb_fmt_thread_id(s, s->query_cpu,
thread_id, sizeof(thread_id)));
put_packet(s, buf);
s->query_cpu = CPU_NEXT(s->query_cpu);
s->query_cpu = gdb_next_attached_cpu(s, s->query_cpu);
} else
put_packet(s, "l");
break;
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
thread = strtoull(p+16, (char **)&p, 16);
cpu = find_cpu(thread);
if (read_thread_id(p + 16, &p, &pid, &tid) == GDB_READ_THREAD_ERR) {
put_packet(s, "E22");
break;
}
cpu = gdb_get_cpu(s, pid, tid);
if (cpu != NULL) {
cpu_synchronize_state(cpu);
/* memtohex() doubles the required space */
len = snprintf((char *)mem_buf, sizeof(buf) / 2,
"CPU#%d [%s]", cpu->cpu_index,
cpu->halted ? "halted " : "running");
if (s->multiprocess && (s->process_num > 1)) {
/* Print the CPU model and name in multiprocess mode */
ObjectClass *oc = object_get_class(OBJECT(cpu));
const char *cpu_model = object_class_get_name(oc);
char *cpu_name =
object_get_canonical_path_component(OBJECT(cpu));
len = snprintf((char *)mem_buf, sizeof(buf) / 2,
"%s %s [%s]", cpu_model, cpu_name,
cpu->halted ? "halted " : "running");
g_free(cpu_name);
} else {
/* memtohex() doubles the required space */
len = snprintf((char *)mem_buf, sizeof(buf) / 2,
"CPU#%d [%s]", cpu->cpu_index,
cpu->halted ? "halted " : "running");
}
trace_gdbstub_op_extra_info((char *)mem_buf);
memtohex(buf, mem_buf, len);
put_packet(s, buf);