Funcfurter1
Now let's look at another scenario in which termination handling really proves its value. Look at this function:
DWORD Funcfurter1() {
DWORD dwTemp;
// 1. Do any processing here.
...
__try {
// 2. Request permission to access
// protected data, and then use it.
WaitForSingleObject(g_hSem, INFINITE);
dwTemp = Funcinator(g_dwProtectedData);
}
__finally {
// 3. Allow others to use protected data.
ReleaseSemaphore(g_hSem, 1, NULL);
}
// 4. Continue processing.
return(dwTemp);
}
Now imagine that the
Funcinator function called in the
try block contains a bug that causes an invalid memory access. Without SEH, this situation would present the user with the ever-popular "Application has stopped working" dialog box provided by theWindows
Error Reporting (WER) that will be presented in great detail inChapter 25, "Unhandled Exceptions, Vectored Exception Handling, and C++ Exceptions." When the user dismissed the error dialog box, the
process would be terminated. When the process is terminated (because of an invalid memory access), the semaphore would still be owned and would never be released—any threads in other processes that were waiting for this semaphore would never be scheduled CPU
time. But placing the call toReleaseSemaphore in afinally block guarantees that the semaphore gets
released even if some other function causes a memory access violation. I have to put a damper on this statement: starting with Windows Vista, you have to explicitly protect your try/finally
to ensure that thefinally block gets executed when an exception is raised. The necessary explanations are provided in "The SEH Termination Sample
Application" on page 673, and the
next chapter will dig into the details of thetry/except protection.
现在设想一下,在本例中的函数Funcinator中有一个bug,会产生非法内存访问。如果不使用SEH,这种形势下,会出现一个WER提供的错误报告对话框(在25章里详细讲解)。如果用户关闭这个对话框,该进程将被终止,此时semaphore没有被释放,等待它的线程将继续等待。但把ReleaseSemaphore放到finally里,会保证semaphore会被正确释放,即使其他函数导致了内存访问冲突。(似从Vista开始)
However, even in prior versions of Windows, the
finally blocks are not guaranteed to execute for any exception. For example, in Windows XP, if a stack exhaustion exception occurs in thetry block,
chances are good that thefinally block is not going to get executed, because the WER code is running inside the faulting process possibly without enough stack left to report an
error, so the process would be silently terminated. Similarly, if the exception generated a corruption in the SEH chain, the termination handler will not be executed. Last but not least, if another exception happened in the exception filter, the termination
handler will not get executed. The rule of thumb to follow is always minimize the action of the code that runs withincatch orfinally
blocks; otherwise, the process just terminates and no morefinally blocks execute. This is why the error reporting in Windows Vista runs in a separate process, as detailed inChapter
25.
然而,在以前的Windows中,finally块并不能保证对任何异常都能执行。比如,在XP里,try中的堆栈异常不会导致finally中的代码被执行,因为WER代码在出错的进程里执行,很可能没有足够的stack来报告错误,因此进程会悄然结束。类似的,如果在SEH链中,异常产生了一个冲突,termination hander不会被执行。Last but not least,如果在exception
filter中发生了其他异常,termination hander不会被执行。The rule of thumb to follow is always minimize the action of the code that runs withincatchorfinallyblocks;
otherwise, the process just terminates and no morefinallyblocks execute. This is why the error reporting in Windows Vista runs in a separate process, as detailed inChapter
25.
If termination handlers are powerful enough to capture a process while terminating because of an invalid memory access, we should have no trouble believing that they will also capturesetjump
andlongjump combinations and, of course, simple statements such asbreak andcontinue.
如果 termination handers很强大,可以捕获因为非法内存访问终止的进程,we should have no trouble believing that they will also capture setjump and longjump combinations and, of course, simple statements such as break and continue.
Pop Quiz Time:
FuncaDoodleDoo
Now for a test. Can you determine what the following function returns?
DWORD FuncaDoodleDoo() {
DWORD dwTemp = 0;
while (dwTemp < 10) {
__try {
if (dwTemp == 2)
continue;
if (dwTemp == 3)
break;
}
__finally {
dwTemp++;
}
dwTemp++;
}
dwTemp += 10;
return(dwTemp);
}
Let's analyze what the function does step by step. First
dwTemp is set to
0. The code in the
try block executes, but neither of the
if statements evaluates to
TRUE. Execution moves naturally to the code in thefinally block, which incrementsdwTemp
to1. Then the instruction after thefinally block incrementsdwTemp
again, making it2.
一步步分析一下这个函数。首先 dwTemp为0,进入try之后,因为没有一个if为TRUE,执行流程自然地进入finally块,在这里dwTemp被自增。finally后的代码再次自增,使之为2
When the loop iterates,
dwTemp is
2 and the
continue statement in the
try block will execute. Without a termination handler to force execution of thefinally block before exit from thetry
block, execution would immediately jump back up to thewhile test,dwTemp would not be changed, and
we would have started an infinite loop. With a termination handler, the system notes that thecontinue statement causes the flow of control to exit thetry
block prematurely and moves execution to thefinally block. In thefinally block,dwTemp
is incremented to3. However, the code after thefinally block doesn't execute because the flow of control
moves back tocontinue and thus to the top of the loop.
在接下来的循环中,由于dwTemp为2,try中的continue将被执行。Without a termination handler to force execution of thefinallyblock
before exit from thetryblock,执行流程将立即回到while,dwTemp将永远不变,程序将陷入死循环。借助termination hander,系统会注意到continue将导致有提前退出try的情况并执行finally。在finally里,dwTemp被自增到3,然后,finally后的代码此次将不被执行,因为流程跳回到continue,继续循环。
Now we are processing the loop's third iteration. This time, the firstif statement evaluates toFALSE,
but the secondif statement evaluates toTRUE. The system again catches our attempt to break out of
thetry block and executes the code in thefinally block first. NowdwTemp
is incremented to4. Because abreak statement was executed, control resumes after the loop. Thus, the
code after thefinally block and still inside the loop doesn't execute. The code below the loop adds10
todwTemp for a grand total of14—the result of calling this function. It should go without saying that
you should never actually write code likeFuncaDoodleDoo. I placed thecontinue andbreak
statements in the middle of the code only to demonstrate the operation of the termination handler.
现在我们执行第三次循环。这次,第二个if被满足,系统再次发现我们要提前退出try,因此先执行finally。现在dwTemp被自增到4.因为执行的是break,finally中的代码还是没有被执行,循环底下的代码被执行,最后的结果变为14.
Although a termination handler will catch most situations in which thetry block would otherwise be exited prematurely, it can't cause the code in afinally
block to be executed if the thread or process is terminated. A call toExitThread orExitProcess will
immediately terminate thethread or process without executing any of the code in afinally
block. Also, if your thread or process should die because some application calledTerminateThread orTerminateProcess,
the code in afinally block again won't execute. Some C run-time functions (such asabort) that in turn
callExitProcess again preclude the execution offinally blocks. You can't do anything to prevent another
application from terminating one of your threads or processes, but you can prevent your own premature calls toExitThread andExitProcess.
如果进程或者线程是被ExitThread或者ExitProcess终止的,finally中的代码将不会执行。
分享到:
相关推荐
Chapter 23: Timers and Sleeping Chapter 24: Process Creation Chapter 25: Process Termination Chapter 26: Monitoring Child Processes Chapter 27: Program Execution Chapter 28: Process Creation and ...
MOLAND: Termination of the consent solicitation.pdf
Termination of Coverage.pdf
Chapter 2: The Wizards and The Gallery AppWizard Starting AppWizard Choosing Your Application's User Interface Selecting Database Support Adding Compound Document Support Embellishing Your User ...
Advanced Process Termination 2.1 用多种方法结束进程 一般用于测试安全工具的自我保护的测试
一份描述网口Bob Smith的电路,对于了解此电路的功能有很大的帮助
2015-09-12 07:01:00.692: [ CRSAPP][12074]32CheckResource error for ora.lxhgnc.lxhgnc2.inst error code = -2 2015-09-12 07:01:00.935: [ CRSEVT][12331]32CAAMonitorHandler :: 0:Could not join /opt/oracle/...
Atom-Termination.zip,Integrated terminal for Atom. Looks like terminal-plus, acts like your native terminal (except every other Friday). Looking for collaborators! :-)终止,atom是一个用web技术构建的...
In the past there have been two main termination specifications for UTP data cable infrastructure and yet another for phone cable infrastructure. In today’s world of structured cable systems where ...
反射弧EC2实例终止保护已禁用 用于检测是否已为EC2实例禁用实例终止保护的Reflex规则。 要了解有关EC2实例终止保护的更多信息,请参阅。 入门 要开始使用Reflex,请查看。 用法 要使用此规则,请将其添加到您的...
一篇关于x264快速自适应模式选择的论文:Fast Adaptive Early Termination for Mode Selection in H.264AVC Standard Based on x264 Implementation
该项目确保Kubernetes控制平面通过API或控制台对可能导致EC2实例变得不可用的事件做出适当响应,例如, , , 和EC2实例终止。 如果不加以处理,则您的应用程序代码可能无法正常停止,需要更长的时间才能恢复完全...
ecs-spot-termination配置集 此配置集安装了一个现场终止脚本,该脚本将连续运行并监视现场两分钟警告。 看到两分钟的警告后,它将从ECS群集中耗尽实例。什么是lono配置集? Lono配置集允许通常嵌入在模板中的 可...
使用这个程序可以轻易关闭著名杀毒软件、系统关键进程,但使用前请关闭杀毒软件&防火墙,以免误杀。
《UNIX Network Programming Volume 2》(Unix网络编程卷2英文版,djvu格式,带绿色小巧的阅读器) 原书名: UNIX Network Programming Volume 2:Interprocess Communications 2nd ed. 原出版社: Prentice Hall/...
Transmission lines equations for coupled lines symmetrical lines and symmetrically driven homogeneous medium symmetrical lines in homogeneous medium symmetrical lines and asymmetrical driven ...
EC2实例计划终止 此CloudFormation模板创建Lambda函数,用于在“停止”状态下计划终止的EC2实例超过30天,并... Lambda函数ec2_termination_lambda_function用于计划的终止。 IAM角色以及适用于lambda功能的策略。 e
2 Representing processes in Linux 3 Organising the task structures 4 Wait queues 5 Mutual exclusion with locks 6 Mutual exclusion with waiting 7 Scheduling 8 Process creation 9 Process termination 10 ...
Chapter 2. The Transport Layer: TCP, UDP, and SCTP Section 2.1. Introduction Section 2.2. The Big Picture Section 2.3. User Datagram Protocol (UDP) Section 2.4. Transmission Control Protocol ...