GDBが遅い

GDBが遅い

CTRL私はARMアセンブリコードを実行するための素晴らしいデモをしています(+を押すまでC)、1秒ごとにコードを無限に実行するためにGDBが必要です。誰にも解決策はありますか?

訪問者が私のブースを訪れるとき、あなたはキーボードの前に立ってプログラムを実行したくありません。

答え1

GdbのCLIはwhileループをサポートしています。組み込みコマンドはありませんが、sleepシェルを呼び出してプログラムを実行しsleepたり、gdbの組み込みPythonインタプリタ(利用可能な場合)を使用したりできます。 Control-Cで中断できます。

方法1:

(gdb)そして(1)
 >ステップ
 >シェル睡眠1
 >終わり

方法2:

(gdb)Pythonのインポート時間
(gdb)そして(1)
 >ステップ
 >Python time.sleep(1)
 >終わり

方法3(マクロ定義):

(gdb)定義が遅く実行されます。
「runslowly」を定義するコマンドを入力します。
「END」行で終わります。
>Pythonのインポート時間
>そして(1)
 >ステップ
 >Python time.sleep(1)
 >終わり
>終わり
(gdb)ファイルが遅く実行されます。
「runslowly」タイプのドキュメントです。
「END」行で終わります。
>1秒ごとに1行ずつ歩く。
>終わり

(gdb)ゆっくり走る

答え2

expectこれは自動化できます。

#!/usr/bin/env expect
spawn -noecho gdb -q ls
expect -ex {(gdb)}
send -- "break main\r"
expect -ex {(gdb)}
send -- "run\r"
while {1} {
    expect -ex {(gdb)}
    send -- "s\r"
    sleep 1
}

あるいは、プログラムが使い果たされる危険性がある場合はs繰り返すことができますが、gdbもう少し複雑です。

#!/usr/bin/env expect

while {1} {
    spawn -noecho gdb -q ls
    expect -ex {(gdb)}
    send -- "break main\r"
    expect -ex {(gdb)}
    send -- "run\r"
    expect {
        -ex {The program is not being run} {}
        eof {}
        -ex {(gdb)} {
            send -- "s\r"
            sleep 1
            exp_continue
        }
    }
}

答え3

コマンドでシェルパイプを使用できるというアイデアは次のとおりです。

while :; do echo step; sleep 1; done | gdb arm-program

gdb はパイプからコマンドを読み込みます。無限ループで毎秒「ステップ」コマンドを表示します。

いくつかのブレークポイントを設定してプログラムを実行できます。

(echo br 1; echo run; while :; do echo step; sleep 1; done ) | gdb arm-program

答え4

現在許可されている回答はいつも step、起動するとブレークポイント、シグナル、さらにはプログラムの終了まで「スキップ」します(最後に、gdb内部の中断が発生する前に「プログラムは実行されません」というエラーが発生します)while
別の原因として、GDBが「full」を出力すると、ページングがオンになっていると(デフォルト)停止します。

この問題はPython APIを使用してうまく処理できます。

  • ユーザコマンド定義(自動ステップ実行速度を指定する追加パラメータを含む)
  • オプション:デフォルトのパラメータ定義(単純化のためにここでは固定値に置き換えられます)
  • Pythonでwhileループを実行し、CTRL-Cの「期待される」キーボード割り込みを処理します。
  • stop停止理由を確認してステップタイプを保存するには、イベントハンドラを登録してください。
  • 「単純ではない」停止(中断点/監視点/信号/...)を停止するようにwhileループを調整します。

次のコードをgdb-auto-step.pyに配置して、source gdb-auto-step.py必要に応じて有効にすることができます(または常に使用できるように.gdbinitファイルに含めます)。

import gdb
import time

class CmdAutoStep (gdb.Command):
    """Auto-Step through the code until something happens or manually interrupted.
An argument says how fast auto stepping is done (1-19, default 5)."""
    def __init__(self):
        print('Registering command auto-step')
        super(CmdAutoStep, self).__init__("auto-step", gdb.COMMAND_RUNNING)
        gdb.events.stop.connect(stop_handler_auto_step)

    def invoke(self, argument, from_tty):

        try:
            frame = gdb.newest_frame()
        except gdb.error:
            raise gdb.GdbError("The program is not being run.")

        number = 5 # optional: use a parameter for the default
        if argument:
            if not argument.isdigit():
                raise gdb.GdbError("argument must be a digit, not " + argument)
            number = int(argument)
            if number == 0 or number > 19:
                raise gdb.GdbError("argument must be a digit between 1 and 19")

        sleep_time = 3.0 / (number * 1.4)

        global last_stop_was_simple
        last_stop_was_simple = True

        pagination = gdb.execute("show pagination", False, True).find("on")
        if pagination:
            gdb.execute("set pagination off", False, False)
        
        try:
            while (last_stop_was_simple):
                gdb.execute ("step")
                time.sleep(sleep_time)
        except KeyboardInterrupt as ki:
            if pagination:
                gdb.execute("set pagination on", False, False)
        except gdb.GdbError as user_error:
            if pagination:
                gdb.execute("set pagination on", False, False)
            # pass user errors unchanged
            raise user_error
        except:
            if pagination:
                gdb.execute("set pagination on", False, False)
            traceback.print_exc()

def stop_handler_auto_step(event):
    # check the type of stop, the following is the common one after step/next,
    # a more complex one would be a subclass (for example breakpoint or signal)
    global last_stop_was_simple
    last_stop_was_simple = type(event) is gdb.StopEvent

CmdAutoStep()

バラよりhttps://stackoverflow.com/a/67470615/5027456速度パラメータauto-nextauto-step改善されたエラー処理など、より完全な(更新された)コードを取得するには

関連情報