2011-12-09 104 views
0

有沒有什麼辦法以編程方式模擬Linux上運行的嵌入式c應用程序的函數。在下面的例子中,我想模擬main在運行時調用someBlah而不是someFunc以編程方式模擬函數

#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閃電,...或手動)。

但是使用函數指針是一個更乾淨的方法。

如果函數是一個共享庫中,你甚至可以覆蓋其Procedure Linkage Table(另見ABI spec,這取決於建築 - 這裏是一個ARM

+0

我還沒有嘗試你的方法,但看起來合適。所以接受你的答案。 – Kamath

+0

好吧不,我不能使用PLT我的代碼是靜態鏈接的。 – Kamath

4

當然,只需製作一個函數指針表。

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

如果它們都具有相同的接口和返回類型,則可以通過切換表條目來切換它們。

然後你通過執行

table_function[BLAH](); 

如果你想換一個函數調用一個函數,只說

table_function[BLAH] = otherBlah; 

另外:除非你正在寫某種JIT的不這樣做編譯環境或虛擬機,通常你不需要這樣的結構,如果你需要它們,你可能會遇到糟糕的架構日。

雖然如果您有面向對象設計的經驗,那麼您可以用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

注意問題的第二行:「...在運行時」。 – pmod

+0

@pmod哎呀,錯過了。 – Jeff

1

有對於C.一些嘲諷框架

在工作中,我們在cgreen上取得了一些成功,但是我們必須對其內部進行更改。幸運的是,它非常小,並且相對容易擴展。替代方案看起來不錯,但我沒有使用,是UnityCMock的組合。

關於單元測試嵌入式C代碼的一般話題,我強烈推薦Test Driven Development for Embedded C

相關問題