2017-08-10 66 views
0

我創建了一個Windows可執行文件,用作某些嵌入式設備的模擬器(所有業務邏輯與原始設備完全相同,只有硬件相關的東西被刪除)。重新啓動Windows進程inplace保存進程ID和句柄

這種模擬需要不時地,並在「正常」使用情況下,它類似的東西復位:

//some global environment 
... 

int main(int argc, char* argv[]) 
{ 
    __debugbreak(); 

    //... do some stuff 

    //if(restart needed){ 
     printf("before _execv"); 
     _execv(argv[0], argv); //"reset" simulated device 
    //} 

    //... do some other testing stuff 
    return 0; 
} 

注:上面的代碼只是說明主要思想,在實際應用中是execv電話實際上位於HW_Reset()存根,這是從原始代碼中的多個地方調用。

問題_execv在Windows上並不完全表現爲execv在Linux上: 當我調試在Visual Studio此應用程序的_execv不更換「重新啓動」圖像當前的進程映像。相反,它只是創建一個具有新ID的新進程,並終止當前進程,從而將其從Visual Studio中分離出來,以便保留所有需要重新附加到新進程的斷點(在單個調試會話中有幾十次重新啓動)。

目前我使用__debugbreak()作爲解決方法。 其他選項是通過重新初始化全局環境並使用setjmp/longjmp的某種組合來重置模擬 - 但是全局環境和相應的初始值設定項通過原始文件的臨時數據傳播,並且它們大多數是靜態的,因此無法處理這種重置手動(我也不允許編輯原始文件)。

所以,問題是:在那裏,導致當前進程通過在重置所有的全局(靜態)變量,如是否有可能重新加載相同的重新啓動「就地」某些Windows API /通用的解決方法在同一地址空間內處理圖像,保留外部可觀察的進程ID,進程句柄以及與Visual Studio調試器的連接?

+2

沒有,什麼都沒有,甚至靠近窗戶在這種情況下 – RbMm

回答

0

恐怕簡單的答案是Windows上沒有這樣的功能。

0

Windows不支持您要求的內容。你將不得不調整你main()代碼在一個循環中運行,而不是,如:

//some global environment 
... 

int main(int argc, char* argv[]) 
{ 
    __debugbreak(); 

    do 
    { 
     //... (re)initialize simulated device 
     //... do some stuff 
    } 
    while (restart needed); 

    //... do some other testing stuff 
    return 0; 
} 
+0

不存在「(重新)初始化模擬裝置」的操作都必須手工完成,包括(重新)初始化那些「數千個原始文件」中的靜態數據。 –

+0

@ Chajnik-U:最好擺脫全局和靜態,將它們包裝在對象中,然後重新初始化可以簡單地銷燬舊對象並創建新對象。 –