質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2326閲覧

【Pythonでgdb】オブジェクトのアドレスを保持している `gdb.Value` からアドレス値 **だけ** を取得したい

IkazoIchikawa

総合スコア38

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/09/01 13:05

知りたい事

c言語で作成 -> gcc でコンパイル&ビルドしたプログラムを gdb でデバッグしています。
gdb を python で制御する機能(※1)をつかって、
オブジェクトのアドレス値をしたいです。
しかし、アドレスを保持している gdb.Value型 のオブジェクトから、
アドレス値を Python の int 型で取得する方法がわからず、
教えてほしいです。

やってみたこと

例えば、以下の c言語プログラム

c

1volatile int gint_val0 = (-1); 2 3int main(int argc, char *args[]){ 4 return 1; 5}

これを、 以下のように、
gcc でコンパイル & ビルド -> gdb に食わせてから、
gdb 内の python を起動して、 gint_val0 のアドレスを取得します。

gdb

1PS C:\Users**\Desktop\github\gdb-py> gcc example.c -o example.exe -g -O0 2PS C:\Users***\Desktop\github\gdb-py> gdb example.exe 3GNU gdb (GDB) (Cygwin 8.1.1-1) 8.1.1 4Copyright (C) 2018 Free Software Foundation, Inc. 5License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 6This is free software: you are free to change and redistribute it. 7There is NO WARRANTY, to the extent permitted by law. Type "show copying" 8and "show warranty" for details. 9This GDB was configured as "x86_64-pc-cygwin". 10Type "show configuration" for configuration details. 11For bug reporting instructions, please see: 12<http://www.gnu.org/software/gdb/bugs/>. 13Find the GDB manual and other documentation resources online at: 14<http://www.gnu.org/software/gdb/documentation/>. 15For help, type "help". 16Type "apropos word" to search for commands related to "word"... 17Reading symbols from example.exe...done. 18(gdb) break main 19Breakpoint 1 at 0x100401094: file example.c, line 4. 20(gdb) run 21Starting program: /cygdrive/c/Users/***/Desktop/github/gdb-py/example.exe 22[New Thread 15508.0x3530] 23[New Thread 15508.0x4558] 24[New Thread 15508.0x27d4] 25[New Thread 15508.0x33f4] 26 27Thread 1 "example" hit Breakpoint 1, main (argc=1, args=0xffffcc20) at example.c:4 284 return 1; 29(gdb) pi # `gdb` 内の Python インタラクティブシェルを起動 30>>> gdbval_gint_val0 = gdb.lookup_symbol("gint_val0")[0].value() # ( 1) `gint_val0` を `gdb.Vlue` 型で取得 31>>> print(int(gdbval_gint_val0)) # ( 2) `gdb.Vlue` -> `int` 型に cast してから `print()`してみる 32-1 # -> `gint_val0` に代入した `-1` が Python の int に cast できている 33>>> gdbval_gint_val0_adr = gdbval_gint_val0.address # ( 3) `gint_val0` のアドレス を `gdb.Value` 型として取得 34>>> print(int(gdbval_gint_val0_adr)) # ( 4) アドレスを `gdb.Vlue` -> `int` 型に cast してから `print()`してみる 35Traceback (most recent call last): # -> アドレス値 -> `int` 型に cast された値が print されることを期待したけど、 36 File "<stdin>", line 1, in <module> # Exception になってしまう 37gdb.error: Cannot convert value to int. 38>>> print(gdbval_gint_val0_adr) # ( 5) cast せずに `print()` してみる 390x100402010 <gint_val0> # -> アドレス値を表示できたけど `<変数名>` が付加されてしまう 40>>> print(str(gdbval_gint_val0_adr)) # ( 6) `string` に cast してから `print()` してみる 410x100402010 <gint_val0> # -> cast しないで `print()` した場合と同じ結果。 42>>>

上記中、 (3) の手順で gdb.Value.address から得られるオブジェクトは、
※2 にあるように、gdb.Value 型なので、 Python の int 型に cast できると思ったのですが、
結果の (4) で Exception になってしまいます。

試しに、 (5)(6) のように、 直接 print() したり Python の string 型に cast すれば、
Exception は発生せずに string 型として取得できるのは分かりましたが、
以下の問題があります。

  • (1of2)

表示されているように、 <変数名> が付加されてしまいます。
取得した string 値を文字列操作すれば不要な部分は 取り除けるとは思いますが、
上記の様に print() できているということは、 gdb.Value は 0x???? の値がいくつなのかはわかっているはずです。
Python の string 型に cast した後に、 わざわざ文字列操作してやっと 0x??? を取得するのは、スマートではないと思うんです。

  • (2of2)

取得できる型は string 型です。
メモリアドレスは数値型なので、 int 型で取得したい場合は、
(1of2)の問題を、文字列操作で 0x??? の形になるように操作してから、
さらに 16進数文字列 -> int 型変換が必要です。
(大して難しい事ではないと思いますが、やらなくて済む方法があるならその方法を使いたいです)

オブジェクトのアドレスを保持している gdb.Value からアドレス値 だけ を取得する方法はあるのでしょうか?

使用環境

使用している環境は以下のとおりです

OS -> Windows10
gcc ver -> 7.4.0
gdb ver -> 8.1.1
python ver -> 3.7.2

出典

※1
23.2 Extending GDB using Python

※2
23.2.2.3 Values From Inferior

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

以下で解決しました

>>> hex(int(gdbval_gint_val0.address.cast(gdb.lookup_type("unsigned long long")))) '0x100402010'

gdb.Value の .cast() メソッドがキモのようです

投稿2019/09/03 09:33

IkazoIchikawa

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

CPythonの実装ではid関数を用いてオブジェクトのアドレスを取得できます。これでいけませんか?

組み込み関数 — Python 3.7.4 ドキュメント | id(object)

投稿2019/09/01 13:55

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

IkazoIchikawa

2019/09/02 11:10

トライしてみましたが、期待する値は得られませんでした、、、 ``` >>> print(gdbval_gint_val0_adr) 0x100402010 <gint_val0> >>> print(id(gdbval_gint_val0_adr)) 7696578926384 ``` 教えていただいた `id()` は、この例でいうところの、 `gdbval_gint_val0_adr` が格納する gdb.Value オブジェクト が配置されたアドレスを返すもののようです。 説明不足だったかもしれません。 ほしい値は、 `gint_val0` が配置されたアドレス値 `0x100402010` がほしいんです、、 それとも、上記のような使い方が間違っていますか??
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問