1

次の問題があります。ソフトウェアがデッドロックを引き起こしています。その原因について私が持っている唯一の手がかりは、このような状況に対してチップセットによって提供される 8 レベルのみのプリミティブ スタック トレースです。

ただし、私のスタック トレースは次のようなものです。

memset
memset
memset
memset
memset
memset
memset
memset

どの関数がこの混乱を引き起こしているかを確認するために、 memset を邪魔にならないように削除したいと思います。gcc に memset をインライン化するように依頼すると、gcc は関数本体がないと文句を言います。

それで、memsetをインライン化する方法はありますか? この問題のデバッグについて他に考えがある人はいますか?

編集

forを使用して memset をダム実装に置き換えようとしましたが、これによりソフトウェアの動作がおかしくなり、デッドロックに陥るのを妨げる他の問題が発生しました。

編集

ちなみに、MIPS arch を使っています。私は MIPS アセンブリの専門家ではないので、memset の逆アセンブル コードを取得し、C 関数の本体に挿入するというばかげた試みをしました。objdump -d と gdb 逆アセンブルの指示が違うので、両方試してみました。作成した関数は次のとおりです。

void * memset(void * str_a, int ch, size_t count) {
    asm("mov    #12,r0");
    asm("cmp/gt r6,r0");
    asm("mov    r4,r0");
    asm("bt.s   30 <.L_dup_bytes+0x18>");
    asm("add    r4,r6");
    asm("tst    #3,r0");
    asm("bt.s   18 <.L_dup_bytes>");
    asm("extu.b r5,r5");
    asm("mov.b  r5,@r0");
    asm("add    #1,r0");
    asm("tst    #3,r0");
    asm("bf 10 <_memset+0x10>");
}

void * memset(void * str_a, int ch, size_t count) {
    asm("mov    #12,r0");
    asm("cmp/gt r6,r0");
    asm("mov    r4,r0");
    asm("bt.s   0x8163682c <memset+48>");
    asm("add    r4,r6");
    asm("tst    #3,r0");
    asm("bt.s   0x81636814 <memset+24>");
    asm("extu.b r5,r5");
    asm("mov.b  r5,@r0");
    asm("add    #1,r0");
    asm("tst    #3,r0");
    asm("bf 0x8163680c <memset+16>");
    asm("swap.b r5,r2");
    asm("or r2,r5");
    asm("swap.w r5,r2");
    asm("or r2,r5");
    asm("add    #-16,r6");
    asm("nop    ");
    asm("mov.l  r5,@r0");
    asm("cmp/hs r6,r0");
    asm("mov.l  r5,@(4,r0)");
    asm("bf.s   0x81636820 <memset+36>");
    asm("add    #8,r0");
    asm("add    #16,r6");
    asm("cmp/eq r6,r0");
    asm("bt 0x81636838 <memset+60>");
    asm("mov.b  r5,@r0");
    asm("add    #1,r0");
    asm("cmp/eq r6,r0");
    asm("bf 0x81636830 <memset+52>");
    asm("rts    ");
    asm("mov    r4,r0");
}

これにより、次のエラーが発生しました。

最初のメムセット:

/tmp/ccAuFFap.s: Assembler messages:
/tmp/ccAuFFap.s:3457: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3469: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3489: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3457: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/ccAuFFap.s:3469: Error: displacement to undefined symbol .L0 overflows 8-bit field 
/tmp/ccAuFFap.s:3489: Error: displacement to defined symbol .L0 overflows 8-bit field

2 番目の memset:

/tmp/cctCDgi5.s: Assembler messages:
/tmp/cctCDgi5.s:3457: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3469: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3489: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3529: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3545: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3561: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3457: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3469: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3489: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3529: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3545: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3561: Error: displacement to defined symbol .L0 overflows 8-bit field

誰かがそれらのエラーを助けることができますか?

編集

からのソースコードで別のバージョンを試しました:

void * memset(void * str_a, int ch, size_t count) {    
    asm("slti    t1, a2, 8               ");
    asm("bne     t1, zero, L(last8)");
    asm("move    v0, a0                  ");
    asm("beq     a1, zero, L(ueven)      ");
    asm("andi    a1, 0xff                ");
    asm("sll     t0, a1, 8");
    asm("or      a1, t0");
    asm("sll     t0, a1, 16");
    asm("or      a1, t0                  ");
    asm("L(ueven):       ");
    asm("subu    t0, zero, a0            ");
    asm("andi    t0, 0x3");
    asm("beq     t0, zero, L(chkw)");
    asm("subu    a2, t0");
    asm("SWHI    a1, 0(a0)               ");
    asm("addu    a0, t0                  ");
    asm("L(chkw):        ");
    asm("andi    t0, a2, 0x7             ");
    asm("beq     t0, a2, L(chkl)");
    asm("subu    a3, a2, t0");
    asm("addu    a3, a0                  ");
    asm("move    a2, t0                  ");
    asm("L(loopw):       ");
    asm("addiu   a0, 8                   ");
    asm("sw      a1, -8(a0)");
    asm("bne     a0, a3, L(loopw)");
    asm("sw      a1, -4(a0)");
    asm("L(chkl):        ");
    asm("andi    t0, a2, 0x4             ");
    asm("beq     t0, zero, L(last8)      ");
    asm("subu    a2, t0");
    asm("sw      a1, 0(a0)               ");
    asm("addiu   a0, 4");
    asm("L(last8):       ");
    asm("blez    a2, L(exit)             ");
    asm("addu    a3, a2, a0              ");
    asm("L(lst8l):       ");
    asm("addiu   a0, 1");
    asm("bne     a0, a3, L(lst8l)");
    asm("sb      a1, -1(a0)");
    asm("L(exit):        ");
    asm("j       ra                      ");
    asm("nop");
}

