2011-12-09 9 views
0

linux上で実行されている埋め込み型Cアプリケーションの関数をプログラムでモックする方法はありますか?以下の例では、実行時にsomeFuncの代わりにsomeBlahに電話するためにmainをモックしたいと思います。プログラムで関数を模倣する

#include <stdio.h> 

void someFunc(void) 
{ 
    printf("%s():%d\n",__func__,__LINE__); 
} 

void someBlah(void) 
{ 
    printf("%s():%d\n",__func__,__LINE__); 
} 

int main(void) 
{ 
    someFunc(); 
} 

プログラムはLinuxのRAMから実行されるため、テキストセグメントは変更可能である必要があります。私はGDBがブレークポイントのコード位置がトラップ命令に置き換えられているいくつかの同様のコンセプトで動作することを知っています。

+0

あなたはなぜ尋ねるのですか? –

答えて

1

あなたはいつもとマシンコードを生成することによって、例えば(mprotectへの適切な呼び出しによってテキストセグメントの一部が変更可能にし、自分自身でいくつかのコードを上書きする可能性がlibjit、GNU lightning、...または手動で)。

しかし、関数ポインタを使用する方がよりクリーンな方法です。

機能は共有ライブラリ内にある場合は、あなたもそのProcedure Linkage Tableを上書きする可能性が(アーキテクチャに依存しており、また、ABI specを参照してください - ここARMするためのものである)

+0

私はあなたのアプローチを試していませんが、それは適切です。あなたの答えを受け入れる。 – Kamath

+0

いいえ、PLTを使用できません。コードが静的にリンクされています。 – Kamath

4

もちろん、関数ポインタのテーブルを作成するだけです。それらはすべて同じインターフェイスおよび戻り値の型を持っている場合は

#define BLAH 0 
#define FOO 1 
void (*table_function[])(void) = {someBlah, someFoo}; 

、あなただけのテーブルエントリを切り替えることで、それらを切り替えることができます。あなたはJITのいくつかの種類を書いているのでない限りこれをしない:

次に、あなたが機能を交換したい場合は、ちょうどまた

table_function[BLAH] = otherBlah; 

を言う

table_function[BLAH](); 

を実行することにより、関数を呼び出しますコンパイル環境やVMでは、通常、そのような構文は必要ありません。必要な場合は、おそらくアーキテクチャの日が間違っている可能性があります。

OOデザインで経験があれば、多態的な構造をC言語で設計できます(それが意味をなさない場合は無視してください)。

+0

または仮想テーブルを実装:) –

+0

私たちのケースでは、main関数の実装を変更することはできません – Kamath

+0

私の質問はVM/OO設計とは何の関係もなく、私たちはプラットフォームユニットテストのため、実行時には模擬する必要があります。 – Kamath

0

私はこれを行っているもう一つの方法は次のとおりです。

#include <stdio.h> 
#define DEBUG 

void someFunc(void) 
{ 
#ifndef DEBUG 
    printf("%s():%d\n",__func__,__LINE__); 
#else 
    printf("%s():%d\n",__func__,__LINE__); 
#endif 
} 

int main(void) 
{ 
    someFunc(); 
} 
+0

2行目の質問: "... in run-time。" – pmod

+0

@pmod oops、それを逃した。 – Jeff

1

C.のためのいくつかのモックフレームワークがあります。

私たちはcgreenで成功しましたが、内部を変更する必要がありました。幸いにも、それは非常に小さく、比較的容易に拡張できます。良い見えますが、私は一緒に作業していない代替は、UnityCMockの組み合わせです。

埋め込みCコードの一般的なトピックについては、Test Driven Development for Embedded Cを強くお勧めします。

関連する問題