锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
鐜板湪浣跨敤W32DSM鏉ュ叿浣撹鏄庯細
1銆傚厛鎵撳紑闇瑕佸垎鏋愮殑DLL錛岀劧鍚庨氳繃鑿滃崟鍔熻兘-銆嬪嚭鍙f潵鎵懼埌闇瑕佸垎鏋愮殑鍑芥暟錛屽弻鍑誨氨鍙互浜嗐?nbsp;
瀹冨彲浠ョ洿鎺ュ畾浣嶅埌璇ュ嚱鏁般?nbsp;
2銆傜湅鍑嗚鍑芥暟鐨勫叆鍙o紝涓鑸嚱鏁版槸浠ヤ互涓嬩唬鐮佷綔涓哄叆鍙g偣鐨勩?nbsp;
push ebp
mov ebp, esp
...
3銆傜劧鍚庡線涓嬫壘鍒拌鍑芥暟鐨勫嚭鍙o紝涓鑸嚱鏁板嚭鍙f湁浠ヤ笅璇彞銆?nbsp;
...
ret xxxx;//鍏朵腑xxxx灝辨槸鍑芥暟宸暟鐨勬墍鏈夌殑瀛楄妭鏁幫紝涓?鐨勫嶆暟錛寈xxx闄や互4寰楀埌鐨勭粨鏋?nbsp;
灝辨槸鍙傛暟鐨勪釜鏁般?nbsp;
鍏朵腑鍙傛暟瀛樻斁鐨勫湴鏂癸細
ebp+08 //絎竴涓弬鏁?nbsp;
ebp+0C //絎簩涓弬鏁?nbsp;
ebp+10 //絎笁涓弬鏁?nbsp;
ebp+14 //絎洓涓弬鏁?nbsp;
ebp+18 //絎簲涓弬鏁?nbsp;
ebp+1C //絎叚涓弬鏁?nbsp;
銆傘傘傘?nbsp;
-------------------------------------------
榪樻湁涓縐嶇粡甯哥湅鍒扮殑璋冪敤鏂瑰紡錛?nbsp;
sub esp,xxxx //寮澶撮儴鍒?nbsp;
//鍑芥暟鐨勫唴瀹?nbsp;
銆傘傘?nbsp;
//鍑芥暟鐨勫唴瀹?nbsp;
add esp,xxxx
ret //緇撳熬閮ㄥ垎
鍏朵腑xxxx/4鐨勭粨鏋滀篃鏄弬鏁扮殑涓暟銆?nbsp;
-------------------------------------------------
榪樻湁涓縐嶈皟鐢ㄦ柟寮忥細
鏈変簬璇ュ嚱鏁版瘮杈冪畝鍗曪紝娌℃湁鍙傛暟鐨勫帇鏍堣繃紼嬶紝
閲岄潰鐨?nbsp;
esp+04灝辨槸絎竴涓弬鏁?nbsp;
esp+08灝辨槸絎簩涓弬鏁?nbsp;
銆傘傘?nbsp;
esp+xx灝辨槸絎瑇x/4涓弬鏁?nbsp;
浣犺鐪嬪埌鐨剎x鐨勬渶澶ф暟闄や互4鍚庣殑緇撴灉錛屽氨鏄鍑芥暟鎵浼犻掔殑鍙傛暟鐨勪釜鏁般?nbsp;
----------------------------------------------
鍒扮幇鍦ㄤ綅緗紝浣犲簲璇ヨ兘寰堟竻妤氱殑鐪嬪埌浜嗕紶閫掔殑鍙傛暟鐨勪釜鏁般傝嚦浜庝紶閫掔殑鏄簺浠涔堝唴瀹癸紝榪橀渶瑕佽繘涓姝ョ殑鍒嗘瀽銆?nbsp;
鏈鏂逛究鐨勫姙娉曞氨鏄厛鎵懼埌鏄粈涔堣蔣浠跺湪璋冪敤姝ゅ嚱鏁幫紝鐒跺悗閫氳繃璋冭瘯鐨勬妧鏈紝鎵懼埌璇ュ嚱鏁拌璋冪敤鐨勫湴鏂廣備竴鑸兘鏄疨USH鎸囦護
鏉ュ疄鐜板弬鏁扮殑浼犻掔殑銆傝繖鏃跺彲浠ョ湅涓涓嬪叿浣撴槸浠涔堜笢瑗胯鍘嬪叆鍫嗘爤浜嗭紝涓鑸潵璇達紝濡傛灉鍙傛暟鏄暣鏁幫紝涓鐪嬪氨鍙互鐭ラ亾浜嗭紝
濡傛灉鏄瓧絎︿覆鐨勮瘽涔熸槸姣旇緝綆鍗曠殑錛屽彧瑕佸埌閭d釜鍦板潃涓婇潰鍘葷湅涓涓嬪氨鍙互浜嗐?nbsp;
濡傛灉浼犻掔殑緇撴瀯鐨勮瘽錛屾病鏈夊緢鏂逛究鐨勫姙娉曡В鍐籌紝灝辨槸璇繪噦璇ユ眹緙栧氨鍙互浜嗐傚浜庝互涓婄殑鍒嗘瀽錛屾湰浜哄彧鍏跺埌浜嗘姏鐮栧紩鐜夛紝
甯屾湜瀵瑰ぇ瀹舵湁鐐圭敤澶勩?
SFP Overwrite
I'd like a share a little trick I figured out today. I'm sure it has been done before and probably many times but its new to me so I'll describe it here. I asked myself if anything cool could be achieved by overwriting the Saved Frame Pointer instead of the Return Address. I'm not sure what sort of security-related attacks could be leveraged by doing this, but I did find that its possible to affect the program flow in the calling function. This is just another trick to change the flow of execution and even works on a non-executable stack.
The vulnerable program source code
The attack program source code
EBP and Local Variables
The extended base pointer is a register used by the CPU as base for the current stack frame. As we discussed earlier, the EBP for the function that called the current one is stored in the current function's Saved Frame Pointer. The EBP points to this SFP; in this way, there is a chain of saved EBPs for each stack frame. Check out the EIP Redirection page for more details about this. The location of the current stack frame's SFP is stored in the Extended Base Pointer.
Keeping track of the chain of the program's stack frames is not the only purpose of the EBP/SFPs. As the name implies, the Extended Base Pointer register holds an address that is used as the "base" of the current stack frame (this address is the frame's SFP). The code in the current function references local variables using EBP as a base. For example, the C code for setting a variable equal to 3 is myVar = 3;. This might be assembled into something like: MOV SS:[EBP - 4], 0x03. This means that the local variable myVar is referred to as "the address on the stack stored in EBP, minus 4 bytes" by the assembled code. Another variable in the same function called myVar2 might be located at SS:[EBP - 8]. We can see that if an attacker could change the value of EBP, they could also change where the code thinks local variables are.
Using SFP to Modify EBP
Imagine that there is function called FunctionA that is not vulnerable to any sort of buffer overflow. Inside it is a local integer variable that is used by the function later on. Before the variable is used, another function called FunctionB is called. This one happens to be vulnerable to a buffer overflow. Our goal is to trick FunctionA into using a variable that we define instead of the one that it declared.
We wait until the execution reaches FunctionB and we are able to input our malicious buffer. At the beginning we'll have the value of the fake variable that FunctionA will be tricked into using. From there, we pad the buffer with junk until the saved frame pointer is reached. Now we push the address on the stack that is directly below our fake variable. The reason we do this is that FunctionA references its real variable as SS:[ebp - 4]. Therefore, our injected EBP must be 4 bytes beyond our fake variable. By setting it up in this way, if we can manage to get that address into the Extended Base Pointer while FunctionA is executing; our fake variable will be referenced instead of the real one. We are not overwriting the value in the real variable. Instead, we are changing FunctionA's perception of its location to an address inside the buffer that we control.
The Target
Now its time to put our attack into a context. At the top of the source code, you'll notice the vulnerable test() function. All it does is declare a 5 byte buffer and fail to protect it while its being filled with user input. The main() function declares a local integer variable (4 bytes) and feeds the decimal value 3 into it. Main() then calls the test() function which asks the user for input but doesn't do anything with it. After test() returns, a loop is entered. The loop keeping looping as long as the integer c is greater than zero. Each time it repeats, the value of c is decreased by one and "Later" is displayed on the screen. Overall, this thing prints that word c times. Because the value of this integer was set to 3 earlier, this means that "Later" is printed 3 times by this loop.
We will trick this program into thinking that a variable we create using the vulnerable buffer is actually c. By filling this fake variable with the decimal value 500,000,001, we'll make this loop run and print "Later" 500 million and one times instead of the expected three.
Buiding the Attack
As before, we'll be writing a program in C that will feed a malicious string into the input of the vulnerable program. Because our ultimate goal is to overwrite the test() function's SFP, we'll need to pad the string appropriately to get there. The first 4 bytes of the attack string will be the value of our fake variable that main() will eventually use in its loop. These bytes need to equal the goal of 500,000,001 so we'll feed "\x01\x65\xCD\x1D" first. The next four do not matter in this case, but take note that they will become main()'s fake SFP. From here use OllyDbg to find the distance between this fake main() SFP and test()'s SFP. If you are unsure where the test() function's SFP is, you can always step the program until inside test() and check the EBP register. You'll find that the buffer begins at 0x0027FF00 and the test() function's SFP is located at 0x0027FF18. After converting to decimal and subtracting the 8 bytes we already used up so far, it means we'll need to add 16 bytes of padding to reach test()'s SFP.
Next we'll actually overwrite the SFP. Have a look at the main() function and you'll find that the loop references the variable c as SS:[EBP - 4]. This means that if we want it to reference that 4 byte value at the beginning of the buffer instead, we need main()'s EBP to point to the address 4 bytes beyond the beginning of our attack buffer. We've already pointed out that any value we can sneak into test()'s SFP will end up in the EBP when main() returns. So we end the attack string with the following 3 bytes: "\x04\xFF\x27". The value is chosen because 0x0027FF04 - 4 is the address of our fake variable. Writing all four bytes is, again, not necessary because gets() automatically sticks a null byte at the end of the string inputted.
Final Overview
By crafting the above buffer and ensuring that the last 3 bytes overwrite test()'s SFP, we directly control EBP when test() returns back to main(). Because main() uses EBP to reference an important variable c and we control EBP; we make main() think that c is actually where our old overwritten buffer began. The data is still there because there was no reason for the program to erase/modify it. Because c is referenced as SS:[EBP - 4] in main(), we need that overwritten Stack Frame Pointer to point to the address four bytes below the fake variable location on the stack. When main uses our fake EBP to reference variable c is it will subtract 4 from it and find our fake variable value. This was filled in with the decimal value of 500,000,001. Main() runs the loop to print "Later" a number of times determined by c. So by doing all of this trickery we can make the program display "Later" 500,000,001 times instead of 3.
浠g爜:
char __usercall sub_1000E860<al>(int a1<ebx>) { int ST14_4_0; // ST14_4@0 int v2; // ST10_4@1 const CHAR *v3; // eax@3 const CHAR *v4; // eax@10 int v6; // eax@2 char v7; // bl@2 char v8; // al@9 int v9; // [sp+Ch] [bp-9Ch]@1 signed int v10; // [sp+A4h] [bp-4h]@1 char v11; // [sp+10h] [bp-98h]@1 char v12; // [sp+48h] [bp-60h]@2 char v13; // [sp+2Ch] [bp-7Ch]@2 LPCSTR lpText; // [sp+14h] [bp-94h]@3 unsigned int v15; // [sp+28h] [bp-80h]@3 char v16; // [sp+64h] [bp-44h]@15 BYTE3(v9) = 0; sub_10016AA0(); v10 = 0; std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__(&v11); LOBYTE(v10) = 1; v2 = a1; while ( 1 ) { sub_100169B0(16, (int)&v12); LOBYTE(v10) = 2; v6 = std__operator_(&v13, v6, "\\etc\\licence"); LOBYTE(v10) = 3; v7 = sub_10017A20((int)&unk_10024460, v6, (int)&v11) == 0; LOBYTE(v10) = 2; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v13); LOBYTE(v10) = 1; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v12); if ( !v7 ) break; std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v11, "\nThe add-in will not work without a valid licence.\n\nInstall the licence file now?", v2); v3 = lpText; if ( v15 < 0x10 ) v3 = (const CHAR *)&lpText; if ( MessageBoxA(0, v3, "AspectC++ Add-In for Visual Studio .NET", 0x24u) != 6 ) break; if ( !sub_1000E690() ) { MessageBoxA(0, "Installation of licence file failed.", "AspectC++ Add-In", 0x40u); break; } } if ( byte_10024465 ) { sub_10017730((int)&unk_10024460, 16, (int)&v11); if ( v8 && (unsigned __int8)sub_10017520(&v11) != 1 ) { BYTE3(v9) = 1; } else { std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v11, "\nThe add-in will not work.", ST14_4_0); v4 = lpText; if ( v15 < 0x10 ) v4 = (const CHAR *)&lpText; MessageBoxA(0, v4, "AspectC++ Add-In", 0x40u); } } LOBYTE(v10) = 0; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v11); v10 = -1; sub_10016910((int)&v16); return BYTE3(v9); }
鍩烘湰涓婂彲浠ュ緱鍑洪粯璁ゆ槸鍒嗘瀽
C:\Program Files\pure-systems\AspectC++ Add-In\etc\licence 璁稿彲鏂囦歡
鍒嗘瀽榪囩▼搴旇鍦?x10017a20閲?
浠g爜:
char __thiscall sub_10017A20(int this, int a2, int a3) { int v3; // ebp@1 int v4; // esi@1 int v5; // eax@2 int v6; // eax@4 int v7; // edi@5 char result; // al@8 int v9; // ecx@1 int v10; // eax@5 int v11; // eax@6 int v12; // ST04_4@6 char v13; // bl@6 char v14; // [sp+Ch] [bp-28h]@6 signed int v15; // [sp+30h] [bp-4h]@6 v3 = a3; v4 = this; v9 = this + 96; *(_DWORD *)v9 = 0; *(_DWORD *)(v9 + 4) = 0; *(_DWORD *)(v9 + 8) = 0; *(_DWORD *)(v9 + 12) = 0; *(_BYTE *)(v4 + 5) = 0; std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(v3, "Loading licence file failed."); if ( *(_DWORD *)(a2 + 24) < 0x10u ) v5 = a2 + 4; else v5 = *(_DWORD *)(a2 + 4); v6 = xmlParseFile(v5); *(_DWORD *)v4 = v6; if ( v6 && (v10 = xmlDocGetRootElement(v6), v7 = v10, v10) && (v11 = std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__( &v14, "licence"), v12 = *(_DWORD *)(v7 + 8), v15 = 0, v13 = std__operator__(v11, v12), v15 = -1, std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v14), v13) && sub_10017930(v7) ) { *(_BYTE *)(v4 + 5) = 1; sub_10017730(v4, v3, v3); result = 1; } else { result = 0; } return result; }
榪欐槸0x10017730鐨勮繃紼?
浠g爜:
void __userpurge sub_10017730(int this<ecx>, int ebp0<ebp>, int a2) { int ST18_4_0; // ST18_4@0 int ST1C_4_0; // ST1C_4@0 int v5; // esi@1 signed int v6; // eax@4 int v7; // ST18_4@6 int v8; // eax@20 int v9; // eax@4 int v10; // ST1C_4@12 int v11; // ST1C_4@18 int r; // [sp+60h] [bp+0h]@1 int v13; // [sp+50h] [bp-10h]@1 signed int v14; // [sp+5Ch] [bp-4h]@3 char v15; // [sp+34h] [bp-2Ch]@4 char v16; // [sp+18h] [bp-48h]@4 int v17; // [sp+1Ch] [bp-44h]@12 unsigned int v18; // [sp+30h] [bp-30h]@20 int v19; // [sp+2Ch] [bp-34h]@22 v5 = this; v13 = r ^ dword_100242D0; std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(a2, "Invalid licence file found."); if ( *(_BYTE *)(v5 + 5) && !*(_BYTE *)(v5 + 4) ) { sub_10017B20((int)&a2, ebp0); v14 = 0; if ( !sub_1001A050((int)&a2) ) { LABEL_23: v14 = -1; sub_1001A060(&a2); goto LABEL_24; } v9 = std__operator_(&v15, v5 + 12, v5 + 40); LOBYTE(v14) = 1; std__operator_(&v16, v9, v5 + 68); LOBYTE(v14) = 3; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v15); v6 = *(_DWORD *)(v5 + 8); if ( v6 || !*(_DWORD *)(v5 + 96) ) { if ( v6 == 1 && *(_DWORD *)(v5 + 96) && *(_DWORD *)(v5 + 100) && *(_DWORD *)(v5 + 104) && *(_DWORD *)(v5 + 108) ) { std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "evaluation", ST18_4_0); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 96), ST1C_4_0); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 100), v10); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 104), ST1C_4_0); v7 = *(_DWORD *)(v5 + 108); } else { if ( v6 != 2 || !*(_DWORD *)(v5 + 96) || !*(_DWORD *)(v5 + 100) || !*(_DWORD *)(v5 + 104) || !*(_DWORD *)(v5 + 108) ) goto LABEL_20; std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "user", ST18_4_0); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 96), ST1C_4_0); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 100), v11); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__( &v17, *(_DWORD *)(v5 + 104), ST1C_4_0); v7 = *(_DWORD *)(v5 + 108); } } else { std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "beta", ST18_4_0); v7 = *(_DWORD *)(v5 + 96); } std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v17, v7, ST1C_4_0); LABEL_20: v8 = v17; if ( v18 < 0x10 ) v8 = (int)&v17; *(_BYTE *)(v5 + 4) = sub_10019E30(v5 + 112, v8, v19, (int)&a2); LOBYTE(v14) = 0; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v16); goto LABEL_23; } LABEL_24: sub_1001A7B0( r ^ v13, ebp0); }
鏄ㄥぉ鎴戣嚜宸辮皟璇曠殑鏃跺欎篃鐘簡涓涓敊璇紝灝辨槸璋冭瘯CppAddin.dll寰堢棝鑻︼紝嫻垂涓嶅皯鏃墮棿鍜屽垎鏁e緢澶氱殑綺懼姏錛屼腑闂磋佹槸鍙楀埌Va_X.dll鐨勫共鎵幫紝鑰屼笖msdev.exe鍦–ppAddin娌″姞杞芥椂娌℃硶鐩存帴涓嬫柇鐐癸紝蹇呴』寰楀湪OD涓緗竴涓柊妯″潡鍔犺澆鐨勬柇鐐癸紙閫夐」->璋冭瘯閫夐」->浜嬩歡->涓柇浜庢柊妯″潡錛?榪欐牱涓嬫潵錛屾瘡嬈¤皟璇曞け璐ュ悗閲嶅惎鐨勮繃紼嬪緢鏄極闀匡紝嫻垂浜嗕笉灝戞椂闂達紝鍙戝笘瀛愮殑姹傚姪鐨勬椂鍊欙紝鎴戜負浜嗗ぇ澶т滑緇欐垜鑳芥柟渚跨殑瑙e喅闂錛屽敖閲忔妸闈炴妧鏈棶棰橀兘璇曢獙浜嗕竴涓嬶紝浠ュ厤澶уぇ浠榪欎簺闂鍥頒綇浜嗭紝涓鎬掍箣涓嬩笉緇欐垜綆℃垜浜嗐備絾鏄繖鏍蜂竴鏉ワ紝涔熶負鎴戣嚜宸辮В鍐沖拰鍙戠幇闂鍔犲揩浜嗛熷害銆?br />鎬葷粨涓涓嬶細
1.瑙e喅闂瑕佷笢鏂逛笉浜紝瑗挎柟浜紝涓嶈灝嗚嚜宸辯簿鍔涙秷鑰楀湪榪滅闂鏈韓鐨勫湴鏂?br /> 2.鍧氭寔灝辨槸鑳滃埄錛屽摢鎬曟槸鑿滈笩錛屼笉鎳傚灝戞眹緙栵紙鐪嬩唬鐮佽繕寰楅潬浼熷ぇ銆佸厜鑽c佹紜殑F5錛夛紝涔熻兘鍙栧緱鎴愮嘩
涓嬮潰鍐欏啓鍒嗘瀽榪囩▼錛?br />鍏跺疄鏄ㄥぉ宸茬粡鎵懼埌浜嗗叧閿殑榪囩▼錛岄偅灝辨槸0x10017a20錛岃繖閲岄潰灝辨槸鍒嗘瀽xml鏍煎紡鐨勮鍙枃浠?br />榪欓噷闈㈡湁涓や釜璋冪敤錛宻ub_10017930()鍜?sub_10017730()
澶ф鍙互鐪嬪緱鍑烘潵錛宻ub_10017930鍙備笌浜唜ml鏍煎紡鐨勮鍙暟鎹殑瑙f瀽榪囩▼錛屽畠璋冪敤鎴愬姛涔嬪悗錛屾墠璋冪敤10017730瀵規暟鎹繘琛岄獙璇侊紝瑕佸垎鏋愯鍙暟鎹牸寮忥紝蹇呴』鐮旂┒10017930
浠g爜:
char __stdcall sub_10017930(int a1) { int v1; // ebp@1 int v2; // esi@1 int v3; // esi@3 char result; // al@7 int v5; // eax@1 int v6; // eax@2 char v7; // bl@2 char v8; // [sp+Ch] [bp-28h]@2 signed int v9; // [sp+30h] [bp-4h]@2 v1 = a1; v5 = xmlGetProp(a1, "version"); v2 = v5; if ( v5 && (v6 = std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__( &v8, L"1"), v9 = 0, v7 = std__operator__(v6, v2), v9 = -1, std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v8), v7) ) { v3 = *(_DWORD *)(v1 + 12); result = (unsigned __int8)sub_10016D60(*(_DWORD *)(v1 + 12)) && (unsigned __int8)sub_10016E70(v3) && (unsigned __int8)sub_10017570(v3) && (unsigned __int8)sub_100172C0(v3); } else { result = 0; } return result; }
鍦ㄨ繖閲岄潰鍙栦簡xml鐨勪竴涓睘鎬у紇ersion,騫朵笖榪樻湁鍥涗釜閮戒笉鑳藉け璐ョ殑榪囩▼:
10016d60 鍙杙roduct 鍏冪礌
10016e70 鍙朿reation 鍏冪礌
10017570 鍙杢ype鍏冪礌
100172c0 鍙杝ignature鍏冪礌
涓轟簡鐔熸倝libxml,鎴戠壒鎰忕紪鍐欎簡涓孌靛吀鍨媗ibxml鐢ㄦ硶,騫跺垎鏋愪簡鍏跺弽鍚戝伐紼嬪悗鐨勪唬鐮侊紝
浠g爜:
xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; string filename("test.xml"); doc = xmlParseFile(filename.c_str()); cur = xmlDocGetRootElement(doc); if (xmlStrcmp(cur->name, BAD_CAST "licence")) { fprintf(stderr,"document of the wrong type, root node != mail"); xmlFreeDoc(doc); /*return -1; */ } cur = cur->xmlChildrenNode; xmlNodePtr propNodePtr = cur; while(cur != NULL) { //¨¨?3??¨²¦Ì??D¦Ì??¨²¨¨Y if ((!xmlStrcmp(cur->name, (const xmlChar *)"product"))) { string name; string version; xmlChar* szAttr = xmlGetProp(cur,BAD_CAST "name"); name=(char*)szAttr; szAttr=xmlGetProp(cur,BAD_CAST "version"); version=(const char *)szAttr; cout<<"Name:"<<name<<" Version:"<<version<<endl; xmlFree(szAttr); } cur=cur->next; } xmlFreeDoc(doc); /*return 0;*/
寰楀嚭鐨勭粨璁烘槸錛屽嚒鏄睘鎬у肩殑鑾峰彇錛岄兘浼氳皟鐢▁mlGetProp錛岃屽瓙鍏冪礌鐨勮幏鍙栧垯鏄氳繃鐩存帴璁塊棶鍐呭瓨緇撴瀯鎴栬呯被浼糲++鐨勫嚱鏁拌闂紝涓嶄細鐪嬪埌鍑芥暟鍚嶇О鐨勫紩鐢紝鏍規嵁榪欎竴緇撹鍜屽叿浣撶殑璋冭瘯錛屽ぇ鑷存帹鍑烘潵licence鏂囦歡鐨勭粨鏋勫涓?
浠g爜:
<?xml version="1.0" encoding="UTF-8"?> <licence version="1"> <product name="aspect" version="1.0"/> <product name="pointcut" version="1.0" /> <product name="advice" version="1.0" /> <product name="slice" version="1.0" /> <creation date="2009-8-13"/> <type name="user"> <data code="xxxx" name="jans2002" email="jans2002@gmail.com" regnr="ccccc"/> </type> <signature sign="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /> </licence>
鏈変簡榪欎釜licence鏂囦歡錛屾妸瀹冩斁鍒?br />C:\Program Files\pure-systems\AspectC++ Add-In\etc\鐩綍涓?br />涓鍒囬棶棰樺氨鍙樺緱綆鍗曚簡,欏哄埄鎵ц瀹屼簡0x10017930錛屼竴璺潃鍒?x10017730
浠g爜:
int __thiscall sub_10017730(int this, int a2) { int v2; // esi@1 signed int v3; // eax@4 int v4; // ST14_4@6 int v5; // eax@20 int v7; // eax@4 int r; // [sp+4Ch] [bp+0h]@1 int v9; // [sp+3Ch] [bp-10h]@1 signed int v10; // [sp+48h] [bp-4h]@3 char v11; // [sp+20h] [bp-2Ch]@4 char v12; // [sp+4h] [bp-48h]@4 int v13; // [sp+8h] [bp-44h]@20 unsigned int v14; // [sp+1Ch] [bp-30h]@20 int v15; // [sp+18h] [bp-34h]@22 v2 = this; v9 = r ^ dword_100242D0; std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(a2, "Invalid licence file found."); if ( *(_BYTE *)(v2 + 5) && !*(_BYTE *)(v2 + 4) ) { sub_10017B20(); v10 = 0; if ( !(unsigned __int8)sub_1001A050() ) { LABEL_23: v10 = -1; sub_1001A060(); return sub_1001A7B0(); } v7 = std__operator_(&v11, v2 + 12, v2 + 40); LOBYTE(v10) = 1; std__operator_(&v12, v7, v2 + 68); LOBYTE(v10) = 3; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v11); v3 = *(_DWORD *)(v2 + 8); if ( v3 || !*(_DWORD *)(v2 + 96) ) { if ( v3 == 1 && *(_DWORD *)(v2 + 96) && *(_DWORD *)(v2 + 100) && *(_DWORD *)(v2 + 104) && *(_DWORD *)(v2 + 108) ) { std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "evaluation"); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 96)); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 100)); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 104)); v4 = *(_DWORD *)(v2 + 108); } else { if ( v3 != 2 || !*(_DWORD *)(v2 + 96) || !*(_DWORD *)(v2 + 100) || !*(_DWORD *)(v2 + 104) || !*(_DWORD *)(v2 + 108) ) goto LABEL_20; std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "user"); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 96)); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 100)); std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 104)); v4 = *(_DWORD *)(v2 + 108); } } else { std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "beta"); v4 = *(_DWORD *)(v2 + 96); } std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, v4); LABEL_20: v5 = v13; if ( v14 < 0x10 ) v5 = (int)&v13; *(_BYTE *)(v2 + 4) = sub_10019E30(v2 + 112, v5, v15, (int)&a2); LOBYTE(v10) = 0; std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v12); goto LABEL_23; } return sub_1001A7B0(); }
鐢變簬鏈変簡姝g‘鏍煎紡鐨刲icence錛屽墠闈㈡墽琛岀殑閮藉緢欏哄埄錛屼竴鐩村埌浜唖ub_10019E30,璺熻繘鍘諱竴鐪嬶紝涓鍒囦簡鐒朵簡:
浠g爜:
bool __thiscall sub_10019E30(int this, int a2, int a3, int a4) { int v5; // esi@1 int v6; // eax@1 int v7; // eax@1 char v8; // [sp+4h] [bp-10h]@1 v5 = this; v6 = EVP_sha1(); EVP_DigestInit(&v8, v6); EVP_DigestUpdate(&v8, a2, a3); v7 = sub_1001A030(); return EVP_VerifyFinal(&v8, v5, *(_DWORD *)(v5 + 4096), v7) == 1;
}
鍓嶉潰涓瀹氶兘鏄姞瀵嗛獙璇佺殑錛屼絾鏄嚱鏁版渶鍚庢潵浜嗕竴鍙?
浠g爜:
EVP_VerifyFinal(&v8, v5, *(_DWORD *)(v5 + 4096), v7) == 1;
鍢垮樋錛岀湅鍚嶅瓧浼拌灝辨槸榪欎釜浜嗭紝鐪嬬湅榪欎釜鍑芥暟鐨勮繑鍥炲鹼紝1琛ㄧず鎴愬姛錛屽叾浠栬〃紺哄け璐ワ紝閭e氨鏄彧瑕佽姝ゅ嚱鏁版案榪滆繑鍥?錛屽氨澶у姛鍛婃垚浜嗭紝璇ュ埌姹囩紪浠g爜浜?
浠g爜:
004066F0 /$ 83EC 10 sub esp, 10 ; 媯鏌ユ暟瀛楃鍚嶉儴鍒? 004066F3 |. 56 push esi 004066F4 |. 8BF1 mov esi, ecx 004066F6 |. E8 81270000 call <jmp.&LIBEAY32.#333> 004066FB |. 50 push eax 004066FC |. 8D4424 08 lea eax, dword ptr [esp+8] 00406700 |. 50 push eax 00406701 |. E8 70270000 call <jmp.&LIBEAY32.#268> 00406706 |. 8B4C24 24 mov ecx, dword ptr [esp+24] 0040670A |. 8B5424 20 mov edx, dword ptr [esp+20] 0040670E |. 51 push ecx 0040670F |. 52 push edx 00406710 |. 8D4424 14 lea eax, dword ptr [esp+14] 00406714 |. 50 push eax 00406715 |. E8 56270000 call <jmp.&LIBEAY32.#269> 0040671A |. 8B4C24 34 mov ecx, dword ptr [esp+34] 0040671E |. 83C4 14 add esp, 14 00406721 |. E8 2A100000 call 00407750 00406726 |. 8B8E 00100000 mov ecx, dword ptr [esi+1000] 0040672C |. 50 push eax 0040672D |. 51 push ecx 0040672E |. 8D5424 0C lea edx, dword ptr [esp+C] 00406732 |. 56 push esi 00406733 |. 52 push edx 00406734 |. E8 49270000 call <jmp.&LIBEAY32.#290> 00406739 |. 83C4 10 add esp, 10 0040673C |. 48 dec eax 0040673D |. F7D8 neg eax 0040673F 1BC0 sbb eax, eax 00406741 90 inc eax 00406742 5E pop esi 00406743 83C4 10 add esp, 10 00406746 \. C2 0C00 retn 0C
涓鑸潵璁詫紝鍑芥暟榪斿洖鍊奸兘浼氱敤EAX,涓嶇涓変竷浜屽崄涓浜嗭紝鍏堝惂EAX鍋氫簡鍐嶈錛屾妸涓婇潰閭d釜榛戜綋鐨?br />inc eax 鏀規垚nop錛堝懙鍛碉紝nop鏄ぇ瀹剁殑鏈鐖?鏈哄櫒鐮佹槸90浜?榪欐槸鏀硅繃鐨勪簡)
淇濆瓨鍒版枃浠躲?br />澶у姛鍛婃垚鍝堬紒錛?
韜負鑿滈笩錛岃兘鍙栧緱榪欐牱鐨勭粨鏋滐紝鐪熸槸璁╀漢鍏村錛岃阿璋㈠悇浣嶉槄璇伙紝榪樿鍚勪綅楂樻墜涓嶅悵璧愭暀銆?br />涓嬭澆瀹夎紼嬪簭鍙婄牬瑙?/a>
鍦ㄤ竴涓嬌鐢║NICODE鐨勫伐紼嬮噷浣跨敤log4cplus 1.0.3搴擄紝鍙戠幇鎬繪槸鍙戠敓閾炬帴閿欒銆傜寽鎯沖彲鑳芥槸log4cplus闇瑕佸湪UNICODE涓嬬紪璇戯紝鍩轟簬Debug鍜孯elease涓や釜澶嶅埗浜哢nicode Debug/Release閰嶇疆錛屽紑濮嬬紪璇戔?UniRelease寰堝鏄撻氳繃浜嗙紪璇戯紝浣嗘槸UniDebug鍗存繪槸鍙戠敓閾炬帴閿欒錛屼絾鏄嚱鏁拌偗瀹氬凡緇忓疄鐜頒簡錛屽皢閾炬帴閿欒鍙戠敓鐨勬枃浠禔ppender.obj鏂囦歡鎵撳紑錛岀劧鍚庢瘮杈冪紪璇戝櫒閲屾姤鍑虹殑淇℃伅
涓涓槸
鑰岄摼寮忓櫒鎵句笉鍒扮殑絎﹀彿鏄細
榪欎袱涓鍙烽兘寰堟櫐娑╋紝寰堥毦璁╀漢鎼炴槑鐧戒粈涔堟剰鎬濓紝鏀劇嫍涓鎼滐紝榪樼湡鏈夊伐鍏峰彨undname.exe錛屽湪VC7.1閲岃嚜甯︼紝
Undecoration of :- "?error@OnlyOnceErrorHandler@log4cplus@@UAEXABV?$basic_string
@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z"
is :- "public: virtual void __thiscall log4cplus::OnlyOnceErrorHandler::error(cl
ass std::basic_string<unsigned short,struct std::char_traits<unsigned short>,cla
ss std::allocator<unsigned short> > const &)"
Undecoration of :- "?error@OnlyOnceErrorHandler@log4cplus@@UAEXABV?$basic_string
@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z"
is :- "public: virtual void __thiscall log4cplus::OnlyOnceErrorHandler::error(cl
ass std::basic_string<char,struct std::char_traits<char>,class std::allocator<ch
ar> > const &)"
涓瀵規瘮錛屽氨鐭ラ亾鍙兘榪樻槸UNICODE鐨勫師鍥狅紝浠旂粏媯鏌++棰勫鐞嗙鍙瘋緗紝鍙戠幇濂藉閮借繕鏄疢CBS錛屼慨鏀癸紝閲嶆柊緙栬瘧錛岄棶棰樿В鍐熾?
鏈枃鍋囧畾鎮ㄧ啛鎮?Win32銆丆++ 鍜屽綰跨▼澶勭悊銆?
涓嬭澆鏈枃鐨勪唬鐮侊細CriticalSections.exe (415KB)
鎽樿
涓寸晫鍖烘槸涓縐嶉槻姝㈠涓嚎紼嬪悓鏃舵墽琛屼竴涓壒瀹氫唬鐮佽妭鐨勬満鍒訛紝榪欎竴涓婚騫舵病鏈夊紩璧峰お澶氬叧娉紝鍥犺屼漢浠湭鑳藉鍏舵繁鍒葷悊瑙c傚湪闇瑕佽窡韙唬鐮佷腑鐨勫綰跨▼澶勭悊鐨勬ц兘鏃訛紝瀵?Windows 涓復鐣屽尯鐨勬繁鍒葷悊瑙i潪甯告湁鐢ㄣ?鏈枃娣卞叆鐮旂┒涓寸晫鍖虹殑鍘熺悊錛屼互鎻ず鍦ㄦ煡鎵炬閿佸拰紜鎬ц兘闂榪囩▼涓殑鏈夌敤淇℃伅銆傚畠榪樺寘鍚竴涓究鍒╃殑瀹炵敤宸ュ叿紼嬪簭錛屽彲浠ユ樉紺烘墍鏈変復鐣屽尯鍙婂叾褰撳墠鐘舵併?
鍦ㄦ垜浠澶氬勾鐨勭紪紼嬪疄璺典腑錛屽浜?Win32廬 涓寸晫鍖烘病鏈夊彈鍒伴潪甯稿鐨勨渦nder the hood鈥濆叧娉ㄨ屾劅鍒伴潪甯稿鎬傚綋鐒訛紝鎮ㄥ彲鑳戒簡瑙f湁鍏充復鐣屽尯鍒濆鍖栦笌浣跨敤鐨勫熀紜鐭ヨ瘑錛屼絾鎮ㄦ槸鍚︽浘緇忚姳璐規椂闂存潵娣卞叆鐮旂┒ WINNT.H 涓墍瀹氫箟鐨?CRITICAL_SECTION 緇撴瀯鍛紵鍦ㄨ繖涓緇撴瀯涓湁涓浜涢潪甯告湁鎰忎箟鐨勫ソ涓滆タ琚暱鏈熷拷鐣ャ傛垜浠皢瀵規榪涜琛ュ厖錛屽茍鍚戞偍浠嬬粛涓浜涘緢鏈夋剰涔夌殑鎶宸э紝榪欎簺鎶宸у浜庤窡韙偅浜涢毦浠ュ療瑙夌殑澶氱嚎紼嬪鐞嗛敊璇潪甯告湁鐢ㄣ傛洿閲嶈鐨勬槸錛屼嬌鐢ㄦ垜浠殑 MyCriticalSections 瀹炵敤宸ュ叿錛屽彲浠ユ槑鐧藉浣曞 CRITICAL_SECTION 榪涜寰皬鍦版墿灞曪紝浠ユ彁渚涢潪甯告湁鐢ㄧ殑鐗規э紝榪欎簺鐗規у彲鐢ㄤ簬璋冭瘯鍜屾ц兘璋冩暣錛堣涓嬭澆瀹屾暣浠g爜錛屽弬瑙佹湰鏂囬《閮ㄧ殑閾炬帴錛夈?
鑰佸疄璇達紝浣滆呬滑緇忓父蹇界暐 CRITICAL_SECTION 緇撴瀯鐨勯儴鍒嗗師鍥犲湪浜庡畠鍦ㄤ互涓嬩袱涓富瑕?Win32 浠g爜搴撲腑鐨勫疄鐜版湁寰堝ぇ涓嶅悓錛歁icrosoft廬 Windows廬 95 鍜?Windows NT廬銆備漢浠煡閬撹繖涓ょ浠g爜搴撻兘宸茬粡鍙戝睍鍑哄ぇ閲忓悗緇増鏈紙鍏舵渶鏂扮増鏈垎鍒負 Windows Me 鍜?Windows XP錛夛紝浣嗘病鏈夊繀瑕佸湪姝ゅ灝嗗叾涓涓鍒楀嚭銆傚叧閿湪浜?Windows XP 鐜板湪宸茬粡鍙戝睍寰楅潪甯稿畬鍠勶紝寮鍙戝晢鍙兘寰堝揩灝變細鍋滄瀵?Windows 95 緋誨垪鎿嶄綔緋葷粺鐨勬敮鎸併傛垜浠湪鏈枃涓氨鏄繖涔堝仛鐨勩?
璇氱劧錛屽綋浠婃渶鍙楀叧娉ㄧ殑鏄?Microsoft .NET Framework錛屼絾鏄壇濂界殑鏃у紡 Win32 緙栫▼涓嶄細寰堝揩娑堝け銆傚鏋滄偍鎷ユ湁閲囩敤浜嗕復鐣屽尯鐨勭幇鏈?Win32 浠g爜錛屾偍浼氬彂鐜版垜浠殑宸ュ叿浠ュ強瀵逛復鐣屽尯鐨勮鏄庨兘闈炲父鏈夌敤銆備絾鏄娉ㄦ剰錛屾垜浠彧璁ㄨ Windows NT 鍙婂叾鍚庣畫鐗堟湰錛岃屾病鏈夋秹鍙婁笌 .NET 鐩稿叧鐨勪換浣曞唴瀹癸紝榪欎竴鐐歸潪甯擱噸瑕併?
涓寸晫鍖猴細綆榪?
濡傛灉鎮ㄩ潪甯哥啛鎮変復鐣屽尯錛屽茍鍙互涓嶅亣鎬濈儲鍦拌繘琛屽簲鐢紝閭e氨鍙互鐣ヨ繃鏈妭銆傚惁鍒欙紝璇峰悜涓嬮槄璇伙紝浠ュ榪欎簺鍐呭榪涜蹇熷洖欏俱傚鏋滄偍涓嶇啛鎮夎繖浜涘熀紜鍐呭錛屽垯鏈妭涔嬪悗鐨勫唴瀹瑰氨娌℃湁澶ぇ鎰忎箟銆?
涓寸晫鍖烘槸涓縐嶈交閲忕駭鏈哄埗錛屽湪鏌愪竴鏃墮棿鍐呭彧鍏佽涓涓嚎紼嬫墽琛屾煇涓粰瀹氫唬鐮佹銆傞氬父鍦ㄤ慨鏀瑰叏灞鏁版嵁錛堝闆嗗悎綾伙級鏃朵細浣跨敤涓寸晫鍖恒備簨浠躲佸鐢ㄦ埛緇堢鎵ц紼嬪簭鍜屼俊鍙烽噺涔熺敤浜庡綰跨▼鍚屾錛屼絾涓寸晫鍖轟笌瀹冧滑涓嶅悓錛屽畠騫朵笉鎬繪槸鎵ц鍚戝唴鏍告ā寮忕殑鎺у埗杞崲錛岃繖涓杞崲鎴愭湰鏄傝吹銆傜◢鍚庡皢浼氱湅鍒幫紝瑕佽幏寰椾竴涓湭鍗犵敤涓寸晫鍖猴紝浜嬪疄涓婂彧闇瑕佸鍐呭瓨鍋氬嚭寰堝皯鐨勪慨鏀癸紝鍏墮熷害闈炲父蹇傚彧鏈夊湪灝濊瘯鑾峰緱宸插崰鐢ㄤ復鐣屽尯鏃訛紝瀹冩墠浼氳煩鑷沖唴鏍告ā寮忋傝繖涓杞婚噺綰х壒鎬х殑緙虹偣鍦ㄤ簬涓寸晫鍖哄彧鑳界敤浜庡鍚屼竴榪涚▼鍐呯殑綰跨▼榪涜鍚屾銆?
涓寸晫鍖虹敱 WINNT.H 涓墍瀹氫箟鐨?RTL_CRITICAL_SECTION 緇撴瀯琛ㄧず銆傚洜涓烘偍鐨?C++ 浠g爜閫氬父澹版槑涓涓?CRITICAL_SECTION 綾誨瀷鐨勫彉閲忥紝鎵浠ユ偍鍙兘瀵規騫朵笉浜嗚В銆傜爺絀?WINBASE.H 鍚庢偍浼氬彂鐜幫細
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
鎴戜滑灝嗗湪鐭椂闂村唴鎻ず RTL_CRITICAL_SECTION 緇撴瀯鐨勫疄璐ㄣ傛鏃訛紝閲嶈闂鍦ㄤ簬 CRITICAL_SECTION錛堜篃縐頒綔 RTL_CRITICAL_SECTION錛夊彧鏄竴涓嫢鏈夋槗璁塊棶瀛楁鐨勭粨鏋勶紝榪欎簺瀛楁鍙互鐢?KERNEL32 API 鎿嶄綔銆?
鍦ㄥ皢涓寸晫鍖轟紶閫掔粰 InitializeCriticalSection 鏃訛紙鎴栬呮洿鍑嗙‘鍦拌錛屾槸鍦ㄤ紶閫掑叾鍦板潃鏃訛級錛屼復鐣屽尯鍗沖紑濮嬪瓨鍦ㄣ傚垵濮嬪寲涔嬪悗錛屼唬鐮佸嵆灝嗕復鐣屽尯浼犻掔粰 EnterCriticalSection 鍜?LeaveCriticalSection API銆備竴涓嚎紼嬭嚜 EnterCriticalSection 涓繑鍥炲悗錛屾墍鏈夊叾浠栬皟鐢?EnterCriticalSection 鐨勭嚎紼嬮兘灝嗚闃繪錛岀洿鍒扮涓涓嚎紼嬭皟鐢?LeaveCriticalSection 涓烘銆傛渶鍚庯紝褰撲笉鍐嶉渶瑕佽涓寸晫鍖烘椂錛屼竴縐嶈壇濂界殑緙栫爜涔犳儻鏄皢鍏朵紶閫掔粰 DeleteCriticalSection銆?
鍦ㄤ復鐣屽尯鏈浣跨敤鐨勭悊鎯蟲儏鍐典腑錛屽 EnterCriticalSection 鐨勮皟鐢ㄩ潪甯稿揩閫燂紝鍥犱負瀹冨彧鏄鍙栧拰淇敼鐢ㄦ埛妯″紡鍐呭瓨涓殑鍐呭瓨浣嶇疆銆傚惁鍒欙紙鍦ㄥ悗鏂囧皢浼氶亣鍒頒竴縐嶄緥澶栨儏鍐碉級錛岄樆姝簬涓寸晫鍖虹殑綰跨▼鏈夋晥鍦板畬鎴愯繖涓宸ヤ綔錛岃屼笉闇瑕佹秷鑰楅澶栫殑 CPU 鍛ㄦ湡銆傛墍闃繪鐨勭嚎紼嬩互鍐呮牳妯″紡絳夊緟錛屽湪璇ヤ復鐣屽尯鐨勬墍鏈夎呭皢鍏墮噴鏀句箣鍓嶏紝涓嶈兘瀵硅繖浜涚嚎紼嬭繘琛岃皟搴︺傚鏋滄湁澶氫釜綰跨▼琚樆姝簬涓涓復鐣屽尯涓紝褰撳彟涓綰跨▼閲婃斁璇ヤ復鐣屽尯鏃訛紝鍙湁涓涓嚎紼嬭幏寰楄涓寸晫鍖恒?
娣卞叆鐮旂┒錛歊TL_CRITICAL_SECTION 緇撴瀯
鍗充嬌鎮ㄥ凡緇忓湪鏃ュ父宸ヤ綔涓嬌鐢ㄨ繃涓寸晫鍖猴紝鎮ㄤ篃闈炲父鍙兘騫舵病鏈夌湡姝d簡瑙h秴鍑烘枃妗d箣澶栫殑鍐呭銆備簨瀹炰笂瀛樺湪鐫寰堝闈炲父瀹規槗鎺屾彙鐨勫唴瀹廣備緥濡傦紝浜轟滑寰堝皯鐭ラ亾涓涓繘紼嬬殑涓寸晫鍖烘槸淇濆瓨浜庝竴涓摼琛ㄤ腑錛屽茍涓斿彲浠ュ鍏惰繘琛屾灇涓俱傚疄闄呬笂錛學INDBG 鏀寔 !locks 鍛戒護錛岃繖涓鍛戒護鍙互鍒楀嚭鐩爣榪涚▼涓殑鎵鏈変復鐣屽尯銆傛垜浠◢鍚庡皢瑕佽皥鍒扮殑瀹炵敤宸ュ叿涔熷簲鐢ㄤ簡涓寸晫鍖鴻繖涓椴滀負浜虹煡鐨勭壒寰併備負浜嗙湡姝g悊瑙h繖涓瀹炵敤宸ュ叿濡備綍宸ヤ綔錛屾湁蹇呰鐪熸鎺屾彙涓寸晫鍖虹殑鍐呴儴緇撴瀯銆傝鐫榪欎竴鐐癸紝鐜板湪寮濮嬬爺絀?RTL_CRITICAL_SECTION 緇撴瀯銆備負鏂逛究璧瘋錛屽皢姝ょ粨鏋勫垪鍑哄涓嬶細
struct RTL_CRITICAL_SECTION
{
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
ULONG_PTR SpinCount;
};
浠ヤ笅鍚勬瀵規瘡涓瓧孌佃繘琛岃鏄庛?
DebugInfo 姝ゅ瓧孌靛寘鍚竴涓寚閽堬紝鎸囧悜緋葷粺鍒嗛厤鐨勪即闅忕粨鏋勶紝璇ョ粨鏋勭殑綾誨瀷涓?RTL_CRITICAL_SECTION_DEBUG銆傝繖涓緇撴瀯涓寘鍚洿澶氭瀬鏈変環鍊肩殑淇℃伅錛屼篃瀹氫箟浜?WINNT.H 涓傛垜浠◢鍚庡皢瀵瑰叾榪涜鏇存繁鍏ュ湴鐮旂┒銆?
LockCount 榪欐槸涓寸晫鍖轟腑鏈閲嶈鐨勪竴涓瓧孌點傚畠琚垵濮嬪寲涓烘暟鍊?-1錛涙鏁板肩瓑浜庢垨澶т簬 0 鏃訛紝琛ㄧず姝や復鐣屽尯琚崰鐢ㄣ傚綋鍏朵笉絳変簬 -1 鏃訛紝OwningThread 瀛楁錛堟瀛楁琚敊璇湴瀹氫箟浜?WINNT.H 涓?鈥?搴斿綋鏄?DWORD 鑰屼笉鏄?HANDLE錛夊寘鍚簡鎷ユ湁姝や復鐣屽尯鐨勭嚎紼?ID銆傛瀛楁涓?(RecursionCount -1) 鏁板間箣闂寸殑宸艱〃紺烘湁澶氬皯涓叾浠栫嚎紼嬪湪絳夊緟鑾峰緱璇ヤ復鐣屽尯銆?
RecursionCount 姝ゅ瓧孌靛寘鍚墍鏈夎呯嚎紼嬪凡緇忚幏寰楄涓寸晫鍖虹殑嬈℃暟銆傚鏋滆鏁板間負闆訛紝涓嬩竴涓皾璇曡幏鍙栬涓寸晫鍖虹殑綰跨▼灝嗕細鎴愬姛銆?
OwningThread 姝ゅ瓧孌靛寘鍚綋鍓嶅崰鐢ㄦ涓寸晫鍖虹殑綰跨▼鐨勭嚎紼嬫爣璇嗙銆傛綰跨▼ ID 涓?GetCurrentThreadId 涔嬬被鐨?API 鎵榪斿洖鐨?ID 鐩稿悓銆?
LockSemaphore 姝ゅ瓧孌電殑鍛藉悕涓嶆伆褰擄紝瀹冨疄闄呬笂鏄竴涓嚜澶嶄綅浜嬩歡錛岃屼笉鏄竴涓俊鍙楓傚畠鏄竴涓唴鏍稿璞″彞鏌勶紝鐢ㄤ簬閫氱煡鎿嶄綔緋葷粺錛氳涓寸晫鍖虹幇鍦ㄧ┖闂層傛搷浣滅郴緇熷湪涓涓嚎紼嬬涓嬈″皾璇曡幏寰楄涓寸晫鍖猴紝浣嗚鍙︿竴涓凡緇忔嫢鏈夎涓寸晫鍖虹殑綰跨▼鎵闃繪鏃訛紝鑷姩鍒涘緩榪欐牱涓涓彞鏌勩傚簲褰撹皟鐢?DeleteCriticalSection錛堝畠灝嗗彂鍑轟竴涓皟鐢ㄨ浜嬩歡鐨?CloseHandle 璋冪敤錛屽茍鍦ㄥ繀瑕佹椂閲婃斁璇ヨ皟璇曠粨鏋勶級錛屽惁鍒欏皢浼氬彂鐢熻祫婧愭硠婕忋?
SpinCount 浠呯敤浜庡澶勭悊鍣ㄧ郴緇熴侻SDN廬 鏂囨。瀵規瀛楁榪涜濡備笅璇存槑錛氣滃湪澶氬鐞嗗櫒緋葷粺涓紝濡傛灉璇ヤ復鐣屽尯涓嶅彲鐢紝璋冪敤綰跨▼灝嗗湪瀵逛笌璇ヤ復鐣屽尯鐩稿叧鐨勪俊鍙鋒墽琛岀瓑寰呮搷浣滀箣鍓嶏紝鏃嬭漿 dwSpinCount 嬈°傚鏋滆涓寸晫鍖哄湪鏃嬭漿鎿嶄綔鏈熼棿鍙樹負鍙敤錛岃璋冪敤綰跨▼灝遍伩鍏嶄簡絳夊緟鎿嶄綔銆傗濇棆杞鏁板彲浠ュ湪澶氬鐞嗗櫒璁$畻鏈轟笂鎻愪緵鏇翠匠鎬ц兘錛屽叾鍘熷洜鍦ㄤ簬鍦ㄤ竴涓驚鐜腑鏃嬭漿閫氬父瑕佸揩浜庤繘鍏ュ唴鏍告ā寮忕瓑寰呯姸鎬併傛瀛楁榛樿鍊間負闆訛紝浣嗗彲浠ョ敤 InitializeCriticalSectionAndSpinCount API 灝嗗叾璁劇疆涓轟竴涓笉鍚屽箋?
RTL_CRITICAL_SECTION_DEBUG 緇撴瀯
鍓嶉潰鎴戜滑娉ㄦ剰鍒幫紝鍦?RTL_CRITICAL_SECTION 緇撴瀯鍐咃紝DebugInfo 瀛楁鎸囧悜涓涓?RTL_CRITICAL_SECTION_DEBUG 緇撴瀯錛岃緇撴瀯緇欏嚭濡備笅錛?
struct _RTL_CRITICAL_SECTION_DEBUG
{
WORD Type;
WORD CreatorBackTraceIndex;
RTL_CRITICAL_SECTION *CriticalSection;
LIST_ENTRY ProcessLocksList;
DWORD EntryCount;
DWORD ContentionCount;
DWORD Spare[ 2 ];
}
榪欎竴緇撴瀯鐢?InitializeCriticalSection 鍒嗛厤鍜屽垵濮嬪寲銆傚畠鏃㈠彲浠ョ敱 NTDLL 鍐呯殑棰勫垎閰嶆暟緇勫垎閰嶏紝涔熷彲浠ョ敱榪涚▼鍫嗗垎閰嶃俁TL_CRITICAL_SECTION 鐨勮繖涓浼撮殢緇撴瀯鍖呭惈涓緇勫尮閰嶅瓧孌碉紝鍏鋒湁榪ョ劧涓嶅悓鐨勮鑹詫細鏈変袱涓毦浠ョ悊瑙o紝闅忓悗涓や釜鎻愪緵浜嗙悊瑙h繖涓涓寸晫鍖洪摼緇撴瀯鐨勫叧閿紝涓や釜鏄噸澶嶈緗殑錛屾渶鍚庝袱涓湭浣跨敤銆?
涓嬮潰鏄 RTL_CRITICAL_SECTION 瀛楁鐨勮鏄庛?
Type 姝ゅ瓧孌墊湭浣跨敤錛岃鍒濆鍖栦負鏁板?0銆?
CreatorBackTraceIndex 姝ゅ瓧孌典粎鐢ㄤ簬璇婃柇鎯呭艦涓傚湪娉ㄥ唽琛ㄩ」 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\YourProgram 涔嬩笅鏄?keyfield銆丟lobalFlag 鍜?StackTraceDatabaseSizeInMb 鍊箋傛敞鎰忥紝鍙湁鍦ㄨ繍琛岀◢鍚庤鏄庣殑 Gflags 鍛戒護鏃舵墠浼氭樉紺鴻繖浜涘箋傝繖浜涙敞鍐岃〃鍊肩殑璁劇疆姝g‘鏃訛紝CreatorBackTraceIndex 瀛楁灝嗙敱鍫嗘爤璺熻釜涓墍鐢ㄧ殑涓涓儲寮曞煎~鍏呫傚湪 MSDN 涓悳绱?GFlags 鏂囨。涓殑鐭鈥渃reate user mode stack trace database鈥濆拰鈥渆nlarging the user-mode stack trace database鈥濓紝鍙互鎵懼埌鏈夊叧榪欎竴鍐呭鐨勬洿澶氫俊鎭?
CriticalSection 鎸囧悜涓庢緇撴瀯鐩稿叧鐨?RTL_CRITICAL_SECTION銆?strong>鍥?1 璇存槑璇ュ熀紜緇撴瀯浠ュ強 RTL_CRITICAL_SECTION銆丷TL_CRITICAL_SECTION_DEBUG 鍜屼簨浠墮摼涓叾浠栧弬涓庤呬箣闂寸殑鍏崇郴銆?
鍥?1 涓寸晫鍖哄鐞嗘祦紼?/strong>
ProcessLocksList LIST_ENTRY 鏄敤浜庤〃紺哄弻鍚戦摼琛ㄤ腑鑺傜偣鐨勬爣鍑?Windows 鏁版嵁緇撴瀯銆俁TL_CRITICAL_SECTION_DEBUG 鍖呭惈浜嗛摼琛ㄧ殑涓閮ㄥ垎錛屽厑璁稿悜鍓嶅拰鍚戝悗閬嶅巻璇ヤ復鐣屽尯銆傛湰鏂囧悗闈㈢粰鍑虹殑瀹炵敤宸ュ叿璇存槑濡備綍浣跨敤 Flink錛堝墠鍚戦摼鎺ワ級鍜?Blink錛堝悗鍚戦摼鎺ワ級瀛楁鍦ㄩ摼琛ㄤ腑鐨勬垚鍛樹箣闂寸Щ鍔ㄣ備換浣曚粠浜嬭繃璁懼椹卞姩紼嬪簭鎴栬呯爺絀惰繃 Windows 鍐呮牳鐨勪漢閮戒細闈炲父鐔熸倝榪欎竴鏁版嵁緇撴瀯銆?
EntryCount/ContentionCount 榪欎簺瀛楁鍦ㄧ浉鍚岀殑鏃墮棿銆佸嚭浜庣浉鍚岀殑鍘熷洜琚掑銆傝繖鏄偅浜涘洜涓轟笉鑳介┈涓婅幏寰椾復鐣屽尯鑰岃繘鍏ョ瓑寰呯姸鎬佺殑綰跨▼鐨勬暟鐩備笌 LockCount 鍜?RecursionCount 瀛楁涓嶅悓錛岃繖浜涘瓧孌墊案榪滈兘涓嶄細閫掑噺銆?
Spares 榪欎袱涓瓧孌墊湭浣跨敤錛岀敋鑷蟲湭琚垵濮嬪寲錛堝敖綆″湪鍒犻櫎涓寸晫鍖虹粨鏋勬椂灝嗚繖浜涘瓧孌佃繘琛屼簡娓呴浂錛夈傚悗闈㈠皢浼氳鏄庯紝鍙互鐢ㄨ繖浜涙湭琚嬌鐢ㄧ殑瀛楁鏉ヤ繚瀛樻湁鐢ㄧ殑璇婃柇鍊箋?
鍗充嬌 RTL_CRITICAL_SECTION_DEBUG 涓寘鍚涓瓧孌碉紝瀹冧篃鏄父瑙勪復鐣屽尯緇撴瀯鐨勫繀瑕佹垚鍒嗐備簨瀹炰笂錛屽鏋滅郴緇熸伆宸т笉鑳界敱榪涚▼鍫嗕腑鑾峰緱榪欎竴緇撴瀯鐨勫瓨鍌ㄥ尯錛孖nitializeCriticalSection 灝嗚繑鍥炰負 STATUS_NO_MEMORY 鐨?LastError 緇撴灉錛岀劧鍚庤繑鍥炲浜庝笉瀹屾暣鐘舵佺殑涓寸晫鍖虹粨鏋勩?
涓寸晫鍖虹姸鎬?
褰撶▼搴忔墽琛屻佽繘鍏ヤ笌紱誨紑涓寸晫鍖烘椂錛孯TL_CRITICAL_SECTION 鍜?RTL_CRITICAL_SECTION_DEBUG 緇撴瀯涓殑瀛楁浼氭牴鎹復鐣屽尯鎵澶勭殑鐘舵佸彉鍖栥傝繖浜涘瓧孌電敱涓寸晫鍖?API 涓殑綈胯浠g爜鏇存柊錛屽湪鍚庨潰灝嗕細鐪嬪埌榪欎竴鐐廣傚鏋滅▼搴忎負澶氱嚎紼嬶紝騫朵笖鍏剁嚎紼嬭闂槸鐢變復鐣屽尯淇濇姢鐨勫叕鐢ㄨ祫婧愶紝鍒欒繖浜涚姸鎬佸氨鏇存湁鎰忎箟銆?
浣嗘槸錛屼笉綆′唬鐮佺殑綰跨▼浣跨敤鎯呭喌濡備綍錛屾湁涓ょ鐘舵侀兘浼氬嚭鐜般傜涓縐嶆儏鍐碉紝濡傛灉 LockCount 瀛楁鏈変竴涓笉絳変簬 -1 鐨勬暟鍊鹼紝姝や復鐣屽尯琚崰鐢紝OwningThread 瀛楁鍖呭惈鎷ユ湁璇ヤ復鐣屽尯鐨勭嚎紼嬬殑綰跨▼鏍囪瘑絎︺傚湪澶氱嚎紼嬬▼搴忎腑錛孡ockCount 涓?RecursionCount 鑱斿悎琛ㄦ槑褰撳墠鏈夊灝戠嚎紼嬭闃繪浜庤涓寸晫鍖恒傜浜岀鎯呭喌錛屽鏋?RecursionCount 鏄竴涓ぇ浜?1 鐨勬暟鍊鹼紝鍏跺憡鐭ユ偍鎵鏈夎呯嚎紼嬪凡緇忛噸鏂拌幏寰楄涓寸晫鍖哄灝戞錛堜篃璁鎬笉蹇呰錛夛紝璇ヤ復鐣屽尯鏃㈠彲浠ラ氳繃璋冪敤 EnterCriticalSection銆佷篃鍙互閫氳繃璋冪敤 TryEnterCriticalSection 鑾峰緱銆傚ぇ浜?1 鐨勪換浣曟暟鍊奸兘琛ㄧず浠g爜鐨勬晥鐜囧彲鑳借緝浣庢垨鑰呭彲鑳藉湪浠ュ悗鍙戠敓閿欒銆備緥濡傦紝璁塊棶鍏叡璧勬簮鐨勪換浣?C++ 綾繪柟娉曞彲鑳戒細涓嶅繀瑕佸湴閲嶆柊榪涘叆璇ヤ復鐣屽尯銆?
娉ㄦ剰錛屽湪澶у鏁版椂闂撮噷錛孡ockCount 涓?RecursionCount 瀛楁涓垎鍒寘鍚叾鍒濆鍊?-1 鍜?0錛岃繖涓鐐歸潪甯擱噸瑕併備簨瀹炰笂錛屽浜庡崟綰跨▼紼嬪簭錛屼笉鑳戒粎閫氳繃媯鏌ヨ繖浜涘瓧孌墊潵鍒ゆ柇鏄惁鏇捐幏寰楄繃涓寸晫鍖恒備絾鏄紝澶氱嚎紼嬬▼搴忕暀涓嬩簡涓浜涙爣璁幫紝鍙互鐢ㄦ潵鍒ゆ柇鏄惁鏈変袱涓垨澶氫釜綰跨▼璇曞浘鍚屾椂鎷ユ湁鍚屼竴涓寸晫鍖恒?
鎮ㄥ彲浠ユ壘鍒扮殑鏍囪涔嬩竴鏄嵆浣垮湪璇ヤ復鐣屽尯鏈鍗犵敤鏃?LockSemaphore 瀛楁涓粛鍖呭惈涓涓潪闆跺箋傝繖琛ㄧず錛氬湪鏌愪竴鏃墮棿錛屾涓寸晫鍖洪樆姝簡涓涓垨澶氫釜綰跨▼ 鈥?浜嬩歡鍙ユ焺鐢ㄤ簬閫氱煡璇ヤ復鐣屽尯宸茶閲婃斁錛岀瓑寰呰涓寸晫鍖虹殑綰跨▼涔嬩竴鐜板湪鍙互鑾峰緱璇ヤ復鐣屽尯騫剁戶緇墽琛屻傚洜涓?OS 鍦ㄤ復鐣屽尯闃繪鍙︿竴涓嚎紼嬫椂鑷姩鍒嗛厤浜嬩歡鍙ユ焺錛屾墍浠ュ鏋滄偍鍦ㄤ笉鍐嶉渶瑕佷復鐣屽尯鏃跺繕璁板皢鍏跺垹闄わ紝LockSemaphore 瀛楁鍙兘浼氬鑷寸▼搴忎腑鍙戠敓璧勬簮娉勬紡銆?
鍦ㄥ綰跨▼紼嬪簭涓彲鑳介亣鍒扮殑鍙︿竴鐘舵佹槸 EntryCount 鍜?ContentionCount 瀛楁鍖呭惈涓涓ぇ浜庨浂鐨勬暟鍊箋傝繖涓や釜瀛楁淇濆瓨鏈変復鐣屽尯瀵逛竴涓嚎紼嬭繘琛岄樆姝㈢殑嬈℃暟銆傚湪姣忔鍙戠敓榪欎竴浜嬩歡鏃訛紝榪欎袱涓瓧孌佃閫掑錛屼絾鍦ㄤ復鐣屽尯瀛樺湪鏈熼棿涓嶄細琚掑噺銆傝繖浜涘瓧孌靛彲鐢ㄤ簬闂存帴紜畾紼嬪簭鐨勬墽琛岃礬寰勫拰鐗規с備緥濡傦紝EntryCount 闈炲父楂樻椂鍒欐剰鍛崇潃璇ヤ復鐣屽尯緇忓巻鐫澶ч噺浜夌敤錛屽彲鑳戒細鎴愪負浠g爜鎵ц榪囩▼涓殑涓涓綔鍦ㄧ摱棰堛?
鍦ㄧ爺絀朵竴涓閿佺▼搴忔椂錛岃繕浼氬彂鐜頒竴縐嶄技涔庢棤娉曡繘琛岄昏緫瑙i噴鐨勭姸鎬併備竴涓嬌鐢ㄩ潪甯擱綣佺殑涓寸晫鍖虹殑 LockCount 瀛楁涓寘鍚竴涓ぇ浜?-1 鐨勬暟鍊鹼紝涔熷氨鏄瀹冭綰跨▼鎵鎷ユ湁錛屼絾鏄?OwningThread 瀛楁涓洪浂錛堣繖鏍峰氨鏃犳硶鎵懼嚭鏄摢涓嚎紼嬪鑷撮棶棰橈級銆傛祴璇曠▼搴忔槸澶氱嚎紼嬬殑錛屽湪鍗曞鐞嗗櫒璁$畻鏈哄拰澶氬鐞嗗櫒璁$畻鏈轟腑閮戒細鍑虹幇榪欑鎯呭喌銆傚敖綆?LockCount 鍜屽叾浠栧煎湪姣忔榪愯涓兘涓嶅悓錛屼絾姝ょ▼搴忔繪槸姝婚攣浜庡悓涓涓寸晫鍖恒傛垜浠潪甯稿笇鏈涚煡閬撴槸鍚︽湁浠諱綍鍏朵粬寮鍙戜漢鍛樹篃閬囧埌浜嗗鑷磋繖涓鐘舵佺殑 API 璋冪敤搴忓垪銆?
鏋勫緩涓涓洿濂界殑鎹曢紶鍣?
鍦ㄦ垜浠涔犱復鐣屽尯鐨勫伐浣滄柟寮忔椂錛岄潪甯稿伓鐒跺湴寰楀埌涓浜涢噸瑕佸彂鐜幫紝鍒╃敤榪欎簺鍙戠幇鍙互寰楀埌涓涓潪甯稿ソ鐨勫疄鐢ㄥ伐鍏楓傜涓涓彂鐜版槸 ProcessLocksList LIST_ENTRY 瀛楁鐨勫嚭鐜幫紝榪欎嬌鎴戜滑鎯沖埌榪涚▼鐨勪復鐣屽尯鍙兘鏄彲鏋氫婦鐨勩傚彟涓涓噸澶у彂鐜版槸鎴戜滑鐭ラ亾浜嗗浣曟壘鍑轟復鐣屽尯鍒楄〃鐨勫ご銆傝繕鏈変竴涓噸瑕佸彂鐜版槸鍙互鍦ㄦ病鏈変換浣曟崯澶辯殑鎯呭喌涓嬪啓 RTL_CRITICAL_SECTION 鐨?Spare 瀛楁錛堣嚦灝戝湪鎴戜滑鐨勬墍鏈夋祴璇曚腑濡傛錛夈傛垜浠繕鍙戠幇鍙互寰堝鏄撳湴閲嶅啓緋葷粺鐨勪竴浜涗復鐣屽尯渚嬬▼錛岃屼笉闇瑕佸婧愭枃浠惰繘琛屼換浣曚慨鏀廣?
鏈鍒濓紝鎴戜滑鐢變竴涓畝鍗曠殑紼嬪簭寮濮嬶紝鍏舵鏌ヤ竴涓繘紼嬩腑鐨勬墍鏈変復鐣屽尯錛屽茍鍒楀嚭鍏跺綋鍓嶇姸鎬侊紝浠ユ煡鐪嬫槸鍚︽嫢鏈夎繖浜涗復鐣屽尯銆傚鏋滄嫢鏈夛紝鍒欐壘鍑虹敱鍝釜綰跨▼鎷ユ湁錛屼互鍙婅涓寸晫鍖洪樆姝簡澶氬皯涓嚎紼嬶紵榪欑鍋氭硶瀵逛簬 OS 鐨勭媯鐑呬滑姣旇緝閫傚悎錛屼絾瀵逛簬鍙槸甯屾湜鏈夊姪浜庣悊瑙e叾紼嬪簭鐨勫吀鍨嬬殑紼嬪簭鍛樺氨涓嶆槸闈炲父鏈夌敤浜嗐?
鍗充嬌鏄湪鏈綆鍗曠殑鎺у埗鍙版ā寮忊淗ello World鈥濈▼搴忎腑涔熷瓨鍦ㄨ澶氫復鐣屽尯銆傚叾涓ぇ閮ㄥ垎鏄敱 USER32 鎴?GDI32 涔嬬被鐨勭郴緇?DLL 鍒涘緩錛岃岃繖浜?DLL 寰堝皯浼氬鑷存閿佹垨鎬ц兘闂銆傛垜浠笇鏈涙湁涓縐嶆柟娉曡兘婊ら櫎榪欎簺涓寸晫鍖猴紝鑰屽彧鐣欎笅浠g爜涓墍鍏沖績鐨勯偅浜涗復鐣屽尯銆俁TL_CRITICAL_SECTION_DEBUG 緇撴瀯涓殑 Spare 瀛楁鍙互寰堝ソ鍦板畬鎴愯繖涓宸ヤ綔銆傚彲浠ヤ嬌鐢ㄥ叾涓殑涓涓垨涓や釜鏉ユ寚紺猴細榪欎簺涓寸晫鍖烘槸鏉ヨ嚜鐢ㄦ埛緙栧啓鐨勪唬鐮侊紝鑰屼笉鏄潵鑷?OS銆?
浜庢槸錛屼笅涓涓昏緫闂灝卞彉涓哄浣曠‘瀹氬摢浜涗復鐣屽尯鏄潵鑷偍緙栧啓鐨勪唬鐮併傛湁浜涜鑰呭彲鑳借繕璁板緱 Matt Pietrek 2001 騫?1 鏈堢殑 Under The Hood 涓撴爮涓殑 LIBCTINY.LIB銆侺IBCTINY 鎵閲囩敤鐨勪竴涓妧宸ф槸涓涓?LIB 鏂囦歡錛屽畠閲嶅啓浜嗗叧閿?Visual C++ 榪愯鏃朵緥紼嬬殑鏍囧噯瀹炵幇銆傚皢 LIBCTINY.LIB 鏂囦歡緗簬閾炬帴鍣ㄨ鐨勫叾浠?LIB 涔嬪墠錛岄摼鎺ュ櫒灝嗕嬌鐢ㄨ繖涓瀹炵幇錛岃屼笉鏄嬌鐢?Microsoft 鎵鎻愪緵鐨勫鍏ュ簱涓殑鍚屽悕鍚庣畫鐗堟湰銆?
涓哄涓寸晫鍖哄簲鐢ㄧ被浼兼妧宸э紝鎴戜滑鍒涘緩 InitializeCriticalSection 鐨勪竴涓浛浠g増鏈強鍏剁浉鍏沖鍏ュ簱銆傚皢姝?LIB 鏂囦歡緗簬 KERNEL32.LIB 涔嬪墠錛岄摼鎺ュ櫒灝嗛摼鎺ユ垜浠殑鐗堟湰錛岃屼笉鏄?KERNEL32 涓殑鐗堟湰銆傚 InitializeCriticalSection 鐨勫疄鐜版樉紺哄湪鍥?2 涓傛浠g爜鍦ㄦ蹇典笂闈炲父綆鍗曘傚畠棣栧厛璋冪敤 KERNEL32.DLL 涓殑瀹為檯 InitializeCriticalSection銆傛帴涓嬫潵錛屽畠鑾峰緱璋冪敤 InitializeCriticalSection 鐨勪唬鐮佸湴鍧錛屽茍灝嗗叾璐磋嚦 RTL_CRITICAL_SECTION_DEBUG 緇撴瀯鐨勫鐢ㄥ瓧孌典箣涓銆傛垜浠殑浠g爜濡備綍紜畾璋冪敤浠g爜鐨勫湴鍧鍛紵x86 CALL 鎸囦護灝嗚繑鍥炲湴鍧緗簬鍫嗘爤涓侰riticalSectionHelper 浠g爜鐭ラ亾璇ヨ繑鍥炲湴鍧浣嶄簬鍫嗘爤甯т腑涓涓凡鐭ョ殑鍥哄畾浣嶇疆銆?
瀹為檯緇撴灉鏄細涓?CriticalSectionHelper.lib 姝g‘閾炬帴鐨勪換浣?EXE 鎴?DLL 閮藉皢瀵煎叆鎴戜滑鐨?DLL (CriticalSectionHelper.DLL)錛屽茍鍗犵敤搴旂敤浜嗗鐢ㄥ瓧孌電殑涓寸晫鍖恒傝繖鏍峰氨浣夸簨鎯呯畝鍗曚簡璁稿銆傜幇鍦ㄦ垜浠殑瀹炵敤宸ュ叿鍙互綆鍗曞湴閬嶅巻榪涚▼涓殑鎵鏈変復鐣屽尯錛屽茍涓斿彧鏄劇ず鍏鋒湁姝g‘濉厖鐨勫鐢ㄥ瓧孌電殑涓寸晫鍖轟俊鎭傞偅涔堥渶瑕佷負榪欎竴瀹炵敤宸ュ叿浠樺嚭浠涔堜唬浠峰憿錛熻紼嶇瓑錛岃繕鏈夋洿澶氱殑鍐呭錛?
鍥犱負鎮ㄧ殑鎵鏈変復鐣屽尯鐜板湪閮藉寘鍚鍏惰繘琛屽垵濮嬪寲鏃剁殑鍦板潃錛屽疄鐢ㄥ伐鍏峰彲浠ラ氳繃鎻愪緵鍏跺垵濮嬪寲鍦板潃鏉ヨ瘑鍒悇涓復鐣屽尯銆傚師濮嬩唬鐮佸湴鍧鏈韓娌℃湁閭d箞鏈夌敤銆傚垢榪愮殑鏄紝DBGHELP.DLL 浣夸唬鐮佸湴鍧鍚戞簮鏂囦歡銆佽鍙峰拰鍑芥暟鍚嶇О鐨勮漿鎹㈠彉寰楅潪甯稿鏄撱傚嵆浣夸竴涓復鐣屽尯涓病鏈夋偍鍦ㄥ叾涓殑絳懼悕錛屼篃鍙互灝嗗叾鍦板潃鎻愪氦緇?DBGHELP.DLL銆傚鏋滃皢鍏跺0鏄庝負涓涓叏灞鍙橀噺錛屽茍涓斿鏋滅鍙峰彲鐢紝鍒欐偍灝卞彲浠ュ湪鍘熷婧愪唬鐮佷腑紜畾涓寸晫鍖虹殑鍚嶇О銆傞『渚胯鏄庝竴涓嬶紝濡傛灉閫氳繃璁劇疆 _NT_SYMBOL_PATH 鐜鍙橀噺錛屽茍璁劇疆 DbgHelp 浠ヤ嬌鐢ㄥ叾 Symbol Server 涓嬭澆鍔熻兘錛屼粠鑰屼嬌 DbgHelp 鍙戞尌鍏舵晥鐢紝鍒欎細寰楀埌闈炲父濂界殑緇撴灉銆?
MyCriticalSections 瀹炵敤宸ュ叿
鎴戜滑灝嗘墍鏈夎繖浜涙濇兂緇撳悎璧鋒潵錛屾彁鍑轟簡 MyCriticalSections 紼嬪簭銆侻yCriticalSections 鏄竴涓懡浠よ紼嬪簭錛屽湪涓嶄嬌鐢ㄥ弬鏁拌繍琛岃紼嬪簭鏃跺彲浠ョ湅鍒頒竴浜涢夐」錛? 鍞竴闇瑕佺殑鍙傛暟鏄?Program ID 鎴?PID錛堝崄榪涘埗褰㈠紡錛夈傚彲浠ョ敤澶氱鏂規硶鑾峰緱 PID錛屼絾鏈綆鍗曠殑鏂規硶鍙兘灝辨槸閫氳繃 Task Manager銆傚湪娌℃湁鍏朵粬閫夐」鏃訛紝MyCriticalSections 鍒楀嚭浜嗘潵鑷唬鐮佹ā鍧楃殑鎵鏈変復鐣屽尯鐘舵侊紝鎮ㄥ凡緇忓皢 CriticalSectionHelper.DLL 閾炬帴鑷寵繖浜涗唬鐮佹ā鍧椼傚鏋滄湁鍙敤浜庤繖涓錛堜簺錛夋ā鍧楃殑絎﹀彿錛屼唬鐮佸皢灝濊瘯鎻愪緵璇ヤ復鐣屽尯鐨勫悕縐幫紝浠ュ強瀵瑰叾榪涜鍒濆鍖栫殑浣嶇疆銆?
瑕佹煡鐪?MyCriticalSections 鏄浣曡搗浣滅敤鐨勶紝璇瘋繍琛?Demo.EXE 紼嬪簭錛岃紼嬪簭鍖呭惈鍦ㄤ笅杞芥枃浠朵腑銆侱emo.EXE 鍙槸鍒濆鍖栦袱涓復鐣屽尯錛屽茍鐢變竴瀵圭嚎紼嬭繘鍏ヨ繖涓や釜涓寸晫鍖恒?a >鍥?3 鏄劇ず榪愯鈥淢yCriticalSections 2040鈥濈殑緇撴灉錛堝叾涓?2040 涓?Demo.EXE 鐨?PID錛夈?
鍦ㄨ鍥句腑錛屽垪鍑轟簡涓や釜涓寸晫鍖恒傚湪鏈緥涓紝瀹冧滑琚懡鍚嶄負 csMain 鍜?yetAnotherCriticalSection銆傛瘡涓淎ddress:鈥濊鏄劇ず浜?CRITICAL_SECTION 鐨勫湴鍧鍙婂叾鍚嶇О銆傗淚nitialized in鈥濊鍖呭惈浜嗗湪鍏朵腑鍒濆鍖?CRITICAL_SECTION 鐨勫嚱鏁板悕銆備唬鐮佺殑鈥淚nitialized at鈥濊鏄劇ず浜嗘簮鏂囦歡鍜屽垵濮嬪寲鍑芥暟涓殑琛屽彿銆?
瀵逛簬 csMain 涓寸晫鍖猴紝鎮ㄥ皢鐪嬪埌閿佸畾鏁頒負 0銆侀掑綊鏁頒負 1錛岃〃紺轟竴涓凡緇忚涓綰跨▼鑾峰緱鐨勪復鐣屽尯錛屽茍涓旀病鏈夊叾浠栫嚎紼嬪湪絳夊緟璇ヤ復鐣屽尯銆傚洜涓轟粠鏉ユ病鏈夌嚎紼嬭闃繪浜庤涓寸晫鍖猴紝鎵浠?Entry Count 瀛楁涓?0銆?
鐜板湪鏉ョ湅 yetAnotherCriticalSection錛屼細鍙戠幇鍏墮掑綊鏁頒負 3銆傚揩閫熸祻瑙?Demo 浠g爜鍙互鐪嬪嚭錛氫富綰跨▼璋冪敤 EnterCriticalSection 涓夋錛屾墍浠ヤ簨鎯呯殑鍙戠敓涓庨鏈熶竴鑷淬備絾鏄紝榪樻湁涓涓浜岀嚎紼嬭瘯鍥捐幏寰楄涓寸晫鍖猴紝騫朵笖宸茬粡琚樆姝€傚悓鏍鳳紝LockCount 瀛楁涔熶負 3銆傛杈撳嚭鏄劇ず鏈変竴涓瓑寰呯嚎紼嬨?
MyCriticalSections 鎷ユ湁涓浜涢夐」錛屼嬌鍏跺浜庢洿涓哄媷鏁㈢殑鎺㈢儲鑰呴潪甯告湁鐢ㄣ?v 寮鍏蟲樉紺烘瘡涓復鐣屽尯鐨勬洿澶氫俊鎭傛棆杞暟涓庨攣瀹氫俊鍙峰瓧孌靛挨涓洪噸瑕併傛偍緇忓父浼氱湅鍒?NTDLL 鍜屽叾浠?DLL 鎷ユ湁涓浜涙棆杞暟闈為浂鐨勪復鐣屽尯銆傚鏋滀竴涓嚎紼嬪湪鑾峰緱涓寸晫鍖虹殑榪囩▼涓浘琚攣瀹氾紝鍒欓攣瀹氫俊鍙峰瓧孌典負闈為浂鍊箋?v 寮鍏寵繕鏄劇ず浜?RTL_CRITICAL_SECTION_DEBUG 緇撴瀯涓鐢ㄥ瓧孌電殑鍐呭銆?
/a 寮鍏蟲樉紺鴻繘紼嬩腑鐨勬墍鏈変復鐣屽尯錛屽嵆浣垮叾涓病鏈?CriticalSectionHelper.DLL 絳懼悕涔熶細鏄劇ず銆傚鏋滀嬌鐢?/a錛屽垯璇峰仛濂芥湁澶ч噺杈撳嚭鐨勫噯澶囥傜湡姝g殑榛戝甯屾湜鍚屾椂浣跨敤 /a 鍜?/v錛屼互鏄劇ず榪涚▼涓叏閮ㄥ唴瀹圭殑鏈澶氱粏鑺傘備嬌鐢?/a 鐨勪竴涓皬灝忕殑濂藉鏄細鐪嬪埌 NTDLL 涓殑LdrpLoaderLock 涓寸晫鍖恒傛涓寸晫鍖哄湪 DllMain 璋冪敤鍜屽叾浠栦竴浜涢噸瑕佹椂闂村唴琚崰鐢ㄣ侺drpLoaderLock 鏄澶氫笉澶槑鏄俱佽〃闈笂闅句互瑙i噴鐨勬閿佺殑褰㈡垚鍘熷洜涔嬩竴銆傦紙涓轟嬌 MyCriticalSection 鑳藉姝g‘鏍囪 LdrpLoaderLock 瀹炰緥錛岄渶瑕佺敤浜?NTDLL 鐨?PDB 鏂囦歡鍙緵浣跨敤銆傦級
/e 寮鍏充嬌紼嬪簭浠呮樉紺哄綋鍓嶈鍗犵敤鐨勪復鐣屽尯銆傛湭浣跨敤 /a 寮鍏蟲椂錛屽彧鏄劇ず浠g爜涓鍗犵敤鐨勪復鐣屽尯錛堝澶囩敤瀛楁涓殑絳懼悕鎵鎸囩ず錛夈傞噰鐢?/a 寮鍏蟲椂錛屽皢鏄劇ず榪涚▼涓殑鍏ㄩ儴琚崰鐢ㄤ復鐣屽尯錛岃屼笉鑰冭檻鍏舵潵婧愩?
閭d箞錛屽笇鏈涗粈涔堟椂鍊欒繍琛?MyCriticalSections 鍛紵涓涓緢鏄庣‘鐨勬椂闂存槸鍦ㄧ▼搴忚姝婚攣鏃躲傛鏌ヨ鍗犵敤鐨勪復鐣屽尯錛屼互鏌ョ湅鏄惁鏈変粈涔堜嬌鎮ㄦ儕璁剁殑浜嬫儏銆傚嵆浣胯姝婚攣鐨勭▼搴忔榪愯浜庤皟璇曞櫒鐨勬帶鍒朵箣涓嬶紝涔熷彲浠ヤ嬌鐢?MyCriticalSections銆?
鍙︿竴縐嶄嬌鐢?MyCriticalSections 鐨勬椂鏈烘槸鍦ㄥ鏈夊ぇ閲忓綰跨▼鐨勭▼搴忚繘琛屾ц兘璋冩暣鏃躲傚湪闃誨浜庤皟璇曞櫒涓殑涓涓嬌鐢ㄩ綣併侀潪閲嶅叆鍑芥暟鏃訛紝榪愯 MyCriticalSections錛屾煡鐪嬪湪璇ユ椂鍒誨崰鐢ㄤ簡鍝簺涓寸晫鍖恒傚鏋滄湁寰堝綰跨▼閮芥墽琛岀浉鍚屼換鍔★紝灝遍潪甯稿鏄撳鑷翠竴縐嶆儏褰細涓涓嚎紼嬬殑澶ч儴鍒嗘椂闂磋娑堣楀湪絳夊緟鑾峰緱涓涓嬌鐢ㄩ綣佺殑涓寸晫鍖轟笂銆傚鏋滄湁澶氫釜浣跨敤棰戠箒鐨勪復鐣屽尯錛岃繖閫犳垚鐨勫悗鏋滃氨鍍忚姳鍥殑嫻囨按杞鎵撲簡緇撲竴鏍楓傝В鍐充竴涓簤鐢ㄩ棶棰樺彧鏄皢闂杞Щ鍒頒笅涓涓鏄撻犳垚闃誨鐨勪復鐣屽尯銆?
涓涓煡鐪嬪摢浜涗復鐣屽尯鏈瀹規槗瀵艱嚧浜夌敤鐨勫ソ鏂規硶鏄湪鎺ヨ繎紼嬪簭緇撳熬澶勮緗竴涓柇鐐廣傚湪閬囧埌鏂偣鏃訛紝榪愯 MyCriticalSections 騫舵煡鎵懼叿鏈夋渶澶?Entry Count 鍊肩殑涓寸晫鍖恒傛鏄繖浜涗復鐣屽尯瀵艱嚧浜嗗ぇ澶氭暟闃誨鍜岀嚎紼嬭漿鎹€?
灝界 MyCriticalSections 榪愯浜?Windows 2000 鍙婃洿鏂扮増鏈紝浣嗘偍浠嶉渶瑕佷竴涓瘮杈冩柊鐨?DbgHelp.DLL 鐗堟湰 錛?5.1 鐗堟垨鏇存柊鐗堟湰銆俉indows XP 涓彁渚涜繖涓鐗堟湰銆備篃鍙互鐢卞叾浠栦嬌鐢?DbgHelp 鐨勫伐鍏蜂腑鑾峰緱璇ョ増鏈備緥濡傦紝Debugging Tools For Windows 涓嬭澆涓氬父鎷ユ湁鏈鏂扮殑 DbgHelp.DLL銆?
娣卞叆鐮旂┒閲嶈鐨勪復鐣屽尯渚嬬▼
姝ゆ渶鍚庝竴鑺傛槸涓洪偅浜涘笇鏈涚悊瑙d復鐣屽尯瀹炵幇鍐呭箷鐨勫媷鏁㈣鑰呮彁渚涚殑銆傚 NTDLL 榪涜浠旂粏鐮旂┒鍚庡彲浠ヤ負榪欎簺渚嬬▼鍙婂叾鏀寔瀛愪緥紼嬪垱寤轟吉鐮侊紙瑙佷笅杞戒腑鐨?NTDLL(CriticalSections).cpp錛夈備互涓?KERNEL32 API 緇勬垚涓寸晫鍖虹殑鍏叡鎺ュ彛錛? 鍓嶄袱涓?API 鍙槸鍒嗗埆鍥寸粫 NTDLL API RtlInitializeCriticalSection 鍜?RtlInitializeCriticalSectionAndSpinCount 鐨勭槮鍖呰銆傛墍鏈夊墿浣欎緥紼嬮兘琚彁浜ょ粰 NTDLL 涓殑鍑芥暟銆傚彟澶栵紝瀵?RtlInitializeCriticalSection 鐨勮皟鐢ㄦ槸鍙︿竴涓洿緇?RtlInitializeCriticalSectionAndSpinCount 璋冪敤鐨勭槮鍖呰錛屽叾鏃嬭漿鏁扮殑鍊間負 0銆備嬌鐢ㄤ復鐣屽尯鐨勬椂鍊欏疄闄呬笂鏄湪騫曞悗浣跨敤浠ヤ笅 NTDLL API錛? 鍦ㄨ繖涓璁ㄨ涓紝鎴戜滑閲囩敤 Kernel32 鍚嶇О錛屽洜涓哄ぇ澶氭暟 Win32 紼嬪簭鍛樺瀹冧滑鏇翠負鐔熸倝銆?
InitializeCriticalSectionAndSpinCount 瀵逛復鐣屽尯鐨勫垵濮嬪寲闈炲父綆鍗曘俁TL_CRITICAL_SECTION 緇撴瀯涓殑瀛楁琚祴浜堝叾璧峰鍊箋備笌姝ょ被浼鹼紝鍒嗛厤 RTL_CRITICAL_SECTION_DEBUG 緇撴瀯騫跺鍏惰繘琛屽垵濮嬪寲錛屽皢 RtlLogStackBackTraces 璋冪敤涓殑榪斿洖鍊艱祴浜?CreatorBackTraceIndex錛屽茍寤虹珛鍒板墠闈復鐣屽尯鐨勯摼鎺ャ?
欏轟究璇翠竴澹幫紝CreatorBackTraceIndex 涓鑸帴鏀跺埌鐨勫間負 0銆備絾鏄紝濡傛灉鏈?Gflags 鍜?Umdh 瀹炵敤宸ュ叿錛屽彲浠ヨ緭鍏ヤ互涓嬪懡浠わ細 榪欎簺鍛戒護浣垮緱 MyProgram 鐨勨淚mage File Execution Options鈥濅笅娣誨姞浜嗘敞鍐岃〃欏廣傚湪涓嬩竴嬈℃墽琛?MyProgram 鏃朵細鐪嬪埌姝ゅ瓧孌墊帴鏀跺埌涓涓潪 0 鏁板箋傛湁鍏蟲洿澶氫俊鎭紝鍙傞槄鐭ヨ瘑搴撴枃绔?Q268343鈥?a >Umdhtools.exe:How to Use Umdh.exe to Find Memory Leaks鈥濄備復鐣屽尯鍒濆鍖栦腑鍙︿竴涓渶瑕佹敞鎰忕殑闂鏄細鍓?64 涓?RTL_CRITICAL_SECTION_DEBUG 緇撴瀯涓嶆槸鐢辮繘紼嬪爢涓垎閰嶏紝鑰屾槸鏉ヨ嚜浣嶄簬 NTDLL 鍐呯殑 .data 鑺傜殑涓涓暟緇勩?
鍦ㄥ畬鎴愪復鐣屽尯鐨勪嬌鐢ㄤ箣鍚庯紝瀵?DeleteCriticalSection錛堝叾鍛藉悕涓嶅綋錛屽洜涓哄畠鍙垹闄?RTL_CRITICAL_SECTION_ DEBUG錛夌殑璋冪敤閬嶅巻涓涓悓鏍峰彲鐞嗚В鐨勮礬寰勩傚鏋滅敱浜庣嚎紼嬪湪灝濊瘯鑾峰緱涓寸晫鍖烘椂琚樆姝㈣屽垱寤轟簡涓涓簨浠訛紝灝嗛氳繃璋冪敤 ZwClose 鏉ラ攢姣佽浜嬩歡銆傛帴涓嬫潵錛屽湪閫氳繃 RtlCriticalSectionLock 鑾峰緱淇濇姢涔嬪悗錛圢TDLL 浠ヤ竴涓復鐣屽尯淇濇姢瀹冭嚜宸辯殑鍐呴儴涓寸晫鍖哄垪琛?鈥?鎮ㄧ寽瀵逛簡錛夛紝灝嗚皟璇曚俊鎭粠閾句腑娓呴櫎錛屽璇ヤ復鐣屽尯閾捐〃榪涜鏇存柊錛屼互鍙嶆槧瀵硅淇℃伅鐨勬竻闄ゆ搷浣溿傝鍐呭瓨鐢辯┖鍊煎~鍏咃紝騫朵笖濡傛灉鍏跺瓨鍌ㄥ尯鏄敱榪涚▼鍫嗕腑鑾峰緱錛屽垯璋冪敤 RtlFreeHeap 灝嗕嬌寰楀叾鍐呭瓨琚噴鏀俱傛渶鍚庯紝浠ラ浂濉厖 RTL_CRITICAL_SECTION銆?
鏈変袱涓?API 瑕佽幏寰楀彈涓寸晫鍖轟繚鎶ょ殑璧勬簮 鈥?TryEnterCriticalSection 鍜?EnterCriticalSection銆傚鏋滀竴涓嚎紼嬮渶瑕佽繘鍏ヤ竴涓復鐣屽尯錛屼絾鍦ㄧ瓑寰呰闃繪璧勬簮鍙樹負鍙敤鐨勫悓鏃訛紝鍙墽琛屾湁鐢ㄧ殑宸ヤ綔錛岄偅涔?TryEnterCriticalSection 姝f槸鎮ㄩ渶瑕佺殑 API銆傛渚嬬▼嫻嬭瘯姝や復鐣屽尯鏄惁鍙敤錛涘鏋滆涓寸晫鍖鴻鍗犵敤錛岃浠g爜灝嗚繑鍥炲?FALSE錛屼負璇ョ嚎紼嬫彁渚涚戶緇墽琛屽彟涓浠誨姟鐨勬満浼氥傚惁鍒欙紝鍏朵綔鐢ㄥ彧鏄浉褰撲簬 EnterCriticalSection銆?
濡傛灉璇ョ嚎紼嬪湪緇х畫榪涜涔嬪墠紜疄闇瑕佹嫢鏈夎璧勬簮錛屽垯浣跨敤 EnterCriticalSection銆傛鏃訛紝鍙栨秷鐢ㄤ簬澶氬鐞嗗櫒璁$畻鏈虹殑 SpinCount 嫻嬭瘯銆傝繖涓渚嬬▼涓?TryEnterCriticalSection 綾諱技錛屾棤璁鴻涓寸晫鍖烘槸絀洪棽鐨勬垨宸茬粡琚綰跨▼鎵鎷ユ湁錛岄兘璋冩暣瀵硅涓寸晫鍖虹殑綈胯銆傛敞鎰忥紝鏈閲嶈鐨?LockCount 閫掑鏄敱 x86鈥渓ock鈥濆墠緙瀹屾垚鐨勶紝榪欎竴鐐歸潪甯擱噸瑕併傝繖紜繚浜嗗湪鏌愪竴鏃墮棿鍐呭彧鏈変竴涓?CPU 鍙互淇敼璇?LockCount 瀛楁銆傦紙浜嬪疄涓婏紝Win32 InterlockedIncrement API 鍙槸涓涓叿鏈夌浉鍚岄攣瀹氬墠緙鐨?ADD 鎸囦護銆傦級
濡傛灉璋冪敤綰跨▼鏃犳硶绔嬪嵆鑾峰緱璇ヤ復鐣屽尯錛屽垯璋冪敤 RtlpWaitForCriticalSection 灝嗚綰跨▼緗簬絳夊緟鐘舵併傚湪澶氬鐞嗗櫒緋葷粺涓紝EnterCriticalSection 鏃嬭漿 SpinCount 鎵鎸囧畾鐨勬鏁幫紝騫跺湪姣忔寰幆璁塊棶涓祴璇曡涓寸晫鍖虹殑鍙敤鎬с傚鏋滄涓寸晫鍖哄湪寰幆鏈熼棿鍙樹負絀洪棽錛岃綰跨▼鑾峰緱璇ヤ復鐣屽尯錛屽茍緇х畫鎵ц銆?
RtlpWaitForCriticalSection 鍙兘鏄繖閲屾墍緇欑殑鎵鏈夎繃紼嬩腑鏈涓哄鏉傘佹渶涓洪噸瑕佺殑涓涓傝繖騫朵笉鍊煎緱澶ф儕灝忔紝鍥犱負濡傛灉瀛樺湪涓涓閿佸茍娑夊強涓寸晫鍖猴紝鍒欏埄鐢ㄨ皟璇曞櫒榪涘叆璇ヨ繘紼嬪氨鍙兘鏄劇ず鍑?RtlpWaitForCriticalSection 鍐?ZwWaitForSingleObject 璋冪敤涓殑鑷沖皯涓涓嚎紼嬨?
濡備吉鐮佷腑鎵鏄劇ず錛屽湪 RtlpWaitForCriticalSection 涓湁涓鐐圭翱璁板伐浣滐紝濡傞掑 EntryCount 鍜?ContentionCount 瀛楁銆備絾鏇撮噸瑕佺殑鏄細鍙戝嚭瀵?LockSemaphore 鐨勭瓑寰咃紝浠ュ強瀵圭瓑寰呯粨鏋滅殑澶勭悊銆傞粯璁ゆ儏鍐墊槸灝嗕竴涓┖鎸囬拡浣滀負絎笁涓弬鏁頒紶閫掔粰 ZwWaitForSingleObject 璋冪敤錛岃姹傝絳夊緟姘歌繙涓嶈瓚呮椂銆傚鏋滃厑璁歌秴鏃訛紝灝嗙敓鎴愯皟璇曟秷鎭瓧絎︿覆錛屽茍鍐嶆寮濮嬬瓑寰呫傚鏋滀笉鑳戒粠絳夊緟涓垚鍔熻繑鍥烇紝灝變細浜х敓涓璇ヨ繘紼嬬殑閿欒銆傛渶鍚庯紝鍦ㄤ粠 ZwWaitForSingleObject 璋冪敤涓垚鍔熻繑鍥炴椂錛屽垯鎵ц浠?RtlpWaitForCriticalSection 榪斿洖錛岃綰跨▼鐜板湪鎷ユ湁璇ヤ復鐣屽尯銆?
RtlpWaitForCriticalSection 蹇呴』璁よ瘑鍒扮殑涓涓復鐣屾潯浠舵槸璇ヨ繘紼嬫鍦ㄨ鍏抽棴錛屽茍涓旀鍦ㄧ瓑寰呭姞杞界▼搴忛攣瀹?(LdrpLoaderLock) 涓寸晫鍖恒俁tlpWaitForCriticalSection 涓瀹?em>涓嶈兘 鍏佽璇ョ嚎紼嬭闃繪錛屼絾鏄繀欏昏煩榪囪絳夊緟錛屽茍鍏佽緇х畫榪涜鍏抽棴鎿嶄綔銆?
LeaveCriticalSection 涓嶅儚 EnterCriticalSection 閭f牱澶嶆潅銆傚鏋滃湪閫掑噺 RecursionCount 涔嬪悗錛岀粨鏋滀笉涓?0錛堟剰鍛崇潃璇ョ嚎紼嬩粛鐒舵嫢鏈夎涓寸晫鍖猴級錛屽垯璇ヤ緥紼嬪皢浠?ERROR_SUCCESS 鐘舵佽繑鍥炪傝繖灝辨槸涓轟粈涔堥渶瑕佺敤閫傚綋鏁扮洰鐨?Leave 璋冪敤鏉ュ鉤琛?Enter 璋冪敤銆傚鏋滆璁℃暟涓?0錛屽垯 OwningThread 瀛楁琚竻闆訛紝LockCount 琚掑噺銆傚鏋滆繕鏈夊叾浠栫嚎紼嬪湪絳夊緟錛屼緥濡?LockCount 澶т簬鎴栫瓑浜?0錛屽垯璋冪敤 RtlpUnWaitCriticalSection銆傛甯姪鍣ㄤ緥紼嬪垱寤?LockSemaphore錛堝鏋滃叾灝氭湭瀛樺湪錛夛紝騫跺彂鍑鴻淇″彿鎻愰啋鎿嶄綔緋葷粺錛氳綰跨▼宸茬粡閲婃斁璇ヤ復鐣屽尯銆備綔涓洪氱煡鐨勪竴閮ㄥ垎錛岀瓑寰呯嚎紼嬩箣涓閫鍑虹瓑寰呯姸鎬侊紝涓鴻繍琛屽仛濂藉噯澶囥?
鏈鍚庤璇存槑鐨勪竴鐐規槸錛孧yCriticalSections 紼嬪簭濡備綍紜畾涓寸晫鍖洪摼鐨勮搗濮嬪憿錛熷鏋滄湁鏉冭闂?NTDLL 鐨勬紜皟璇曠鍙鳳紝鍒欏璇ュ垪琛ㄧ殑鏌ユ壘鍜岄亶鍘嗛潪甯哥畝鍗曘傞鍏堬紝瀹氫綅絎﹀彿 RtlCriticalSectionList錛屾竻絀哄叾鍐呭錛堝畠鎸囧悜絎竴涓?RTL_CRITICAL_SECTION_DEBUG 緇撴瀯錛夛紝騫跺紑濮嬮亶鍘嗐備絾鏄紝騫朵笉鏄墍鏈夌殑緋葷粺閮芥湁璋冭瘯絎﹀彿錛孯tlCriticalSectionList 鍙橀噺鐨勫湴鍧浼氶殢 Windows 鐨勫悇涓増鏈屽彂鐢熷彉鍖栥備負浜嗘彁渚涗竴縐嶅鎵鏈夌増鏈兘鑳芥甯稿伐浣滅殑瑙e喅鏂規錛屾垜浠璁′簡浠ヤ笅璇曟帰鎬ф柟妗堛傝瀵熷惎鍔ㄤ竴涓繘紼嬫椂鎵閲囧彇鐨勬楠わ紝浼氱湅鍒版槸浠ヤ互涓嬮『搴忓 NTDLL 涓殑涓寸晫鍖鴻繘琛屽垵濮嬪寲鐨勶紙榪欎簺鍚嶇О鍙栬嚜 NTDLL 鐨勮皟璇曠鍙鳳級錛? 鍥犱負媯鏌ヨ繘紼嬬幆澧冨潡 (PEB) 涓亸縐婚噺 0xA0 澶勭殑鍦板潃灝卞彲浠ユ壘鍒板姞杞界▼搴忛攣錛屾墍浠ュ璇ラ摼璧峰浣嶇疆鐨勫畾浣嶅氨鍙樺緱姣旇緝綆鍗曘傛垜浠鍙栨湁鍏沖姞杞界▼搴忛攣鐨勮皟璇曚俊鎭紝鐒跺悗娌跨潃閾懼悜鍚庨亶鍘嗕袱涓摼鎺ワ紝浣挎垜浠畾浣嶄簬 RtlCriticalSectionLock 欏癸紝鍦ㄨ鐐瑰緱鍒拌閾劇殑絎竴涓復鐣屽尯銆傛湁鍏沖叾鏂規硶鐨勮鏄庯紝璇峰弬瑙?strong>鍥?4Syntax: MyCriticalSections <PID> [options]
Options:
/a = all critical sections
/e = show only entered critical sections
/v = verbose
InitializeCriticalSection
InitializeCriticalSectionAndSpinCount
DeleteCriticalSection
TryEnterCriticalSection
EnterCriticalSection
LeaveCriticalSection
RtlInitializeCriticalSectionAndSpinCount
RtlEnterCriticalSection
RtlTryEnterCriticalSection
RtlLeaveCriticalSection
RtlDeleteCriticalSection
Gflags /i MyProgram.exe +ust
Gflags /i MyProgram.exe /tracedb 24
RtlCriticalSectionLock
DeferedCriticalSection (this is the actual spelling!)
LoaderLock
FastPebLock
RtlpCalloutEntryLock
PMCritSect
UMLogCritSect
RtlpProcessHeapsListLock
鍥?4 鍒濆鍖栭『搴?/strong>
灝忕粨
鍑犱箮鎵鏈夌殑澶氱嚎紼嬬▼搴忓潎浣跨敤涓寸晫鍖恒傛偍榪熸棭閮戒細閬囧埌涓涓嬌浠g爜姝婚攣鐨勪復鐣屽尯錛屽茍涓斾細闅句互紜畾鏄浣曡繘鍏ュ綋鍓嶇姸鎬佺殑銆傚鏋滆兘澶熸洿娣卞叆鍦頒簡瑙d復鐣屽尯鐨勫伐浣滃師鐞嗭紝鍒欒繖涓鎯呭艦鐨勫嚭鐜板氨涓嶄細鍍忛嬈″嚭鐜版椂閭f牱鐨勪護浜烘伯涓с傛偍鍙互鐮旂┒涓涓湅鏉ラ潪甯稿惈緋婄殑涓寸晫鍖猴紝騫剁‘瀹氭槸璋佹嫢鏈夊畠錛屼互鍙婂叾浠栨湁鐢ㄧ粏鑺傘傚鏋滄偍鎰挎剰灝嗘垜浠殑搴撳姞鍏ユ偍鐨勯摼鎺ュ櫒琛岋紝鍒欏彲浠ュ鏄撳湴鑾峰緱鏈夊叧鎮ㄧ▼搴忎復鐣屽尯浣跨敤鐨勫ぇ閲忎俊鎭傞氳繃鍒╃敤涓寸晫鍖虹粨鏋勪腑鐨勪竴浜涙湭鐢ㄥ瓧孌碉紝鎴戜滑鐨勪唬鐮佸彲浠ヤ粎闅旂騫跺懡鍚嶆偍鐨勬ā鍧楁墍鐢ㄧ殑涓寸晫鍖猴紝騫跺憡鐭ュ叾鍑嗙‘鐘舵併?
鏈夐瓌鍔涚殑璇昏呭彲浠ュ緢瀹規槗鍦板鎴戜滑鐨勪唬鐮佽繘琛屾墿灞曪紝浠ュ畬鎴愭洿涓哄紓涔庡甯哥殑宸ヤ綔銆備緥濡傦紝閲囩敤涓?InitializeCriticalSection 鎸傞挬鐩哥被浼肩殑鏂瑰紡鎴幏 EnterCriticalSection 鍜?LeaveCriticalSection錛屽彲浠ュ瓨鍌ㄦ渶鍚庝竴嬈℃垚鍔熻幏寰楀拰閲婃斁璇ヤ復鐣屽尯鐨勪綅緗備笌姝ょ被浼鹼紝CritSect DLL 鎷ユ湁涓涓槗浜庤皟鐢ㄧ殑 API錛岀敤浜庢灇涓炬偍鑷繁鐨勪唬鐮佷腑鐨勪復鐣屽尯銆傚埄鐢?.NET Framework 涓殑 Windows 紿椾綋錛屽彲浠ョ浉瀵瑰鏄撳湴鍒涘緩涓涓?GUI 鐗堟湰鐨?MyCriticalSections銆傚鎴戜滑浠g爜榪涜鎵╁睍鐨勫彲鑳芥ч潪甯稿ぇ錛屾垜浠潪甯鎬箰鎰忕湅鍒板叾浠栦漢鍛樻墍鍙戠幇鍜屽垱閫犵殑鍒涙柊鎬у姙娉曘?
鏈夊叧鏂囩珷錛岃鍙傞槄錛?/strong> Matt Pietrek 鏄竴浣嶈蔣浠舵灦鏋勫笀鍜屼綔鑰呫備粬灝辮亴浜?Compuware/NuMega 瀹為獙瀹わ紝韜喚涓?BoundsChecker 鍜屸滃垎甯冨紡鍒嗘瀽鍣ㄢ濅駭鍝佺殑棣栧腑鏋舵瀯甯堛備粬宸茬粡鍒涗綔浜嗕笁鏈湁鍏?Windows 緋葷粺緙栫▼鐨勪功綾嶏紝騫舵槸 MSDN Magazine 鐨勭壒綰︾紪杈戙備粬鐨?Web 绔欑偣 (http://www.wheaty.net) 鏈夊叧浜庝互鍓嶆枃绔犲拰涓撴爮鐨?FAQ 鍜屼俊鎭?
Jay Hilyard 鏄?Compuware/NuMega 瀹為獙瀹ょ殑 BoundsChecker 灝忕粍鐨勮蔣浠跺伐紼嬪笀銆備粬銆佷粬鐨勫瀛愬拰浠栦滑鐨勭尗鏄柊緗曞竷浠灝斿窞鐨勬柊灞呮皯銆備粬鐨勮仈緋繪柟寮忎負 RussOsterlund@adelphia.net 鎴?Web 绔欑偣 http://www.smidgeonsoft.com銆?
Global Flag Reference:Create kernel mode stack trace database
GFlags Examples:Enlarging the User-Mode Stack Trace Database
Under the Hood:Reduce EXE and DLL Size with LIBCTINY.LIB
http://support.microsoft.com/kb/313109/zh-cn
鏈〉
姒傝
娌℃湁寮傚父澶勭悊紼嬪簭瀹氫箟澶勭悊寮曞彂鐨勫紓甯告椂錛屽皢璋冪敤璇?UnhandledExceptionFilter 鍑芥暟銆?閫氬父錛岃鍑芥暟浼氬皢寮傚父浼犻掔粰鍦?Ntdll.dll 涓烘枃...
娌℃湁寮傚父澶勭悊紼嬪簭瀹氫箟澶勭悊寮曞彂鐨勫紓甯告椂錛屽皢璋冪敤璇?UnhandledExceptionFilter 鍑芥暟銆?閫氬父錛岃鍑芥暟浼氬皢寮傚父浼犻掔粰鍦?Ntdll.dll 涓烘枃浠跺叾涓崟鑾鳳紝騫跺皾璇曞鐞嗚緗?
鍦ㄨ繘紼嬬殑鍐呭瓨蹇収鎵鍦ㄦ煇浜涙儏鍐典笅錛屽彲浠ョ湅鍒伴攣瀹氱偣淇濆瓨鍒扮嚎紼嬬殑綰跨▼鐨勮皟鐢?UnhandledExceptionFilter 鍑芥暟銆?鍦ㄨ繖鐨勭鎯呭喌涓嬫偍鍙互鎸夌収鏈枃浠ョ‘瀹氬鑷存寮傚父鐨?DLL銆?
Microsoft 璋冭瘯宸ュ叿
http://www.microsoft.com/whdc/devtools/ddk/default.mspx (http://www.microsoft.com/whdc/devtools/ddk/default.mspx)
濡備綍鑾峰緱絎﹀彿
http://www.microsoft.com/whdc/devtools/ddk/default.mspx (http://www.microsoft.com/whdc/devtools/ddk/default.mspx)
120 id: f0f0f0f0.a1c Suspend: 1 Teb 7ff72000 Unfrozen
ChildEBP RetAddr Args to Child
09a8f334 77eb9b46 0000244c 00000001 00000000 ntdll!ZwWaitForSingleObject+0xb [i386\usrstubs.asm @ 2004]
09a8f644 77ea7e7a 09a8f66c 77e861ae 09a8f674 KERNEL32!UnhandledExceptionFilter+0x2b5
[D:\nt\private\windows\base\client\thread.c @ 1753]
09a8ffec 00000000 787bf0b8 0216fe94 00000000 KERNEL32!BaseThreadStart+0x65 [D:\nt\private\windows\base\client\support.c @ 453]
0:120> dd 09a8f66c
09a8f66c 09a8f738 09a8f754 09a8f698 77f8f45c
09a8f67c 09a8f738 09a8ffdc 09a8f754 09a8f710
09a8f68c 09a8ffdc 77f8f5b5 09a8ffdc 09a8f720
09a8f69c 77f8f3fa 09a8f738 09a8ffdc 09a8f754
09a8f6ac 09a8f710 77e8615b 09a8fad4 00000000
09a8f6bc 09a8f738 74a25336 09a8f6e0 09a8f910
09a8f6cc 01dc8ad8 0d788918 00000001 018d1f28
09a8f6dc 00000001 61746164 7073612e 09a8f71c
.exr first DWORD from step 6
0:120> .exr 09a8f738
ExceptionAddress: 78011f32 (MSVCRT!strnicmp+0x00000092)
ExceptionCode: c0000005
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000000
Attempt to read from address 00000000
.cxr second DWORD from step 6
0:120> .cxr 09a8f754
eax=027470ff ebx=7803cb28 ecx=00000000 edx=00000000 esi=00000000 edi=09a8fad4
eip=78011f32 esp=09a8fa20 ebp=09a8fa2c iopl=0 nv up ei ng nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010286
MSVCRT!strnicmp+92:
78011f32 8a06 mov al,[esi]
0:120> kv
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
09a8fa2c 780119ab 09a8fad4 00000000 09a8faa8 MSVCRT!strnicmp+0x92
09a8fa40 7801197c 09a8fad4 00000000 6d7044fd MSVCRT!stricmp+0x3c
09a8fa80 6e5a6ef6 09a8fad4 2193d68d 00e5e298 MSVCRT!stricmp+0xd
09a8fa94 6d7043bf 09a8fad4 09a8faa8 0000001c IisRTL!CLKRHashTable::FindKey+0x59 (FPO: [2,0,1])
09a8faac 749fc22d 09a8fad4 01d553b0 0000001c ISATQ!CDirMonitor::FindEntry+0x1e
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\infocomm\atq\dirmon.cpp @ 884]
09a8fac4 749fd1cb 09a8fad4 09a8fb10 525c3a46 asp!RegisterASPDirMonitorEntry+0x6e
(FPO: [EBP 0x09a8fb08] [2,0,4]) [D:\nt\private\inet\iis\svcs\cmp\asp\aspdmon.cpp @ 534]
09a8fb08 749fcdd6 00000000 09a8fcbc 018d1f28 asp!CTemplateCacheManager::RegisterTemplateForChangeNotification+0x8a
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\cmp\asp\cachemgr.cpp @ 621]
09a8fb3c 74a08bfe 00000000 000000fa 74a30958 asp!CTemplateCacheManager::Load+0x382
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\cmp\asp\cachemgr.cpp @ 364]
09a8fc68 74a0d4c9 04c12518 018d1f28 09a8fcbc asp!LoadTemplate+0x42
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\cmp\asp\exec.cpp @ 1037]
09a8fcc0 74a2c3e5 00000000 0637ee38 09a8fd58 asp!CHitObj::ViperAsyncCallback+0x3e8
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\cmp\asp\hitobj.cpp @ 2414]
09a8fcd8 787c048a 00000000 77aa1b03 01e91ed8 asp!CViperAsyncRequest::OnCall+0x3f
(FPO: [Non-Fpo]) [D:\nt\private\inet\iis\svcs\cmp\asp\viperint.cpp @ 194]
09a8fce0 77aa1b03 01e91ed8 77a536d8 00000000 COMSVCS!STAActivityWorkHelper+0xa
(FPO: [1,0,0])
09a8fd24 77aa1927 000752f8 000864dc 787c0480 ole32!EnterForCallback+0x6a
(FPO: [Non-Fpo]) [D:\nt\private\ole32\com\dcomrem\crossctx.cxx @ 1759]
09a8fe50 77aa17ea 000864dc 787c0480 01e91ed8 ole32!SwitchForCallback+0x12b
(FPO: [Non-Fpo]) [D:\nt\private\ole32\com\dcomrem\crossctx.cxx @ 1644]
09a8fe78 77aa60c1 000864dc 787c0480 01e91ed8 ole32!PerformCallback+0x50
(FPO: [Non-Fpo]) [D:\nt\private\ole32\com\dcomrem\crossctx.cxx @ 1559]
09a8fed4 77aa5fa6 04f2b4c0 787c0480 01e91ed8 ole32!CObjectContext::InternalContextCallback+0xf5
(FPO: [Non-Fpo]) [D:\nt\private\ole32\com\dcomrem\context.cxx @ 3866]
09a8fef4 787bd3c3 04f2b4c0 787c0480 01e91ed8 ole32!CObjectContext::DoCallback+0x1a
(FPO: [Non-Fpo]) [D:\nt\private\ole32\com\dcomrem\context.cxx @ 3746]
09a8ff24 787bf373 0216fb3c 00000007 09a8ffec COMSVCS!STAActivityWork::DoWork+0x73
(FPO: [0,4,2])
09a8ffb4 77e8758a 0216fe94 0216fb3c 00000007 COMSVCS!STAThread::STAThreadWorker+0x2bb
(FPO: [EBP 0x09a8ffec] [1,31,4])
09a8ffec 00000000 787bf0b8 0216fe94 00000000 KERNEL32!BaseThreadStart+0x52
(FPO: [Non-Fpo]) [D:\nt\private\windows\base\client\support.c @ 451]
#include <boost/date_time/posix_time/posix_time.hpp>
榪欎釜澶存枃浠訛紝灝辨嫑鏉ヤ簡涓鍫嗙殑闂
鎻愮ず閾炬帴閿欒錛?/p>
鏂囦歡libboost_date_time-vc71-mt-sgd-1_37.lib鎵句笉鍒?/p>
鐒跺悗灝卞紑濮嬩簡婕暱鐨刡oost搴撶紪璇戙?/p>
浣嗘槸緙栬瘧瀹屼簡錛屾彁紺鴻繕鏄壘涓嶅埌錛屾垜鏅曘傛煡浜嗘煡sgd鐨勬剰鎬?/p>
s:浠h〃static
gd:浠h〃璋冭瘯鐗?/p>
璁╁簲鐢ㄧ▼搴忓叏灞忔樉紺哄叾瀹炴濊礬寰堢畝鍗曪細
1.鍏堜繚瀛樿鍏ㄥ睆鐨勭獥鍙g殑鐖剁獥鍙?/p>
2.濡傛灉瑕佸叏灞忕殑紿楀彛涓嶆槸瀛愮獥鍙o紝璁劇疆鍏墮鏍間負WS_CHILD
3.璁劇疆紿楀彛鐨勭埗紿楀彛涓烘闈?::GetDesktopWindow())
4.縐誨姩紿楀彛鑷沖叏灞忥紝騫跺皢紿楀彛璁句負鎬誨湪鏈涓奌WND_TOPMOST
m_videoMgr鏄垜鎺т歡閲屽垱寤虹殑瑙嗛紿楀彛錛屽畠鐨勭埗紿楀彛鏄帶浠剁獥鍙?CameraControl)鎺т歡鏈韓鐨勭獥鍙d笉鐩存帴鏄劇ず錛岃榪欎釜m_videoMgr紿楀彛瀹屽叏瑕嗙洊銆傚湪鍏ㄥ睆鐨勬椂鍊欙紝濡傛灉鐩存帴鏇存敼CameraControl鐨勭埗紿楀彛錛屽畠鐨勫瓙紿楀彛m_videoMgr紿楀彛鎬繪槸涓嶈兘姝g‘鐨勮緗負鍏ㄥ睆錛屽彲鑳藉湪鎺т歡嫻嬭瘯瀹瑰櫒閲屾甯革紝浣嗘槸鍒頒簡IE閲屽氨涓嶆甯鎬簡銆備簬鏄垜鏀逛負鏇存敼m_videoMgr紿楀彛鐨勭埗紿楀彛錛屼繚鐣欐帶浠舵湰韜獥鍙o紝浣嗘槸鏀瑰彉紿楀彛澶у皬鐨勬椂鍊欙紝鏀瑰彉鐖剁獥鍙g殑澶у皬錛屼篃璁竚_videoMgr紿楀彛鍙兘鍜屾帶浠舵湰韜獥鍙g殑澶у皬鏈夊叧鑱旓紝榪欐牱鎴愬姛鐨勮繘琛屼簡鍏ㄥ睆錛岃屼笖涓嶇鏄湪IE鍜屾帶浠舵祴璇曞鍣ㄩ噷閮藉彲浠ユ甯哥殑鍏ㄥ睆鍜屾仮澶嶃?/p>
if(bFullScreen) { //鑾峰彇鎺т歡紿楀彛鐨勭粷瀵逛綅緗?/span>
GetWindowRect(m_rcCtrlRect); ::SetParent(m_videoMgr.GetSafeHwnd(),::GetDesktopWindow()); int cx = ::GetSystemMetrics(SM_CXSCREEN); int cy = ::GetSystemMetrics(SM_CYSCREEN); MoveWindow(0, 0, cx, cy); ::SetWindowPos(m_videoMgr.GetSafeHwnd(),HWND_TOPMOST,0,0,cx,cy,SWP_FRAMECHANGED|SWP_DEFERERASE); m_bFullScreen = TRUE; } else { ::SetParent(m_videoMgr.GetSafeHwnd(),m_hWnd);
//MoveWindow浣跨敤鐩稿紿楀彛鍧愭爣錛屾墍浠ュ繀欏誨厛杞寲涓虹浉瀵瑰潗鏍?/span>CPoint LeftTop(m_rcCtrlRect.TopLeft()); CPoint BottomRight(m_rcCtrlRect.BottomRight()); ::ScreenToClient(m_hWnd,&LeftTop); ::ScreenToClient(m_hWnd,&BottomRight); ::MoveWindow(m_hWnd,LeftTop.x,LeftTop.y,m_rcCtrlRect.Width(),m_rcCtrlRect.Height(),TRUE); ::SetWindowPos(m_videoMgr.GetSafeHwnd(),HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); m_bFullScreen = FALSE; }
瑙e喅浜嗕笂闈㈢殑闂涔嬪悗錛屽張鍙戠幇浜嗕竴涓柊鐨勯棶棰橈紝灝辨槸鍏ㄥ睆浠ュ悗鎯充嬌鐢‥sc閿鍑哄叏灞忔椂錛屾牴鏈笉鍝嶅簲閿洏娑堟伅錛屽悗鏉ュ彂鐜癕FC涔熸湁鎺т歡涓嶅鐞嗛敭鐩樻秷鎭殑闂錛屾兂鎯沖彲鑳借窡鎺т歡鐨勭劍鐐規湁鍏崇郴錛屼簬鏄湪FullScreen鐨勪箣鍓嶏紝鍔犱竴涓猄etFocus()
if(FullScreen&&!IsFullScreen())
{
SetFocus();
OnFullScreen(TRUE);
}鐒跺悗鍙戠幇閿洏娑堟伅澶勭悊姝e父浜嗭紝闂瑙e喅銆?/pre>
]]>