今回のエラーは次のとおりです。

/tmp/ccuyfGW5.s: Assembler messages:
/tmp/ccuyfGW5.s:5131: Error: unknown opcode
/tmp/ccuyfGW5.s:5135: Error: unknown opcode
/tmp/ccuyfGW5.s:5139: Error: unknown opcode
/tmp/ccuyfGW5.s:5143: Error: unknown opcode
/tmp/ccuyfGW5.s:5147: Error: unknown opcode
/tmp/ccuyfGW5.s:5151: Error: unknown opcode
/tmp/ccuyfGW5.s:5155: Error: invalid operands for opcode
/tmp/ccuyfGW5.s:5159: Error: unknown opcode
/tmp/ccuyfGW5.s:5163: Error: invalid operands for opcode
/tmp/ccuyfGW5.s:5167: Error: unknown opcode
/tmp/ccuyfGW5.s:5171: Error: unknown opcode
/tmp/ccuyfGW5.s:5175: Error: unknown opcode
/tmp/ccuyfGW5.s:5179: Error: unknown opcode
/tmp/ccuyfGW5.s:5183: Error: unknown opcode
/tmp/ccuyfGW5.s:5187: Error: unknown opcode
/tmp/ccuyfGW5.s:5191: Error: unknown opcode
/tmp/ccuyfGW5.s:5195: Error: unknown opcode
/tmp/ccuyfGW5.s:5199: Error: unknown opcode
/tmp/ccuyfGW5.s:5203: Error: unknown opcode
/tmp/ccuyfGW5.s:5207: Error: unknown opcode
/tmp/ccuyfGW5.s:5211: Error: unknown opcode
/tmp/ccuyfGW5.s:5215: Error: unknown opcode
/tmp/ccuyfGW5.s:5219: Error: unknown opcode
/tmp/ccuyfGW5.s:5223: Error: unknown opcode
/tmp/ccuyfGW5.s:5227: Error: unknown opcode
/tmp/ccuyfGW5.s:5231: Error: unknown opcode
/tmp/ccuyfGW5.s:5235: Error: unknown opcode
/tmp/ccuyfGW5.s:5239: Error: unknown opcode
/tmp/ccuyfGW5.s:5243: Error: unknown opcode
/tmp/ccuyfGW5.s:5247: Error: unknown opcode
/tmp/ccuyfGW5.s:5251: Error: unknown opcode
/tmp/ccuyfGW5.s:5255: Error: unknown opcode
/tmp/ccuyfGW5.s:5259: Error: unknown opcode
/tmp/ccuyfGW5.s:5263: Error: unknown opcode
/tmp/ccuyfGW5.s:5267: Error: unknown opcode
/tmp/ccuyfGW5.s:5271: Error: unknown opcode
/tmp/ccuyfGW5.s:5275: Error: unknown opcode
/tmp/ccuyfGW5.s:5279: Error: unknown opcode
/tmp/ccuyfGW5.s:5283: Error: unknown opcode
/tmp/ccuyfGW5.s:5287: Error: unknown opcode
/tmp/ccuyfGW5.s:5291: Error: unknown opcode
/tmp/ccuyfGW5.s:5295: Error: unknown opcode

編集

問題は確かにスタックの破損に関連していましたが、サブルーチンから逆アセンブルされたコードを取得し、インライン化のために C 関数本体に戻す方法について誰かが答えを知っているかどうかを確認するために、ここでこの質問を許可します。

4

1 に答える 1

2

インライン MIPS アセンブラが受け入れるコードgdbも生成しません。構文を自動的に修正するツールを知らないので、アセンブラ構文を手動で修正する必要があります。また、インライン asm コードによって変更されるレジスタやメモリを指定する必要があります。これはすべて簡単な作業ではありません。objdumpgccgcc

Cソース コードがある場合、 のオプション-Sを使用するとgcc、ほぼ構文的に正しい MIPS アセンブラが生成されますが、それでも手動で編集する必要があります。

于 2013-10-29T20:43:01.013 に答える