ORTI"風" gdb拡張モジュール
現在のバージョンは0.9.1(beta release)です。gdb-5.0に対応しています (正確には、gdb_stdoutだけ5.0依存)。評価実装として基本部分は一通り完成しています。エラー処理等に目をつぶれば十分実用レベルで動作します。
モジュールは次の仕様に従おうと努力しました。
- OSEK RunTime Interface(ORTI) Version: 2.0 Draft(c-h)
- OSEK RunTime Interface(ORTI) Version: 2.1 release candidate 1 (March 1st, 2001)
- OSEK RunTime Interface(ORTI) Version: 2.1 release candidate 2 (May 29th, 2001)
- Proposal of next OSEK/VDX Debug WG Meeting (May 3rd, 2001)
ORTIを越える拡張部分
このモジュールは使い勝手の向上等を目指し、いくつか本家ORTIを超える拡張機能を搭載しています。
- 条件式型 "CONDITION"の導入
- TEMPLATE定義とTEMPLATE宣言の導入による、似たような記述の簡略化
- ビットフラグ型 "FLAG" の導入
- 勘違い文字列型 "CSTRING"の導入
また、インチキ実装により、次のエセ拡張機能を持っています。
- gdbが解釈できればどんな"式(expression)"でも入力可能
#ターゲット上の関数呼び出しまでできる
現在のモジュールにかかってる制限
現在のORTI"風"モジュールは、個人の趣味で作った紛い物です。本物のと違っていろんな制限がついています。
- いぢわるしないでください
- "TOTRACE"は
無いものと考えてくださいサポート外です
まだ世間の荒波に揉まれていないピュアなモジュールなので、いぢわるしないでください。「多分、このフィールドにこんなの埋めたらcoreとか吐くだろうな」と思ったら、決して入れないでください。きっと吐きます。
gdbでは不可能です。
バージョンの変遷
思い切って1.0にしてしまいたいけど、仕様自体が固まってないので、小数の世界に逃げています.
Ver 0.9.1b
- ENUM-LINKをサポートしました (Release candidate 2準拠)
- info objectコマンドにオブジェクトトラック機能をつけました (oオプション)
- 内部構造の一部を最適化しました
Ver 0.9b
- Release candidate 1にあわせました
- TEMPLATE構文が追加されました
- CONDITION, REFERENCE, IDENTIFIER, FLAG属性が追加されました
ORTI"風"拡張モジュールを導入すると、次のコマンドが追加されます。
- orti file - ORTI"風"ファイルの操作
- info orti - ORTI"風"拡張モジュールの関連情報の表示
- info object - オブジェクト情報の表示
- orti debug - 内部デバッグ用コマンド (使うな危険)
- orti condition - 条件式の付加 (独自拡張)
ORTI"風"ファイルに関連する操作を行います。
| コマンド | 効果 |
|---|---|
| orti file | 現在使用しているORTIファイルの名前を表示する |
| orti file 'ファイル名' | ファイル名で指定されたORTI"風"ファイルを読み込む |
具体的に動かすとこんな感じ
|
(gdb) orti file No description file loaded (gdb) orti file sample.odf Now, GDB is loading something like a ORTI object description file... Version section was loaded successfully. Declaration section was loaded successfully. Information section was loaded successfully. File loading was finished successfully. (gdb) orti file Current description file is 'sample.odf'. |
info ortiコマンドでは、このモジュールに関連したいろんな内部情報を取得できます。
| コマンド | 効果 |
|---|---|
| info orti version | 現在のバージョン等を表示する |
| info orti class '型名' | 定義済みの型の型名および説明を表示する C : CTYPE, E : ENUM, S : STRING, = : CONDITION F : FLAG, I : IDENTIFER, R : REFERENCE, M : MASK |
具体的に使うとこんな感じ (定義ファイルはロード済み)
| (gdb) inf orti version | |
| Module version | : 0.1 (alpha) |
| Kernel OIL | : 2.1 |
| OS semantics | : Something like ORTI |
| Semantics version | : 2.0 |
| (gdb) inf orti class TASK | |
| Property of class 'TASK' (タスク情報) | |
| EXINF | : [C] タスクに渡す拡張情報(タスク番号と出力文字列) |
| PRIORITY | : [C] 優先度 |
| STACK | : [C] スタック開始番地 |
| STATUS | : [E] 現在の状態 |
バージョンに関しては、バージョン判定してないのでKOILが3.0だろうがOS semanticsがORTIでなかろうが、特に何の"関係なく"動きます。ただ、文法上必須なのでなくすことはできません。型情報表示の際には、gdbの補完機能を利用して型名を入力できます。
型名を"クラス"と呼んでるのは私の独断によるものです (attributeと言う名前が付く場所が2つも3つあるのでうざい)。
info objectコマンドでは、実際にオブジェクト情報を取得して、画面に表示してくれます。このモジュールの中核となる機能です。
| コマンド |
| info object[/'書式指定子'] 'オブジェクト名' |
| 効果 |
| 書式指定子に基づいて、オブジェクト名で指定されたオブジェクトの情報を表示する。 |
書式指定子に利用できる文字は次のとおり
| 文字 | 効果 |
|---|---|
| e | オブジェクト情報が構造体であった場合でも、構造体の中身を展開します。 |
| c | 1バイト整数を文字として表示します。たとえば、値が65であった場合は画面に'A'と表示されます。 |
| D | 型名の代わりに型の説明を利用します。 |
| x | 整数を16進数で表示します。 |
| d | 整数を10進数で表示します。デフォルトです。 |
| t | 下の "o"と"p"をあわせたものです。 |
| p | オブジェクト情報がポインタであった場合、その先が示す内容も一回だけ表示します。 |
| o | オブジェクト情報がORTIオブジェクトであった場合、その中身も再帰的に調べます。 |
| h | オブジェクト情報がORTIオブジェクトだった場合、表示の際に "要素名 ="をつけて表示します。デフォルトです。 |
| ! | 直前に指定した指定を否定します (e!なら構造体の中身を展開しない)。 |
具体的に使うとこんな感じ (定義ファイルはロード済み)
| (gdb) info object task1 | |
| Status of object 'task1' (TASK) | |
| [EXINF] | : <structure: taskparameter> |
| [PRIORITY] | : 14 |
| [STACK] | : 0xc0020018 |
| [STATUS] | : Running |
| (gdb) info object/ext task1[EXINF] | |
| Status of object 'task1' (TASK) | |
| [EXINF] | : { 1, 0xc0012f8c <"Task 1"> } |
| (gdb) info object/xD task1[STACK] | |
| Status of object 'task1' (TASK) | |
| [スタック開始番地] | : 0xc0020018 |
オブジェクト名の入力の際には、gdbの補完機能が使えたりします。またオブジェクト名を打たないと、オブジェクトの一覧が見れたりもします。見栄えをよくするために出力結果のコロンの位置をあわせる処理もしています。
orti conditionコマンドでは、gdbのconditionコマンドを使用して、ブレークポイントなどに条件式を付加することができます。この機能により、オブジェクト名やクラス名を使用して、条件ブレークを設定することなどができるようになります。
注意 : 本機能は独自拡張機能であり、ORTIの仕様の範囲を超えています。
| コマンド |
| orti condition 'gdbのブレークID番号など' 'オブジェクト名またはクラス名' '属性名' |
| 効果 |
| オブジェクトの属性名で指定された条件式を、gdbのブレーク番号で指定したブレークに設定します。クラスにデフォルト条件式が定義されている場合でデフォルト条件式を利用する場合、オブジェクト名の代わりにクラス名が使用できます。 |
また、オブジェクト記述(KOIL)には次の文法が追加または拡張されています (斜体以外はマニュアルを参照してください)。
| <attribute_type> | = <c_type>|<enum_type>|<string_type>|<condition_type>. |
| <condition_type> | = "CONDITION" [<default_condition>]. |
| <default_condition> | = <string*>. |
具体的な記述はこのようになります
|
VERSION { "KOIL" = "2.1"; "OSSEMANTICS" = "Something like ORTI","2.0"; }; IMPLEMENTATION TOPPERSJSP {
TASK {
};
CONDITION isrunning, "タスクが実行中であるときの条件";
}
TASK task1 {
isrunning = "_kernel_runtsk == &_kernel_tcb_table[0]";
}; |
具体的に使うとこんな感じ (定義ファイルはロード済み)
| (gdb) orti condition 1 task1 isrunning (gdb) |
CONDITIONで定義された方は、前述の"info obj (オブジェクト情報の表示)"でも利用できます。このときは、結果は"True"または"False"と表示されます。また、"!isrunning"のように属性名に!をつけて指定することで、真偽を反転させることもできます。
TEMPLATE構文は、C++のテンプレートみたいなもので、同じような宣言を繰り返し行うのは面倒だという部分の簡略化に一役買います。
注意 : 本機能は独自拡張機能であり、ORTIの仕様の範囲を超えています。
オブジェクト記述(KOIL)には次の文法が追加または拡張されています (太文字以外はマニュアルを参照してください)。
| <file> | = <version_section> <declaration_section> <template_section> <information_section> |
| <template_section> | = "TEMPLATE" "{" <template_decl>"}" ";" |
| <template_decl> | = <object_type> <template_type> "(" <parameter_decl> ")" "{" { <attribute_decl> } "}" ";" |
| <template_type> | = <identifier*> |
| <parameter_decl> | = <identifer*> [ "," <parameter_decl> ] |
| <information_section> | = { <object_def> | <template_def> } |
| <template_def> | = <template_type> <object_name> "(" <parameter_def> ")" ";" |
| <parameter_def> | = <string*> [ "," <parameter_def> ] |
この拡張により、TEMPLATE宣言部にはパラメータ指定子が利用できます。パラメータ指定子は"$1"や"$6"のように、"$"に連続する1桁の数字で示されます。このパラメータ指定子で指定した部分が、TEMPLATE定義で指定したパラメータに置換されます。引数を書いておいて"$"で引くのはどうしてかという疑問は無視します。ちなみに"$"自身は"$$"と記述します。具体的な使い方に関してはサンプルを見てください。
整数のビットが立つ/立たないで状態を識別しているような変数を扱いやすくします。ORTIのENUMの拡張だと考えてください (「32個のフラグを持つ変数をORTIのENUMで表現したら、42億エントリも書かなきゃならんぞ どうにかせいや ごるぁ」という問題を解決します)。
注意 : 本機能は独自拡張機能であり、ORTIの仕様の範囲を超えています。
また、オブジェクト記述(KOIL)には次の文法が追加または拡張されています (太字以外はマニュアルを参照してください)。
| <attribute_type> | = <c_type>|<enum_type>|<string_type>|<flag_type>. |
| <flag_type> | = "FLAG" "[" <flag_element> [ { "," <flag_element> } ] "]". |
| <flag_element> | = <hi_desc>[ "," <lo_desc>] "=" (<bit_position> | "DEFAULT"). |
| <hi_desc> | = <string*>. |
| <lo_desc> | = <string*>. |
| <bit_position> | = <constants>. |
具体的な記述はこのようになります
|
VERSION { "KOIL" = "2.1"; "OSSEMANTICS" = "Something like ORTI","2.0"; } IMPLEMENTATION TOPPERSJSP {
CYCLIC {
};
FLAG [
}, "周期ハンドラ";
"アセンブリ言語インタフェース","高級言語インタフェース" = 0,
] cyclic_attribute, "属性";
"いきなり起動" = 1, "起動位相保存" = 2 CYCLIC cyc1 {
cyclic_attribute = "_kernel_cyc_table[0].cycinib->cycatr";
}; |
ビット0には、「アセンブリ言語インタフェース」「高級言語インタフェース」の2種類の説明が記述されていますが、前者はビットが立っていたとき、後者はビットが寝ていたときに表示される説明です。ちなみに、ビットが寝たときの説明をつけると、デフォルトの説明("..." = DEFAULT)を指定しても表示されません。また、"..."=2と書いたときは、2であったときでもなく、2でANDを取った結果が非0であったときでもなく、2^2でANDを取ったときの結果が非0であったときに表示されます。32以上の値を打ちそうになったときには、ホントに勘違いしてないかどうかを良く確かめてみてください。
あるオブジェクトがあるオブジェクトを参照するような場合の実装を簡単にします (セマフォ獲得待ちタスクが知りたいとかね)。「全部で100個のインスタンスがあるタスクを参照するクラス定義が10個あったら、中身が100行の同じENUMを10個も書かなきゃならんぞ どうにかせいや ごるぁ」という問題を解決します。TEMPLATEとこの参照は、ホントにオブジェクトごとに依存する記述部をできる限り少なくするためのものです。サンプルを見ると判りますが、これらの型の導入により、mITRON4.0コンフィギュレータがこのファイルを生成する際にオブジェクトごとに出力しなければならない行は、最後に出てくる"TEMPLATE ..."という部分だけになります。
注意 : 本機能は独自拡張機能であり、ORTIの仕様の範囲を超えています。
オブジェクト記述(KOIL)には次の文法が追加または拡張されています (太字以外はマニュアルを参照してください)。
| <attribute_type> | = <c_type> | <enum_type> | <string_type> | <identifier_type> | <reference_type>. |
| <identifier_type> | = "IDENTIFIER" [ <ctype_decl> ] . |
| <reference_type> | = "REFERENCE" <object_name> [ "[" <attribute_name> "]" ]. |
使い方
まず、参照先となるオブジェクトの宣言部(IMPLEMENTATIONの中にあるやつ)にIDENTIFIER型の属性を追加します。そして、それぞれのオブジェクトの定義部には、絶対重ならないような値を持つ何かを指定してあげます (重なったらABC順で先のヤツになるだろうなぁ)。
で、参照元となるオブジェクトの宣言部には、REFERENCE 型名 [属性名]を突っ込みます。例えば、参照先がTASK型でidという名前で属性を作ったのなら、REFERENCE TASK[id]とします。参照元の属性名が参照先の属性名と同じなら(この場合はid)、[id]は省略してもかまいません。
サンプルでは、カーネル型(KERNEL)が今動いているタスク型(TASK)を特定するのに、この参照を利用しています。
材料
- GNU Debugger - gdb 5.0 ソースコード
- GNU C Compiler - gcc 2.95.2
- GNU make
- bison 1.25
- flex 2.5.4a
- perl
これらのツールはRing ServerやRedHat inc.などで取得できます。gdb以外のツールはそのまま付属のドキュメントに従ってささっとインストールしてください。
gdbの作成
まずgdb-5.0を展開します。
|
~% tar zxvf gdb-5.0.tar.gz (省略) % |
configureを実行して、Makefileを作らせます。必要に応じて--targetなどのオプションを指定してください。ここでは日立Super-H用のgdbを生成します。
|
~% cd gdb-5.0 ~/gdb-5.0% ./configure --target=sh-hitachi-elf (省略) ~/gdb-5.0% |
ここで、展開したgdbのgdbディレクトリの下に、配布キットを展開します。
|
~/gdb-5.0% cd gdb ~/gdb-5.0/gdb% tar zxvf ~/orti-ext.tar.gz (省略) ~/gdb-5.0/gdb% |
配布キットの中には、gdbのMakefileを修正するためのMakefileが入っています。これを実行して、Makefileを修正します。
|
~/gdb-5.0/gdb% cd orti-ext ~/gdb-5.0/gdb/orti-ext% make (省略) ~/gdb-5.0/gdb/orti-ext% |
後は普通に全体をmakeします。
|
~/gdb-5.0/gdb/orti-ext% cd ~/gdb-5.0 ~/gdb-5.0% make all (省略) % |
これで完了です。できたgdbを実行し、help ortiでコマンドヘルプメッセージが表示されれば正常にインストールできています。
このORTI "風" gdb拡張モジュールは、現在本研究室で公開しているTOPPERS/JSPカーネル 1.1(patchlevel=1)以上に対応しています (ITRONオブジェクトの記述可能性を評価するのが作った目的)。
まず、カーネルソースを展開します。そして、コンフィギュレータのあるディレクトリ(jsp/cfg)に、「モジュールはこちら」でダウンロードした記述ファイル(toppers_decl.odl)をコピーします。
この後、対象となるターゲットのMakefile(e.g. jsp/V850/Makefile)を変更します。大体100行ちょっと後くらいに、次のような記述があります。
|
# # カーネルのコンフィギュレーションファイルの生成 # kernel_cfg.c: $(UTASK_CFG) $(CPP) $(INCLUDES) $(CDEFS) $(UTASK_CFG) | ../cfg/cfg
|
この行の直前に「以下は編集しないこと」と書いてありますが、気にしないで修正します。太文字部分が変更点です。
|
# # カーネルのコンフィギュレーションファイルの生成 # kernel_cfg.c: $(UTASK_CFG) $(CPP) $(INCLUDES) $(CDEFS) $(UTASK_CFG) | ../cfg/cfg --odl
cat ../cfg/toppers_decl.odl toppers_info.odl > $(UTASK).odl |
これでmake dependすると、sample1.odlとかいうファイルを吐きます。ファイル名はそのときコンパイルしたソースの名前と同じになるようになっています。これをORTI "風"に拡張したgdbに読ませることで、JSPカーネルのデバッグが行えるようになります。
