2011-07-12 64 views
2

我試圖在一個線程中運行我的程序的一部分,並得到一個不尋常的結果。線程提前終止代碼255

我已經更新了這個問題的結果changes suggested by Remus,但由於我仍然收到錯誤,我覺得這個問題仍然存在。

我已經實現了一個DLL中的功能,以配合供應商軟件。一切工作,直到我試圖在此DLL中創建一個線程。

這裏是DLL的相關章節:

extern "C" { 
__declspec(dllexport) void __cdecl ccEntryOnEvent(WORD event); 
} 

定義函數的供應商的軟件調用,則:

using namespace std; 

HANDLE LEETT_Thread = NULL; 
static bool run_LEETT = true; 
unsigned threadID; 
void *lpParam; 

int RunLEETTThread (void) { 
    LEETT_Thread = (HANDLE)_beginthreadex(NULL, 0, LEETT_Main, lpParam, 0 , &threadID); 
    //LEETT_Thread = CreateThread (NULL, 0, LEETT_Main, lpParam, 0 , NULL); 

    if (LEETT_Thread == NULL) 
     ErrorExit (_T("Unable to start translator thread")); 

    run_LEETT = false; // We only wish to create the thread a single time. 
    return 0; 
} 

extern "C" void __cdecl ccEntryOnEvent(WORD event) { 
    switch (event) { 
    case E_START: 
     if (run_LEETT) { 
      RunLEETTThread(); 
      MessageText ("Running LEETT Thread"); 
     } 
     break; 
    } 

    WaitForSingleObject(LEETT_Thread ,INFINITE); 
    return; 
} 

的函數聲明爲

unsigned __stdcall LEETT_Main (void* lpParam) { 

LEETT_Main大約136k,編譯爲獨立可執行文件而沒有優化(我有一個單獨的帶有main()的文件,它調用與myFunc相同的函數)。

之前改變線程的調用方式,宣告包含一個std ::列表的結構時,程序會崩潰,如下所示:

struct stateFlags { 
    bool inComment; // multiline comments bypass parsing, but not line numbering 
    // Line preconditions 
    bool MCodeSeen; // only 1 m code per block allowed 
    bool GCodeSeen; // only 1 g code per block allowed 

    std::list <int> gotos; // a list of the destination line numbers 
}; 

現在崩潰的_beginthreadex命令,通過追蹤顯示這

/* 
    * Allocate and initialize a per-thread data structure for the to- 
    * be-created thread. 
    */ 
    if ((ptd = (_ptiddata)_calloc_crt(1, sizeof(struct _tiddata))) == NULL) 
      goto error_return; 

通過此跟蹤我看到一個錯誤252(壞ptr),最終255(運行時錯誤)。

我想知道是否有人遇到這種行爲創建線程(在dll中?)以及可能的補救措施。當我在我的玩具程序中創建這個結構的實例時,沒有問題。當我刪除列表變量時,程序在其他地方簡單地崩潰,在字符串的聲明上

在這一點上,我非常樂於提出建議,如果必須現在刪除線程的想法,儘管它不是特別實用。

感謝,特別是對那些讀這一遍又一遍:)

+0

難道這是調用應用程序與您的DLL之間的運行時間衝突。你確定你使用了相同的運行時?混合/ MT/MTd/MD和/ MDd時可能會出現問題。 – Chad

+0

@Stephen,只是爲了排除這一點 - 你說你正在創建線程啓動。你的初創公司碰巧是DllMain嗎? – eran

+0

@Chad我正在使用他們的項目配置文件,它使用/ MT。另外我在這個環境中開發的其他項目也能正確執行。 – Stephen

回答

0

線程使用CRT(和std::list意味着CRT)需要與_beginthreadex被創建,如記錄上MSDN

在一個線程調用C運行時庫(CRT) 的可執行文件應該使用_beginthreadex和_endthreadex函數用於線程 管理而不是CreateThread和ExitThread;

不清楚你如何開始你的線程,但它似乎是你在DllMain中做的,這是不推薦的(見Does creating a thread from DllMain deadlock or doesn't it?)。

+0

感謝您的回覆,我會在早上做出這些更改,看看它是否能解決問題。 – Stephen

+0

要麼我錯誤地實施了你的建議,要麼還沒有解決我的問題。但是,感謝這個想法。 – Stephen

+0

你說現在它崩潰了在'_beginthreadex'中分配TLS存儲('__declspec(thread)')的行?你可以在一個真正的調試器(即Windbg,而不是Visual Studio)下運行你的程序,看看'_calloc_crt'調用中是否有任何類型的SEH異常?另外,請檢查'!teb'(請參閱http://windbg.info/doc/1-common-cmds.html#12_thread)並查看失敗點處聲明的堆棧大小。 –

0

在重新檢查這裏的註釋和項目配置時,供應商提供的解決方案文件使用/ MTd進行調試,但是我們正在構建一個DLL,因此我需要使用/ MDd,它立即編譯並正確運行。

很抱歉的荒謬摸不到頭腦...