From d76884f42a7c0b041f2dd7f75f3f74d5a0bd6380 Mon Sep 17 00:00:00 2001 From: John Cortell Date: Fri, 30 Apr 2010 14:22:34 +0000 Subject: [PATCH] Bug 311182: Enhance Spawner JNI code to use DebugBreakProcess when running on >= XP --- .../library/raise.c | 42 ++++++++++++++++-- .../os/win32/x86/spawner.dll | Bin 41667 -> 42781 bytes 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/core/org.eclipse.cdt.core.win32/library/raise.c b/core/org.eclipse.cdt.core.win32/library/raise.c index 7ec280960cf..20f34d37ebe 100644 --- a/core/org.eclipse.cdt.core.win32/library/raise.c +++ b/core/org.eclipse.cdt.core.win32/library/raise.c @@ -54,21 +54,55 @@ find_child_console (HWND hwnd, LPARAM arg) return TRUE; } +// Need to declare this Win32 prototype ourselves. _WIN32_WINNT is getting +// defined to a Windows NT value, thus we don't get this. Can't assume +// we're running on XP, anyway (or can we by now?) +#if (_WIN32_WINNT < 0x0501) +typedef BOOL (WINAPI *DebugBreakProcessFunc)(HANDLE); +#endif ///////////////////////////////////////////////////////////////////////////////////// -// Function implements interrupt process (Ctrl-C emulation) +// Called to interrupt a process that we didn't launch (and thus does not share our +// console). Windows XP introduced the function 'DebugBreakProcess', which allows +// a process to interrupt another process even if if the two do not share a console. +// If we're running on 2000 or earlier, we have to resort to simulating a CTRL-C +// in the console by firing keyboard events. This will work only if the process +// has its own console. That means, e.g., the process should have been started at +// the cmdline with 'start myprogram.exe' instead of 'myprogram.exe'. +// // Arguments: // pid - process' pid // Return : 0 if OK or error code ///////////////////////////////////////////////////////////////////////////////////// int interruptProcess(int pid) { + // See if DebugBreakProcess is available (XP and beyond) + HMODULE hmod = LoadLibrary(L"Kernel32.dll"); + if (hmod != NULL) + { + BOOL success = FALSE; + FARPROC procaddr = GetProcAddress(hmod, "DebugBreakProcess"); + if (procaddr != NULL) + { + HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); + if (proc != NULL) + { + DebugBreakProcessFunc pDebugBreakProcess = (DebugBreakProcessFunc)procaddr; + success = (*pDebugBreakProcess)(proc); + CloseHandle(proc); + } + } + FreeLibrary(hmod); + hmod = NULL; + + if (success == TRUE) + return 0; // 0 == OK; if not, try old-school way + } + #ifdef DEBUG_MONITOR _TCHAR buffer[1000]; #endif - int rc; - // Try another method - rc = 0; + int rc = 0; consoleHWND = NULL; #ifdef DEBUG_MONITOR diff --git a/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll b/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll index 8af8a4cacee983e83aec0e8cfc9e6f185fa4b8e7..0608730ebe644e937688c9bc424630957ff61ca8 100644 GIT binary patch delta 11226 zcmcIqeOy#k-oN)a1BeKC84(Z>W(Gu292IeR3seR%Un0Z8S3p6*01*d8LWd1_76c3Z zk(rrcS-GyCvc+6`eJI<|va;5CSZj-Q+nkhIYk7=}K#fN@QjsP7s95y-&rnv5)V)Jcado z?u{6)X%~b6`u^^5)XtKr_C7D~oSC5cL*i(+7&F<7vtdV?VCsymD9E?w3qn7f3waO? zB$2)l?-K8zSQZlB>j|J0;su!p8Fn}v6qamWkH8`t+93>bXU8t~q{t@4(nL+H_#-XV zEDU;Snjmy(h4Pv*5QHv`kt_Ri)93|FqWCji)5P17L22lGnsco4yLh|sv_CHFb(27S zW3nJL)fm0H(v2D(tSQcD-xnzeb-g|fos}o-w{H&)&gi`UG~~%Wr@68HA5#%Y@WCm- z-L1=;{9cPs{R8uA7Q z2b<;J4LmFR6?)HOSHL}JLpN%9f_EVhT+#EMs~e@hRADK!V561 z>kV(R+-SDksOulJvg_H+7CR5qA~&Hgz5HsI^Xdk_DxX4OBU6G$%YDh_eX;18Fo?|- zFW&sWWF5Jly&g?}8X3l(h^C*Qc1BaMcNkj}O$ksb(X_&Q3KJ(&gSScikWPEg;KXmd zP3-N6~WM2o@4WRleD*+d#h> zH-WDErnBV+n&Foz{*|iz=CV(W^t#`8R-mWLe&K9gBn|k5vU)v*_)llE47A8Ul#Mk| zv41E^^}qao#Y*)wa!gooWCVu$^&AYCVD)Wo;3vFWz7do*W^Brj;k>noxB4}_jIvN> zVxnH2LS-h#IIrZH7~#0G|B?2MNn%e%(1&BDviu18Wy}<|GlC{dcZz=@tMo|TX9$g& z;7ixOU?RG2xrDO!;@5jD-Hrjc#FM!bjm?%zK;(6Sc5YV{gPNR#CTCsE4_A`oMC2n?jbanqP-0>uU` zW`Utp6EvPZ6HJcAXKERVZ}4kthEieH^rjnM3G~;Gp1}LI3X*eHp~3 z$nTuoTE(ZRa+m#MqTnR9E0`_@Pi1+*bUQf6e_OCJF5TR9Q7}b?{F*%)L@$KwV7efh zGCoCopNhtZE<8C-CU#i{cq-pKgr8j@ljR1lhEBh>PQTNgO_qUXOFy^B8%MFBIqZ!b0cwVh)=V_B=K|=_ ziEI5I4N!)6fM>E$B5k-;{6|N1c)l3?n=!o2zp0@cOSH8y7(5Y znlveB-zd)T;WZq$4)+DiG0xPDqJxuSY-SAdN}%?5hab#t-Od5Qul_Ogqs!9IyTdK5 z;P6RNU`L$F5jTCnuut^ps|nFcQ+>!w6Y zzXP$S%5>Zi?!QpEN<-LRTjlY!*}rYOc|8{T<7- z`R`c18R1;8ey1(hc+LhV!#=F#8{RU~*>cr>b0pv8@Ru?HhG@_Uua(5*OYD4aKBHVokP@Z%8>$jK4{`%o> z9nQe?a=7bvy1Qq%J9$=IZcGVsn+By>e-?3ScV5N(9dbm(Tsi!4jnTNymmTIDl`q); zPID&*&%VkbG|9tp4$oLv63D=1$sfzmtfC#EhbITyRL-guOO285H}?A-Nhw2DC^u^4 zf{C!-hqk7-crU@^n;6faNoTZY$TS~$z9a0Wf1>p}X%ihZAAW|>)SdSg;v+enIfd(n!OF1a z*#rFSW~Huqv`~Pv^OfGOY6_@$Y9#J>4^K_>@j<)&HlFr=^>aUcGBp;kW?CVBH%*%* zcGKZ$i__ERA=b}>)@co&Sp)XOJ;ARxv_+|U&|BWW#uQ>3E%c#wRX+f zJ==sCpIv87XZOq(n{^H8^C&iUy?B!L#hNFtM#NWsM9ODcaE2n~TY$!%gj#{8PGGNo zkJgu4=pV83L(I6|v-3cg<>pYS!qo*8~ zZy(9TWs~LHk;SsUa3o9C7msAi`jX%8wK+K3(1b^mWaHr2L-fk@xxU?Z)Reuv$G%#BAUyI{CqB9j;qUa(;XDfQKqO%lTpy<^OZHp{dfHXztC^}BjMn$(Nx>eCt zimq35i=t~3U90FuMZbmt;T^r9=ssE71|xkG!dFVeF-3bRc#m@3spzAMZdG)@q8k-m zujm#D}Vh3hIe&Z{WQzdx&D^ZLTATRT=H+QbofSMTsl)@tUZJ&Jq5Uc45!f~*|bz=HPS z6&twoI0Y;m*y>?e53s6zdm{pEhtP5iavJguf*!(;SVfzm zGay-zJjfO&6w(8^2I+&`hIs9F_?Mug_S^8`0w?K^ zm5^`nAa(k1DW?oQgB)RuHC>32zA zB;8E%OO8xVO1?9BS@O!{b;%{kJIu+iCU+%YNbXL)ntUUDLeL5Qcc<=4J(&7b z>haXyrM{B-R_eQ{AE#bUy^?w@^@r43sX`hSCJKs~yiJlR#H2S(G0ik(&J?mx^}Nzd z9k&+hMu>LuTVl}JO@bf_;qr$rLAVD4lsAKFmV^cUT0R}#cp6BX35|MPo65=$kI|hb z3R@aR7nf*sovOwSXgud|c|<-P?(%`R&{BOsrpiYeUYYyoqooF2 z-;Ckr&A`KF!XV7!xAJMn)Vt=1tYrq3XX&|W%gSKJ8RWkt%%j&s5R5Z^cXza?eGbnS zlWE4?^QnB9QCvnZE()gSml>Hoiem2!;ollDI6p4CU)zZEM$p|Gg2;AH3~QaVZ&%1( zlV)5ep6Pn<8HbM>f275>1f-Mxa*qKd^2pvKw$PUB1q|P+xWh}?A-eV{&ct(bb4&A! z@!c?n*m6DRL@j@ag~!m1MS2Ro&zrhoGO*mJGs8D`?+9@Z9v#DD92t0Q$Au||a_)Ud zcQMB4IM!NNWd$FuZr!_Sl*?Rvf$m-zET++43Jd7(%RFgjQ9OC%OSEsDM289_7OSOo zIdMAvF#v;vcpI!mm1Xy%j2N}!Gr~`s)>G69W55t0wwQltHO>yAH7jO|neco+6U2Qh z^>T$bCtyMwB%cwA-2=?jRrck zR$@I`Y5`D0gX;_whF)c9$-69rzS|&C^csmy=1QzxOO0h2;t47)GLUbP#BOWJV{?Xh zjQ(0|&@D!NJNmD5FTPJp^=NLRy=x7WxJF`cXo;0)V0Jz84b;9~V#l>q3!s(!at(AW zUt*`UbQ{1?Dl9fo)H;b>(^AcrjDSO^5S8=Ut0^Maz&_Q|tt}aN7S7*fpvGc}d3jJ( zMFtfVOJrOt(LD5ZlU9bl#yCB+UZPlxN{g0mR%D0=XassY1w$2%#`>-CbOm;y7)(8q ztI*O9TQkH0nusYlid-_Zbh02$$3Hl$Cpw%_xz#bz)czUTY1`C1DZH_#* zR(Wnu@wo;5V$p2#=We}f!;(?;Gp@=N%{i=xJ?J}YhPm6#xYfSo;NK_!(LVkebi z;#)9>k_TO@%m}#P=B=J=8x1VogNn9gm@m0Cx3~o>cMG=7gTCIDA-+w2-(aBnO%jXp zpn~lg0q5Mj)zVKz1{UW*SJ2G21JxkRZX|J|L0n0XZknxI?F!>uXH|^ys)FgqMdRs< zoJ?AMzmcsLschr;ksFFj3b7?ZxALlZdVZTk z8I=-UE0^frYKguBR*Pl+`DTgUt-@;3(CQr-bPHv)u1umg9+22k4P6H0jiT9IAkoqs ziTP+Lr#geGaCxRmqN-Afm1yWwK+obbeuqTmnMWQZ<{}S4y<3LZZc0Qb3*?r-*aJUV5_HKHm+jJE^ENtI zv_%R?#?GkrT_tlqK+mdd5`7KM<)K+t;@8TYL#wclV6f62kOEG+#cz~3W~)S}(Ag^$ zQow09Kdmz7FtWR}MWVc|Qou1c4yFfv&BSD!gRd{ZdB=^@&N)ouN%!JQ{SReQfY~jb zW3roQjQza`bs4S>*(B^4-1(Fo?3~*rT5XjAeBCV1$eedE`!kVf<_;-fm)oFq%AAi& zCAzgsqU>!_K(rg@oXlxNjXaBOuuq_8*Xi-uktfiG&Gp0s65TA70;=5-=;j=;j~132 zD5p{i_}a~NkL=|D_VrkJDZp6ocJpGFIbo|Lae)53*${Bfjd4R}WMSrC!(iMhkpkM> zBK6ChgNR};k;um;>GIq-f{F6h#NmU-hh+wOt6I_xxKX@h3iI-$OPH~&?UF9bEggTE zLsOBRC zreiBo8nG3zxPBU3VGwnED;kyN-1@}P{JBaTN1yF9FtcgjEP$;IP8;j&qEbNsSDw8dqvQdv~QMbEM>7g{ywt(W$dSRgI7m#{-z1CpsS21q^&zi}Z&XD}8akSDIM_Lnr^th79-GEmgu(MSDP2ljH z`S$0qS_q_Eh2#L~w7DFCDU<;+qPr*r#jFX4MrGCx#CbSezW^ji)r~hfqO$rBNUe%v z2jV{+Z@ojW7e4|zr4)$6^(cIuKcq@A49F!HlABvtQBk&8C{p!)E;#7Cww~4hSEwAwOTq9PZue`KE#laTs2;&Y>Ih z?t`JWa9mte4bDvYO>DS}bT=d$i1Q)Ekz5IoB9)&SAhoJ~w*iS(jm)qWDj_|PuUyl|J7^w_8sNuJ(PeXjQ*m!&oq+eBHp1yFTvI+wdqzXS9 z$OTo>OSqMalMBSwsv=c!l5#L1cl-LS>r2apld;Z~l3Si{Ekb)cWN6HG!zx>q^g$r~ zD$g$iDN=E|fOOxd>c^LW@>Ha6fgE!=;t5r(FRJK_btc4f_3*=IJe8H+j~;B$+h(GH zACA(`-LSo)*jgx@QyDJ+CmNig0$eFu)szh_m|~9jJNgWRN*WAQQNPn zdcPNDR+XbCfcU6_y#mB}I0~?&uuN!Gxqes0;q1?W3?;;o>p*O$RN=kG;CrhJk!w5O zDx6Wdo(N8wYVhNMoKYc5fP|}(&I7Vqg_Hrww5gyPKzxjc%IaYtpSu#`Sw91$+lA!f zt9J?h&(|?kif6$|S9$&j$PE?84n%|T9~SHvK)o*4Jea?P|DUDm*+d{&D%Y_<@?0Ew z%!(?6a#t|i1Ir3>bGbYDfH96FSQ#1O4^`})fHH^7O686Tc`k&T-N(bv%LK zAm<#hY)bg)fNrQ9%?HAdp<&Dh(xbY67XhhNSyd}mLsj)KkOQuc@$xLFEEm$0Zt(So z{^O3U(Dpj;gOe0x`LQanIVZ*c((<5kT6U2%mpJNCVWaGRpzN4@W|| zx%peS7FJk$RD)lr;&AphAoZ$*2*}V~fOB2~;(W{D>kr3!fQ~vd5_0b;DJ(2ci?gc| z`U;#@m1{AO+d2-%D2@SgQI+C&AO~EYIX3}Fn#<1uF|gx@mTMzN5Bmd2T3pBF{ZEbX z9sakFv^c6hNP6`jP14Ll?mr_P+Q-wyfZXEJ^4wgt&jp9Bh@*%7c?Ds@4?nH>Kd9Pu AGynhq delta 10438 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