/* * Error.c * * Sample code for "Multithreading Applications in Win32" * This is from Chapter 2, Listing 2-4 * * Demonstrate ExitThread */
#define WIN32_LEAN_AND_MEAN#include <stdio.h>#include <stdlib.h>#include <windows.h>#include "MtVerify.h"
DWORD WINAPI ThreadFunc(LPVOID);
int main(){ HANDLE hThrd; DWORD exitCode = 0; DWORD threadId; MTVERIFY( hThrd = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &threadId ) ); if (hThrd) printf("Thread launched\n");
MTVERIFY( CloseHandle(hThrd) );
for(;;) { BOOL rc; MTVERIFY( rc = GetExitCodeThread(hThrd, &exitCode) ); if (rc || exitCode != STILL_ACTIVE ) break; }
printf("Thread returned %d\n", exitCode);
return EXIT_SUCCESS;}
DWORD WINAPI ThreadFunc(LPVOID n){ printf("Thread running\n"); return 0;}
od
00401000 /$ 81EC 10010000 sub esp, 11000401006 |. 53 push ebx00401007 |. 56 push esi00401008 |. 8D4424 14 lea eax, dword ptr [esp+14]0040100C |. 57 push edi0040100D |. 50 push eax ; /pThreadId0040100E |. 6A 00 push 0 ; |CreationFlags = 000401010 |. 6A 01 push 1 ; |pThreadParm = 0000000100401012 |. 68 20124000 push 00401220 ; |ThreadFunction = Error.0040122000401017 |. 6A 00 push 0 ; |StackSize = 000401019 |. 6A 00 push 0 ; |pSecurity = NULL0040101B |. C74424 28 000>mov dword ptr [esp+28], 0 ; |00401023 |. FF15 1C204000 call dword ptr [<&KERNEL32.CreateThre>; \CreateThread00401029 |. 8BF0 mov esi, eax0040102B |. 85F6 test esi, esi0040102D |. 75 7B jnz short 004010AA0040102F |. FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError00401035 |. 56 push esi ; /Arguments00401036 |. 8D4C24 10 lea ecx, dword ptr [esp+10] ; |0040103A |. 56 push esi ; |BufSize0040103B |. 51 push ecx ; |Buffer0040103C |. 56 push esi ; |LanguageId0040103D |. 50 push eax ; |MessageId0040103E |. 56 push esi ; |pSource0040103F |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|000401044 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA0040104A |. 8B5424 0C mov edx, dword ptr [esp+C]0040104E |. 8D4424 1C lea eax, dword ptr [esp+1C]00401052 |. 52 push edx ; /<%s>00401053 |. 68 C4304000 push 004030C4 ; |<%s> = "hThrd = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &threadId )"00401058 |. 68 BC304000 push 004030BC ; |<%s> = "Error.c"0040105D |. 6A 1E push 1E ; |<%d> = 1E (30.)0040105F |. 68 78304000 push 00403078 ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""00401064 |. 50 push eax ; |s00401065 |. FF15 60204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA0040106B |. 83C4 18 add esp, 180040106E |. 8D4C24 14 lea ecx, dword ptr [esp+14]00401072 |. 8D7C24 1C lea edi, dword ptr [esp+1C]00401076 |. 33C0 xor eax, eax00401078 |. 56 push esi ; /pOverlapped00401079 |. 51 push ecx ; |pBytesWritten0040107A |. 83C9 FF or ecx, FFFFFFFF ; |0040107D |. 8D5424 24 lea edx, dword ptr [esp+24] ; |00401081 |. F2:AE repne scas byte ptr es:[edi] ; |00401083 |. F7D1 not ecx ; |00401085 |. 49 dec ecx ; |00401086 |. 51 push ecx ; |nBytesToWrite00401087 |. 52 push edx ; |Buffer00401088 |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE0040108A |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle00401090 |. 50 push eax ; |hFile00401091 |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile00401097 |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms0040109C |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep004010A2 |. 6A 01 push 1 ; /status = 1004010A4 |. FF15 2C204000 call dword ptr [<&MSVCRTD.exit>] ; \exit004010AA |> 8B1D 28204000 mov ebx, dword ptr [<&MSVCRTD.printf>; MSVCRTD.printf004010B0 |. 68 64304000 push 00403064 ; /format = "Thread launched",LF,""004010B5 |. FFD3 call ebx ; \printf004010B7 |. 83C4 04 add esp, 4004010BA |. 56 push esi ; /hObject004010BB |. FF15 04204000 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle004010C1 |. 85C0 test eax, eax004010C3 |. 0F85 80000000 jnz 00401149004010C9 |. FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError004010CF |. 6A 00 push 0 ; /Arguments = NULL004010D1 |. 8D4C24 10 lea ecx, dword ptr [esp+10] ; |004010D5 |. 6A 00 push 0 ; |BufSize = 0004010D7 |. 51 push ecx ; |Buffer004010D8 |. 6A 00 push 0 ; |LanguageId = 0 (LANG_NEUTRAL)004010DA |. 50 push eax ; |MessageId004010DB |. 6A 00 push 0 ; |pSource = NULL004010DD |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0004010E2 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA004010E8 |. 8B5424 0C mov edx, dword ptr [esp+C]004010EC |. 8D4424 1C lea eax, dword ptr [esp+1C]004010F0 |. 52 push edx ; /<%s>004010F1 |. 68 50304000 push 00403050 ; |<%s> = "CloseHandle(hThrd)"004010F6 |. 68 BC304000 push 004030BC ; |<%s> = "Error.c"004010FB |. 6A 22 push 22 ; |<%d> = 22 (34.)004010FD |. 68 78304000 push 00403078 ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""00401102 |. 50 push eax ; |s00401103 |. FF15 60204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA00401109 |. 83C4 18 add esp, 180040110C |. 8D4C24 14 lea ecx, dword ptr [esp+14]00401110 |. 8D7C24 1C lea edi, dword ptr [esp+1C]00401114 |. 33C0 xor eax, eax00401116 |. 6A 00 push 0 ; /pOverlapped = NULL00401118 |. 51 push ecx ; |pBytesWritten00401119 |. 83C9 FF or ecx, FFFFFFFF ; |0040111C |. 8D5424 24 lea edx, dword ptr [esp+24] ; |00401120 |. F2:AE repne scas byte ptr es:[edi] ; |00401122 |. F7D1 not ecx ; |00401124 |. 49 dec ecx ; |00401125 |. 51 push ecx ; |nBytesToWrite00401126 |. 52 push edx ; |Buffer00401127 |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE00401129 |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle0040112F |. 50 push eax ; |hFile00401130 |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile00401136 |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms0040113B |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep00401141 |. 6A 01 push 1 ; /status = 100401143 |. FF15 2C204000 call dword ptr [<&MSVCRTD.exit>] ; \exit00401149 |> 8B3D 00204000 mov edi, dword ptr [<&KERNEL32.GetEx>; kernel32.GetExitCodeThread0040114F |. 8D4424 10 lea eax, dword ptr [esp+10]00401153 |. 50 push eax ; /pExitCode00401154 |. 56 push esi ; |hThread00401155 |. FFD7 call edi ; \GetExitCodeThread00401157 |. 85C0 test eax, eax00401159 |. 74 21 je short 0040117C0040115B |> 8B4424 10 /mov eax, dword ptr [esp+10]0040115F |. 0F85 97000000 |jnz 004011FC00401165 |. 3D 03010000 |cmp eax, 1030040116A |. 0F85 8C000000 |jnz 004011FC00401170 |. 8D4C24 10 |lea ecx, dword ptr [esp+10]00401174 |. 51 |push ecx00401175 |. 56 |push esi00401176 |. FFD7 |call edi00401178 |. 85C0 |test eax, eax0040117A |.^ 75 DF \jnz short 0040115B0040117C |> FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError00401182 |. 6A 00 push 0 ; /Arguments = NULL00401184 |. 8D5424 10 lea edx, dword ptr [esp+10] ; |00401188 |. 6A 00 push 0 ; |BufSize = 00040118A |. 52 push edx ; |Buffer0040118B |. 6A 00 push 0 ; |LanguageId = 0 (LANG_NEUTRAL)0040118D |. 50 push eax ; |MessageId0040118E |. 6A 00 push 0 ; |pSource = NULL00401190 |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|000401195 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA0040119B |. 8B4424 0C mov eax, dword ptr [esp+C]0040119F |. 8D4C24 1C lea ecx, dword ptr [esp+1C]004011A3 |. 50 push eax ; /<%s>004011A4 |. 68 24304000 push 00403024 ; |<%s> = "rc = GetExitCodeThread(hThrd, &exitCode)"004011A9 |. 68 BC304000 push 004030BC ; |<%s> = "Error.c"004011AE |. 6A 27 push 27 ; |<%d> = 27 (39.)004011B0 |. 68 78304000 push 00403078 ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""004011B5 |. 51 push ecx ; |s004011B6 |. FF15 60204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA004011BC |. 8D7C24 34 lea edi, dword ptr [esp+34]004011C0 |. 83C9 FF or ecx, FFFFFFFF004011C3 |. 33C0 xor eax, eax004011C5 |. 83C4 18 add esp, 18004011C8 |. F2:AE repne scas byte ptr es:[edi]004011CA |. F7D1 not ecx004011CC |. 8D5424 14 lea edx, dword ptr [esp+14]004011D0 |. 6A 00 push 0 ; /pOverlapped = NULL004011D2 |. 49 dec ecx ; |004011D3 |. 52 push edx ; |pBytesWritten004011D4 |. 8D4424 24 lea eax, dword ptr [esp+24] ; |004011D8 |. 51 push ecx ; |nBytesToWrite004011D9 |. 50 push eax ; |Buffer004011DA |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE004011DC |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle004011E2 |. 50 push eax ; |hFile004011E3 |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile004011E9 |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms004011EE |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep004011F4 |. 6A 01 push 1 ; /status = 1004011F6 |. FF15 2C204000 call dword ptr [<&MSVCRTD.exit>] ; \exit004011FC |> 50 push eax004011FD |. 68 10304000 push 00403010 ; ASCII "Thread returned %d",LF00401202 |. FFD3 call ebx00401204 |. 83C4 08 add esp, 800401207 |. 33C0 xor eax, eax00401209 |. 5F pop edi0040120A |. 5E pop esi0040120B |. 5B pop ebx0040120C |. 81C4 10010000 add esp, 11000401212 \. C3 retn
thread
00401220 . 68 08314000 push 00403108 ; /format = "Thread running",LF,""00401225 . FF15 28204000 call dword ptr [<&MSVCRTD.printf>] ; \printf0040122B . 83C4 04 add esp, 40040122E . 33C0 xor eax, eax00401230 . C2 0400 retn 4
ida
.text:00401000 ; =============== S U B R O U T I N E =======================================.text:00401000.text:00401000.text:00401000 ; int __cdecl main(int argc, const char **argv, const char *envp).text:00401000 _main proc near ; CODE XREF: start+FAp.text:00401000.text:00401000 Buffer = byte ptr -110h.text:00401000 ExitCode = dword ptr -10Ch.text:00401000 NumberOfBytesWritten= dword ptr -108h.text:00401000 ThreadId = dword ptr -104h.text:00401000 var_100 = byte ptr -100h.text:00401000 argc = dword ptr 4.text:00401000 argv = dword ptr 8.text:00401000 envp = dword ptr 0Ch.text:00401000.text:00401000 sub esp, 110h.text:00401006 push ebx.text:00401007 push esi.text:00401008 lea eax, [esp+118h+ThreadId].text:0040100C push edi.text:0040100D push eax ; lpThreadId.text:0040100E push 0 ; dwCreationFlags.text:00401010 push 1 ; lpParameter.text:00401012 push offset StartAddress ; lpStartAddress.text:00401017 push 0 ; dwStackSize.text:00401019 push 0 ; lpThreadAttributes.text:0040101B mov [esp+134h+ExitCode], 0.text:00401023 call ds:CreateThread.text:00401029 mov esi, eax.text:0040102B test esi, esi.text:0040102D jnz short loc_4010AA.text:0040102F call ds:GetLastError.text:00401035 push esi ; Arguments.text:00401036 lea ecx, [esp+120h+Buffer].text:0040103A push esi ; nSize.text:0040103B push ecx ; lpBuffer.text:0040103C push esi ; dwLanguageId.text:0040103D push eax ; dwMessageId.text:0040103E push esi ; lpSource.text:0040103F push 1100h ; dwFlags.text:00401044 call ds:FormatMessageA.text:0040104A mov edx, dword ptr [esp+11Ch+Buffer].text:0040104E lea eax, [esp+11Ch+var_100].text:00401052 push edx.text:00401053 push offset aHthrdCreatethr ; "hThrd = CreateThread(NULL, 0, ThreadFun"....text:00401058 push offset aError_c ; "Error.c".text:0040105D push 1Eh.text:0040105F push offset aTheFollowingCa ; "\nThe following call failed at line %d i"....text:00401064 push eax ; LPSTR.text:00401065 call ds:wsprintfA.text:0040106B add esp, 18h.text:0040106E lea ecx, [esp+11Ch+NumberOfBytesWritten].text:00401072 lea edi, [esp+11Ch+var_100].text:00401076 xor eax, eax.text:00401078 push esi ; lpOverlapped.text:00401079 push ecx ; lpNumberOfBytesWritten.text:0040107A or ecx, 0FFFFFFFFh.text:0040107D lea edx, [esp+124h+var_100].text:00401081 repne scasb.text:00401083 not ecx.text:00401085 dec ecx.text:00401086 push ecx ; nNumberOfBytesToWrite.text:00401087 push edx ; lpBuffer.text:00401088 push 0FFFFFFF4h ; nStdHandle.text:0040108A call ds:GetStdHandle.text:00401090 push eax ; hFile.text:00401091 call ds:WriteFile.text:00401097 push 0BB8h ; dwMilliseconds.text:0040109C call ds:Sleep.text:004010A2 push 1 ; Code.text:004010A4 call ds:exit.text:004010AA ; ---------------------------------------------------------------------------.text:004010AA.text:004010AA loc_4010AA: ; CODE XREF: _main+2Dj.text:004010AA mov ebx, ds:printf.text:004010B0 push offset Format ; "Thread launched\n".text:004010B5 call ebx ; printf.text:004010B7 add esp, 4.text:004010BA push esi ; hObject.text:004010BB call ds:CloseHandle.text:004010C1 test eax, eax.text:004010C3 jnz loc_401149.text:004010C9 call ds:GetLastError.text:004010CF push 0 ; Arguments.text:004010D1 lea ecx, [esp+120h+Buffer].text:004010D5 push 0 ; nSize.text:004010D7 push ecx ; lpBuffer.text:004010D8 push 0 ; dwLanguageId.text:004010DA push eax ; dwMessageId.text:004010DB push 0 ; lpSource.text:004010DD push 1100h ; dwFlags.text:004010E2 call ds:FormatMessageA.text:004010E8 mov edx, dword ptr [esp+11Ch+Buffer].text:004010EC lea eax, [esp+11Ch+var_100].text:004010F0 push edx.text:004010F1 push offset aClosehandleHth ; "CloseHandle(hThrd)".text:004010F6 push offset aError_c ; "Error.c".text:004010FB push 22h.text:004010FD push offset aTheFollowingCa ; "\nThe following call failed at line %d i"....text:00401102 push eax ; LPSTR.text:00401103 call ds:wsprintfA.text:00401109 add esp, 18h.text:0040110C lea ecx, [esp+11Ch+NumberOfBytesWritten].text:00401110 lea edi, [esp+11Ch+var_100].text:00401114 xor eax, eax.text:00401116 push 0 ; lpOverlapped.text:00401118 push ecx ; lpNumberOfBytesWritten.text:00401119 or ecx, 0FFFFFFFFh.text:0040111C lea edx, [esp+124h+var_100].text:00401120 repne scasb.text:00401122 not ecx.text:00401124 dec ecx.text:00401125 push ecx ; nNumberOfBytesToWrite.text:00401126 push edx ; lpBuffer.text:00401127 push 0FFFFFFF4h ; nStdHandle.text:00401129 call ds:GetStdHandle.text:0040112F push eax ; hFile.text:00401130 call ds:WriteFile.text:00401136 push 0BB8h ; dwMilliseconds.text:0040113B call ds:Sleep.text:00401141 push 1 ; Code.text:00401143 call ds:exit.text:00401149 ; ---------------------------------------------------------------------------.text:00401149.text:00401149 loc_401149: ; CODE XREF: _main+C3j.text:00401149 mov edi, ds:GetExitCodeThread.text:0040114F lea eax, [esp+11Ch+ExitCode].text:00401153 push eax ; lpExitCode.text:00401154 push esi ; hThread.text:00401155 call edi ; GetExitCodeThread.text:00401157 test eax, eax.text:00401159 jz short loc_40117C.text:0040115B.text:0040115B loc_40115B: ; CODE XREF: _main+17Aj.text:0040115B mov eax, [esp+11Ch+ExitCode].text:0040115F jnz loc_4011FC.text:00401165 cmp eax, 103h.text:0040116A jnz loc_4011FC.text:00401170 lea ecx, [esp+11Ch+ExitCode].text:00401174 push ecx ; lpExitCode.text:00401175 push esi ; hThread.text:00401176 call edi ; GetExitCodeThread.text:00401178 test eax, eax.text:0040117A jnz short loc_40115B.text:0040117C.text:0040117C loc_40117C: ; CODE XREF: _main+159j.text:0040117C call ds:GetLastError.text:00401182 push 0 ; Arguments.text:00401184 lea edx, [esp+120h+Buffer].text:00401188 push 0 ; nSize.text:0040118A push edx ; lpBuffer.text:0040118B push 0 ; dwLanguageId.text:0040118D push eax ; dwMessageId.text:0040118E push 0 ; lpSource.text:00401190 push 1100h ; dwFlags.text:00401195 call ds:FormatMessageA.text:0040119B mov eax, dword ptr [esp+11Ch+Buffer].text:0040119F lea ecx, [esp+11Ch+var_100].text:004011A3 push eax.text:004011A4 push offset aRcGetexitcodet ; "rc = GetExitCodeThread(hThrd, &exitCode"....text:004011A9 push offset aError_c ; "Error.c".text:004011AE push 27h.text:004011B0 push offset aTheFollowingCa ; "\nThe following call failed at line %d i"....text:004011B5 push ecx ; LPSTR.text:004011B6 call ds:wsprintfA.text:004011BC lea edi, [esp+134h+var_100].text:004011C0 or ecx, 0FFFFFFFFh.text:004011C3 xor eax, eax.text:004011C5 add esp, 18h.text:004011C8 repne scasb.text:004011CA not ecx.text:004011CC lea edx, [esp+11Ch+NumberOfBytesWritten].text:004011D0 push 0 ; lpOverlapped.text:004011D2 dec ecx.text:004011D3 push edx ; lpNumberOfBytesWritten.text:004011D4 lea eax, [esp+124h+var_100].text:004011D8 push ecx ; nNumberOfBytesToWrite.text:004011D9 push eax ; lpBuffer.text:004011DA push 0FFFFFFF4h ; nStdHandle.text:004011DC call ds:GetStdHandle.text:004011E2 push eax ; hFile.text:004011E3 call ds:WriteFile.text:004011E9 push 0BB8h ; dwMilliseconds.text:004011EE call ds:Sleep.text:004011F4 push 1 ; Code.text:004011F6 call ds:exit.text:004011FC ; ---------------------------------------------------------------------------.text:004011FC.text:004011FC loc_4011FC: ; CODE XREF: _main+15Fj.text:004011FC ; _main+16Aj.text:004011FC push eax.text:004011FD push offset aThreadReturned ; "Thread returned %d\n".text:00401202 call ebx ; printf.text:00401204 add esp, 8.text:00401207 xor eax, eax.text:00401209 pop edi.text:0040120A pop esi.text:0040120B pop ebx.text:0040120C add esp, 110h.text:00401212 retn.text:00401212 _main endp.text:00401212.text:00401212 ; ---------------------------------------------------------------------------.text:00401213 align 10h.text:00401220
thread
.text:00401220.text:00401220 ; =============== S U B R O U T I N E =======================================.text:00401220.text:00401220.text:00401220 ; DWORD __stdcall StartAddress(LPVOID).text:00401220 StartAddress proc near ; DATA XREF: _main+12o.text:00401220 push offset aThreadRunning ; "Thread running\n".text:00401225 call ds:printf.text:0040122B add esp, 4.text:0040122E xor eax, eax.text:00401230 retn 4.text:00401230 StartAddress endp.text:00401230.text:00401230 ; ---------------------------------------------------------------------------
转载于:https://www.cnblogs.com/nanshouyong326/archive/2010/07/07/1772718.html
