2020/02/11

2020/02/11

# 研究目的

  • 検証を利用して信頼性を確保するGearsOSを開発中
  • Xv6をベースにGearsOSの実装が進んでいる
  • 現在のOSに欠かせないネットワーク通信/USBなどのプロトコルを高信頼性で実装したい
  • プロコトルは巨大な状態遷移マシンと捉えると、CbC/Gearsでの記述に適している

# やったこと

  • panic関連をチャンレンジしていた
  • バグ取り
  • generate_stubの解読

# panic関連

  • vm(メモリ関連)の書き換え時に「なにか処理をして引数があってない状況などでpanic」したいケースが多かった
    • panicもgotoで飛ばしたい

# panic自体

  • panic自体はCで書かれている
  • cliしてcpuの状態をdumpして無限ループ
  • panicしたかどうかのフラグ panicked をtrueにしている
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
void panic (char *s)
{
    cli();

    cons.locking = 0;

    cprintf("cpu%d: panic: ", cpu->id);

    show_callstk(s);
    panicked = 1; // freeze other CPU

    while (1)
        ;
}

cli

  • cpsr(Current Program Status Registe)で割り込みの制御をしているらしい
    • csprの割り込みに対応するビットをMSR命令でDIS_INTをマスクした値に変えている
1
2
3
4
5
6
7
8
9
void cli (void)
{
    uint val;

    // ok, enable paging using read/modify/write
    asm("MRS %[v], cpsr": [v]"=r" (val)::);
    val |= DIS_INT;
    asm("MSR cpsr_cxsf, %[v]": :[v]"r" (val):);
}

panicした場合はconsoleput(文字出力)で処理が分岐する

  • cliしてwhile(1)に入る
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

void consputc (int c)
{
    if (panicked) {
        cli();
        while (1)
            ;
    }

    if (c == BACKSPACE) {
        uartputc('\b');
        uartputc(' ');
        uartputc('\b');
    } else {
        uartputc(c);
    }

    // cgaputc(c);
}

# CbCで書き直すなら

panic関数はCodeGearにしたい

  • panicked(panicのフラグ)はDataGearに落とし込むのが理想的
  • 今のままだとグローバル変数になってしまう

# DataGear/Interface/CodeGear書いてみた

panickedとかlockを持つConsoleArg

  • DataGearだけ定義する構文が無いので、Interfaceの構文を使っている

# Interface

  • error/ panicのInterface
    • panicはDataGearであるConsoleArgを受け取る
1
2
3
4
5
typedef struct Err <Type, Impl> {
  __code error(Impl* err, int err_code, __code next(...));
  __code panic(Impl* err, char* msg, struct ConsoleArg* ca);
  __code next(...);
} Err;
  • 実装側
    • while(1)って書くか、無限に再帰するかなやんだので、gotoする方向でしてみた
1
2
3
4
typedef struct KernelError <Type, Isa> impl Err {
  __code infinity_loop(Type* err, __code next(...));
  __code next(...);
} KernelError;
  • ConsoleArg
    • panicしたかどうかのフラグと、lock関連
    • console.cbcでstaticに振られていたもの
1
2
3
4
5
typedef struct ConsoleArg <Type, Impl> {
    int panicked;
    struct spinlock lock;
    int locking;
} ConsoleArg;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "param.h"
#include "proc.h"
#interface "Err.h"

// ----
// typedef struct KernelError <Type, Isa> impl Error {
//   __code infinity_loop(Type* error, next(...));
// } KernelError;
// ----

Err* createKernelError(struct Context* cbc_context) {
    struct Err* err  = new Err();
    struct KernelError* kernel_error = new KernelError();
    err->err = (union Data*)kernel_error;
    kernel_error->err = (union Data*)kernel_error;
    kernel_error->infinity_loop = C_infinity_loopKernelError;
    err->error = C_errorKernelError;
    err->panic = C_panicKernelError;
    return err;
}

__code infinity_loopKernelError(struct KernelError* err, __code next(...)) {
  goto next(...);
}

__code errorKernelError(struct KernelError* err, int err_code, __code next(...)) {

    goto next(...);
}

__code panicKernelError(struct KernelError* err, char* msg, struct ConsoleArg* ca) {
    extern struct cpu* cpu;
    extern struct { struct spinlock lock; int locking; } cons;

    cli();
    cons.locking = 0;

    cprintf("cpu%d: panic: ", cpu->id);

    show_callstk(msg);
    ca->panicked = 1; // freeze other CPU

    goto infinity_loopKernelError(err, err->inifinity_loop);
}

# うごかしてみた

  • うまくpanicできてなくて死んでいる
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#0  cli () at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/arm.c:18
#1  0x80032b40 in dabort_handler (r=0x87d1ddf8) at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap.c:50
#2  0x800329b8 in trap_dabort () at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap_asm.S:133
#3  0x80020494 in consputc (c=100) at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:163
#4  0x8002019c in cprintf (fmt=0x80035d78 "data abort: instruction 0x%x, fault addr 0x%x, reason 0x%x \n")
    at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:80
#5  0x80032b68 in dabort_handler (r=0x87d1de98) at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap.c:58
#6  0x800329b8 in trap_dabort () at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap_asm.S:133
#7  0x80020494 in consputc (c=100) at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:163
#8  0x8002019c in cprintf (fmt=0x80035d78 "data abort: instruction 0x%x, fault addr 0x%x, reason 0x%x \n")
    at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:80
#9  0x80032b68 in dabort_handler (r=0x87d1df38) at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap.c:58
#10 0x800329b8 in trap_dabort () at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap_asm.S:133
#11 0x80020494 in consputc (c=100) at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:163
#12 0x8002019c in cprintf (fmt=0x80035d78 "data abort: instruction 0x%x, fault addr 0x%x, reason 0x%x \n")
    at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:80
#13 0x80032b68 in dabort_handler (r=0x87d1dfd8) at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap.c:58
#14 0x800329b8 in trap_dabort () at /mnt/dalmore-home/one/src/anatofuz/CbC_xv6/src/trap_asm.S:133
#15 0x80020494 in consputc (c=100) at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:163
1
2
3
4
5
6
7
8
9
Breakpoint 1, consputc (c=105) at /mnt/dalmore-home/one/build/anatofuz/xv6/CMakeFiles/kernel.dir/c/console.c:163
163         if (Gearef(&proc->cbc_context, ConsoleArg)->panicked) {
(gdb) p proc
$1 = (struct proc *) 0x800b8a5c <ptable+52>
(gdb) p (struct ConsoleArg)proc->cbc_context->data[D_ConsoleArg]
$5 = {ca = 0x87fe1010, panicked = -2013392800, lock = {locked = 2281574596, name = 0x87fe10dc "", cpu = 0x87fe1100, pcs = {
      2281574680, 2281574712, 2281574732, 2281574772, 2281574812, 2281574884, 2281575008, 2281575124, 2281575220, 2281575844}},
  locking = -2013391348}
(gdb) bt

# バグ直し

  • Gearefに書き戻すところをコメントにしていた…
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy