0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

qemuのゲストメモリをホストのデバッガから確認する

Last updated at Posted at 2024-12-02

目的

Exception発生時などにメモリダンプとかしたい

cortex-m

マシンコード内

sはARMv7MStateを持つマシン作成時の構造体。(例えばSTM32F100Stateみたいな)
nはmemory_region_add_subregionの順と思われる。

((CPUState*)s->armv7m ->cpu)->cpu_ases [0].memory_dispatch ->map .sections[n].mr->ram_block->host 

ファイルに吐き出すならこんな感じ

uint8_t *p = ((CPUState*)s->armv7m->cpu)->cpu_ases [0].memory_dispatch ->map .sections[n].mr->ram_block->host;

FILE *fp;
if ((fp = fopen(DUMP_FILE_NAME, "wb")) != 0) {
  fwrite(p, RAM_SIZE, 1, fp);
  fclose(fp);
}

アボート時

callback登録しておくと便利な気がする。
標準で無いのかな?

tyano:qemu$ git diff system/ hw/intc/ | cat
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 404a445138..00d3776643 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -28,6 +28,7 @@
 #include "qemu/module.h"
 #include "trace.h"
 
+void (*machine_specific_memory_dump)(MemoryRegion*);
 /* IRQ number counting:
  *
  * the num-irq property counts the number of external IRQ lines
@@ -521,6 +522,7 @@ static void armv7m_nvic_clear_pending(NVICState *s, int irq, bool secure)
     }
 }
 
+MemoryRegionSection *get_memory_region_section(ARMCPU *cpu);
 static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
                                        bool derived)
 {
@@ -645,6 +647,17 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
                  * Lockup condition due to a guest bug. We don't model
                  * Lockup, so report via cpu_abort() instead.
                  */
+
+if (machine_specific_memory_dump) {
+    MemoryRegionSection* section = get_memory_region_section(s->cpu);
+    for(int i=0;i<10;i++) {
+        if (!section->size) break;
+        if(section->mr->ram  ) {
+            machine_specific_memory_dump(section->mr);
+        }
+        section++;
+    }
+}
                 cpu_abort(CPU(s->cpu),
                           "Lockup: can't escalate %d to HardFault "
                           "(current priority %d)\n", irq, running);
diff --git a/system/physmem.c b/system/physmem.c
index 9a3b3a7636..a7226b30c3 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -3897,3 +3897,8 @@ bool ram_block_discard_is_required(void)
     return qatomic_read(&ram_block_discard_required_cnt) ||
            qatomic_read(&ram_block_coordinated_discard_required_cnt);
 }
+
+MemoryRegionSection *get_memory_region_section(ARMCPU *cpu);
+MemoryRegionSection *get_memory_region_section(ARMCPU *cpu) {
+    return ((CPUState*)cpu)->cpu_ases->memory_dispatch ->map .sections;
+}

gdb

多分これが一番はやい?

abortしたらこんな感じになると思う

(gdb) bt 
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff674a6d3 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78
#2  0x00007ffff66f1c4e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff66d9902 in __GI_abort () at abort.c:79
#4  0x0000555556077051 in cpu_abort (cpu=0x555557b7bd70, fmt=0x5555565ad260 "Lockup: can't escalate %d to HardFault (current priority %d)\n") at ../qemu/cpu-target.c:372
#5  0x0000555556005b15 in do_armv7m_nvic_set_pending (opaque=0x555557afb2d0, irq=3, secure=false, derived=false) at ../qemu/hw/intc/armv7m_nvic.c:661
#6  0x0000555556005ba2 in armv7m_nvic_set_pending (s=0x555557afb2d0, irq=12, secure=false) at ../qemu/hw/intc/armv7m_nvic.c:679
#7  0x0000555555f931d8 in arm_v7m_cpu_do_interrupt (cs=0x555557b7bd70) at ../qemu/target/arm/tcg/m_helper.c:2358
#8  0x00005555560c5fa2 in cpu_handle_exception (cpu=0x555557b7bd70, ret=0x7fff6fdff44c) at ../qemu/accel/tcg/cpu-exec.c:758
#9  0x00005555560c67ef in cpu_exec_loop (cpu=0x555557b7bd70, sc=0x7fff
...

大きさであたりをつけて

(gdb) set $i=0
(gdb) while $i < 10
 >p/x ((CPUState*)s->cpu)->cpu_ases->memory_dispatch->map ->sections[$i].size 
 >set $i=$i+1
 >end
$425 = 0x10000000000000000
$426 = 0x20000
$427 = 0x8000
$428 = 0x2000000
$429 = 0x70000
$430 = 0x400
$431 = 0x20
$432 = 0x20
$433 = 0x400
$434 = 0x14

ダンプする

(gdb) p/x ((CPUState*)s->cpu)->cpu_ases->memory_dispatch->map ->sections[2].mr->ram_block->host
$435 = 0x7ffff4400000
(gdb) dump binary memory memory_dump.bin 0x7ffff4400000 (0x7ffff4400000 + 0x8000)
(gdb) shell od -Ax -tx1z memory_dump.bin | head -5
000000 d5 00 00 00 ca 02 00 00 95 01 00 00 90 01 00 00  >................<
000010 03 00 00 00 00 00 00 00 c4 02 00 00 96 01 00 00  >................<
000020 94 01 00 00 92 01 00 00 11 22 33 44 55 66 77 88  >........."3DUfw.<
000030 99 aa bb cc dd ee ff 00 40 00 4d 00 40 00 0c 00  >........@.M.@...<
000040 bd 04 00 00 8d 04 00 00 00 6c dc 02 00 12 7a 00  >.........l....z.<

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?