2010-04-21 21 views
1

我們有一個企業系統有很多進程(EXE,服務,DCOM服務器,COM +應用程序,ISAPI,MMC管理單元),所有這些都使用了許多COM組件。我們最近在某些客戶部署中看到了故障,但發現很難排除原因。與所有DLL進程共享一些信息

爲了追蹤這個問題,我們用錯誤發生的日誌語句擴充了整個源代碼。

爲了確定哪些日誌來自哪些進程,C++日誌記錄代碼(編譯到所有組件中)使用EXE名稱來命名日誌。這對於某些情況非常有用,但並非全部--COM +應用程序,ISAPI和MMC管理單元都具有系統EXE名稱,並且日誌以交錯方式結束。

我看到了this post about shared data sections這可能有幫助,但我不明白的是誰決定共享部分中的內容。有什麼方法可以保證在別人讀取代碼之前,將一段代碼寫入共享段?

還是有更好的解決方案來解決這個問題嗎?

回答

1

要同步寫入共享部分的多個進程,您需要某種IPC,例如, Windows事件,互斥體,套接字。每個模塊都調用CreateMutex並傳遞所有模塊共享的固定名稱。模塊然後調用WaitForSingleObject等待並聲明互斥鎖 - 當其中一個獲取它時,它可以在每個其他模塊等待時讀取/寫入共享部分。當它完成後,它會調用ReleaseMutex讓另一個模塊繼續運行。

說完所有我個人會堅持日誌文件。我猜你的問題是,對於DLL,你是基於父進程EXE名稱的日誌文件名而不是DLL自己的名字?

您可以通過存儲您在DllMain中傳遞的DLL實例句柄,然後將其與GetModuleFileName一起使用來獲取DLL自己的名稱。注意這適用於EXE以及如果您將實例句柄保留爲NULL。

// global variable to store DLL handle (or it stays NULL if this is an EXE) 
HINSTANCE hDllHandle=NULL; 

BOOLEAN WINAPI DllMain(IN HINSTANCE hInstance, 
    IN DWORD  nReason, 
    IN LPVOID Reserved) 
{ 
    hDllHandle = hInstance; 
    return TRUE; 

} 

<snip> 

void Log(LPSTR lpszMsg) 
{ 
    WCHAR szMyModuleName[MAX_PATH]={0}; 

    // if hDllHandle is still NULL (e.g. this is an EXE) it returns the process name 
    // if non-NULL, it returns our DLL name 
    GetModuleFileName(hDllHandle, szMyModuleName, MAX_PATH); 

    fprintf(LOGFILE, "[%s] %s\n", szMyModuleName, lpszMsg); 

    ....<snip>.... 
} 
+0

感謝您的信息。是的,這是我們陷入困境的地方。很難預測EXE的名稱,因爲DLL可以由任何ActiveX主機託管,雖然在這些情況下通常有一個「主」DLL ..這導致了我的共享數據部分的想法。我想我需要像'GetMainModuleFileName()'這將決定'主'DLL或使用EXE名稱,如果沒有一個..任何想法? – JBRWilkinson 2010-05-11 00:24:40

+0

嗨 - 我上面發佈的代碼肯定會給你 - 如果它鏈接到一個運行在宿主進程中的DLL,它會告訴你你的DLL的名字,否則它會告訴你你的.exe的名字。道歉,如果我錯過了什麼。 – snowcrash09 2010-05-11 08:53:39

+0

所以'主'DLL將有一個DllMain設置hDllHandle ..和其他DLL不。其他DLL的知道如何引用完全相同的hDllHandle變量? – JBRWilkinson 2010-05-11 19:22:53

0

DLL中的共享段的使用(帶有RWS標誌的段)並不能真正解決您的主要問題。如果您需要共享內存以便在進程之間進行快速通信,則可以使用內存映射文件(例如,參見http://msdn.microsoft.com/en-us/library/ms810613.aspx),並可更好地控制共享內存的創建和使用。

要了解有關加載DLL的進程的更多信息,可以另外記錄應用程序的命令行(例如GetCommandLine()函數)。您將看到類似於「C:\ Windows \ system32 \ mmc.exe C:\ Windows \ system32 \ services.msc」或「C:\ Windows \ system32 \ mmc.exe C:\ Windows \ system32 \ azman.msc」爲MMC snapins。

要查看有關調用過程的更多信息,您可以StackWalk64(請參閱http://msdn.microsoft.com/en-us/library/ms680650(VS.85).aspx)函數。有關很好的代碼示例,請參閱http://stackwalker.codeplex.com/http://www.codeproject.com/KB/threads/StackWalker.aspx