15

OpenOCDによって制御される組み込みmcu用にgdbを使用して小さな単体テストを作成しようとしています(これにより、gdbサーバーを介してターゲットを制御できます)。

そこで、gdbのスクリプトを使用してこれを自動化したいと思います。

多かれ少なかれこれを行うgdb用のある種のスクリプトを書きたいと思います。

  1. ブレークポイントをいくつか追加します
  2. プログラムを開始します
  3. 停止したとき、どこで停止しましたか(フレーム情報を取得)
  4. 終了する。

何か案は?

Pythonのgdbスクリプトでこれを行う方法の例がいいでしょう。

ありがとうヨハン


この基本構造があり、関数start_test()が返すものに応じて、多かれ少なかれtest_failed()またはtest_success()に入るとしましょう。

void test_failed() {    
    while(1);    
}

void test_success() {    
    while(1);    
}

int main(void) {    
    int status = start_test();    

    if( status > 0 ) {    
        test_failed();    
    }    
    test_success();

    while(1);    
}

gdbでこれを手動で行うことは、非常に簡単です。

(gdb) break test_success
Breakpoint 1 at 0x20: file src/main.c, line 9.
(gdb) break test_failed
Breakpoint 2 at 0x18: file src/main.c, line 5.
(gdb) cont
Continuing.

Breakpoint 1, test_success () at src/main.c:9
9       while(1);
(gdb) frame
#0  test_success () at src/main.c:9
9       while(1);
(gdb) 

したがって、私が試した次のステップは、これらのgdbコマンドをgdb起動スクリプトに追加することでした。これは多かれ少なかれこのように見えます。

break test_success
break test_failed
target remote localhost:3333
cont 
frame

で始めます

arm-none-eabi-gdb --batch --command=commands.gdb main.elf

そして、この種の作品ですが、それはあまり良くありません。gdbがサポートしているように見える「新しくてかっこいい」Pythonスクリプトでこれを行うにはどうすればよいですか。

4

4 に答える 4

11

参考までに、最近の gdb バージョンは Python でスクリプト可能です。gdb コマンド ラインから Python コードを呼び出すことができます。これにより、まったく新しい世界が開かれます。関連するドキュメントを確認してください。コマンド ラインから次を実行します。

 dnf/yum/apt-get install gdb-doc
 info gdb extending python

テキストベースの情報ブラウザーが気に入らない場合は、(多くの?) 代替のグラフィカルブラウザーを次に示します。

yelp 'info:gdb' # , go to "Extending"

サンプルの gdb-python スクリプトを次に示します。実行中の最初の「your_program」に gdb をアタッチします。

#!/usr/bin/python

import subprocess
import string

def backquotes(cmdwords):
        output = subprocess.Popen(cmdwords, stdout=subprocess.PIPE).communicate()[0]
        return output.strip()

pid = backquotes(['pgrep', 'your_program'])

gdb.execute("attach " + str(pid))
于 2010-11-10T00:25:34.560 に答える
10

私が現在使用している縮小例:

class DebugPrintingBreakpoint(gdb.Breakpoint):
    debugging_IDs = frozenset({37, 153, 420})
    def stop(self):
        top = gdb.newest_frame()
        someVector = top.read_var('aVectorVar')
        # Access the begin() & end() pointer of std::vector in GNU Standard C++ lib
        first = someVector['_M_impl']['_M_start']
        last = someVector['_M_impl']['_M_finish']
        values = []
        while first != last:
            values.append(int(first.dereference()['intID']))
            first = first + 1
        if not set(values) & debugging_IDs:
            return False # skip: none of the items we're looking for can be found by ID in the vector on the stack
        print("Found other accompanying IDs: {}".format(values))
        return True # drop to gdb's prompt
# Ensure shared libraries are loaded already
gdb.execute("start")
# Set our breakpoint, which happens to reside in some shared lib, hence the "start" previously
DebugPrintingBreakpoint("source.cpp:42")
gdb.execute("continue")

このスクリプトは、次のように gdb のプロンプトから実行できます。

(gdb) source script.py

またはコマンドラインから:

$ gdb --command script.py ./executable.elf

詳細については、完全なGDB Python API ドキュメントを参照してください。

于 2014-08-15T09:13:00.040 に答える
3

OK、質問をしているうちに答えが見つかりました...そしてそれは本当に簡単なことでした.

「--command」と「--eval」が特定の順序で実行されることが予想される場合は、両方を同時に使用しないでください。

より予測可能な方法は、すべてを commands.gdb ファイルに入れ、--eval を無視することです。

したがって、次のようになります。

arm-none-eabi-gdb --batch --command=commands.gdb main.elf

commands.gdb は次のようになります。

break test_success
break test_failed
target remote localhost:3333
cont 
frame

しかし、代わりにpythonのようなものでこれを行う方がおそらくはるかに良いでしょう.

于 2010-10-31T08:27:49.313 に答える