diff options
author | Thomas Huth <thuth@redhat.com> | 2017-01-13 13:12:35 +0100 |
---|---|---|
committer | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2017-02-21 18:29:01 +0000 |
commit | 854e67fea6a6f181163a5467fc9ba04de8d181bb (patch) | |
tree | 95528d10774a6b5021083310dee65c7bbe376274 /monitor.c | |
parent | 5fc00480ab1ce767f1c6c63ae644e960295fed2c (diff) |
monitor: Fix crashes when using HMP commands without CPU
When running certain HMP commands ("info registers", "info cpustats",
"info tlb", "nmi", "memsave" or dumping virtual memory) with the "none"
machine, QEMU crashes with a segmentation fault. This happens because the
"none" machine does not have any CPUs by default, but these HMP commands
did not check for a valid CPU pointer yet. Add such checks now, so we get
an error message about the missing CPU instead.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1484309555-1935-1-git-send-email-thuth@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 42 |
1 files changed, 34 insertions, 8 deletions
@@ -1026,6 +1026,9 @@ int monitor_set_cpu(int cpu_index) CPUState *mon_get_cpu(void) { if (!cur_mon->mon_cpu) { + if (!first_cpu) { + return NULL; + } monitor_set_cpu(first_cpu->cpu_index); } cpu_synchronize_state(cur_mon->mon_cpu); @@ -1034,17 +1037,27 @@ CPUState *mon_get_cpu(void) CPUArchState *mon_get_cpu_env(void) { - return mon_get_cpu()->env_ptr; + CPUState *cs = mon_get_cpu(); + + return cs ? cs->env_ptr : NULL; } int monitor_get_cpu_index(void) { - return mon_get_cpu()->cpu_index; + CPUState *cs = mon_get_cpu(); + + return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX; } static void hmp_info_registers(Monitor *mon, const QDict *qdict) { - cpu_dump_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU); + CPUState *cs = mon_get_cpu(); + + if (!cs) { + monitor_printf(mon, "No CPU available\n"); + return; + } + cpu_dump_state(cs, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU); } static void hmp_info_jit(Monitor *mon, const QDict *qdict) @@ -1077,7 +1090,13 @@ static void hmp_info_history(Monitor *mon, const QDict *qdict) static void hmp_info_cpustats(Monitor *mon, const QDict *qdict) { - cpu_dump_statistics(mon_get_cpu(), (FILE *)mon, &monitor_fprintf, 0); + CPUState *cs = mon_get_cpu(); + + if (!cs) { + monitor_printf(mon, "No CPU available\n"); + return; + } + cpu_dump_statistics(cs, (FILE *)mon, &monitor_fprintf, 0); } static void hmp_info_trace_events(Monitor *mon, const QDict *qdict) @@ -1236,6 +1255,12 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, int l, line_size, i, max_digits, len; uint8_t buf[16]; uint64_t v; + CPUState *cs = mon_get_cpu(); + + if (!cs && (format == 'i' || !is_physical)) { + monitor_printf(mon, "Can not dump without CPU\n"); + return; + } if (format == 'i') { int flags = 0; @@ -1265,7 +1290,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, flags = msr_le << 16; flags |= env->bfd_mach; #endif - monitor_disas(mon, mon_get_cpu(), addr, count, is_physical, flags); + monitor_disas(mon, cs, addr, count, is_physical, flags); return; } @@ -1304,7 +1329,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, if (is_physical) { cpu_physical_memory_read(addr, buf, l); } else { - if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) { + if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) { monitor_printf(mon, " Cannot access memory\n"); break; } @@ -2189,11 +2214,12 @@ expr_error(Monitor *mon, const char *fmt, ...) static int get_monitor_def(target_long *pval, const char *name) { const MonitorDef *md = target_monitor_defs(); + CPUState *cs = mon_get_cpu(); void *ptr; uint64_t tmp = 0; int ret; - if (md == NULL) { + if (cs == NULL || md == NULL) { return -1; } @@ -2220,7 +2246,7 @@ static int get_monitor_def(target_long *pval, const char *name) } } - ret = target_get_monitor_def(mon_get_cpu(), name, &tmp); + ret = target_get_monitor_def(cs, name, &tmp); if (!ret) { *pval = (target_long) tmp; } |