Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2548 lines
46 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. xcpt4.c
  5. Abstract:
  6. This module implements user mode exception tests.
  7. Author:
  8. David N. Cutler (davec) 18-Sep-1990
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "ki.h"
  14. #pragma hdrstop
  15. #include "setjmpex.h"
  16. #include "float.h"
  17. #pragma warning(disable:4532)
  18. //
  19. // Define switch constants.
  20. //
  21. #define BLUE 0
  22. #define RED 1
  23. //
  24. // Define guaranteed fault.
  25. //
  26. #define FAULT *(volatile int *)0
  27. //
  28. // Define function prototypes.
  29. //
  30. VOID
  31. addtwo (
  32. IN LONG First,
  33. IN LONG Second,
  34. IN PLONG Place
  35. );
  36. VOID
  37. bar1 (
  38. IN NTSTATUS Status,
  39. IN PLONG Counter
  40. );
  41. VOID
  42. bar2 (
  43. IN PLONG BlackHole,
  44. IN PLONG BadAddress,
  45. IN PLONG Counter
  46. );
  47. VOID
  48. dojump (
  49. IN jmp_buf JumpBuffer,
  50. IN PLONG Counter
  51. );
  52. LONG
  53. Echo(
  54. IN LONG Value
  55. );
  56. VOID
  57. eret (
  58. IN NTSTATUS Status,
  59. IN PLONG Counter
  60. );
  61. VOID
  62. except1 (
  63. IN PLONG Counter
  64. );
  65. ULONG
  66. except2 (
  67. IN PEXCEPTION_POINTERS ExceptionPointers,
  68. IN PLONG Counter
  69. );
  70. ULONG
  71. except3 (
  72. IN PEXCEPTION_POINTERS ExceptionPointers,
  73. IN PLONG Counter
  74. );
  75. VOID
  76. foo1 (
  77. IN NTSTATUS Status
  78. );
  79. VOID
  80. foo2 (
  81. IN PLONG BlackHole,
  82. IN PLONG BadAddress
  83. );
  84. VOID
  85. fret (
  86. IN PLONG Counter
  87. );
  88. BOOLEAN
  89. Tkm (
  90. VOID
  91. );
  92. VOID
  93. Test61Part2 (
  94. IN OUT PULONG Counter
  95. );
  96. VOID
  97. PerformFpTest(
  98. VOID
  99. );
  100. double
  101. SquareDouble (
  102. IN double op
  103. );
  104. VOID
  105. SquareDouble17E300 (
  106. OUT PVOID ans
  107. );
  108. LONG
  109. test66sub (
  110. IN PLONG Counter
  111. );
  112. LONG
  113. test67sub (
  114. IN PLONG Counter
  115. );
  116. VOID
  117. xcpt4 (
  118. VOID
  119. )
  120. {
  121. PLONG BadAddress;
  122. PCHAR BadByte;
  123. PLONG BlackHole;
  124. ULONG Index1;
  125. ULONG Index2 = RED;
  126. jmp_buf JumpBuffer;
  127. LONG Counter;
  128. EXCEPTION_RECORD ExceptionRecord;
  129. double doubleresult;
  130. //
  131. // Announce start of exception test.
  132. //
  133. DbgPrint("Start of exception test\n");
  134. //
  135. // Initialize exception record.
  136. //
  137. ExceptionRecord.ExceptionCode = STATUS_INTEGER_OVERFLOW;
  138. ExceptionRecord.ExceptionFlags = 0;
  139. ExceptionRecord.ExceptionRecord = NULL;
  140. ExceptionRecord.NumberParameters = 0;
  141. //
  142. // Initialize pointers.
  143. //
  144. BadAddress = (PLONG)NULL;
  145. BadByte = (PCHAR)NULL;
  146. BadByte += 1;
  147. BlackHole = &Counter;
  148. //
  149. // Simply try statement with a finally clause that is entered sequentially.
  150. //
  151. DbgPrint(" test1...");
  152. Counter = 0;
  153. try {
  154. Counter += 1;
  155. } finally {
  156. if (abnormal_termination() == FALSE) {
  157. Counter += 1;
  158. }
  159. }
  160. if (Counter != 2) {
  161. DbgPrint("failed, count = %d\n", Counter);
  162. } else {
  163. DbgPrint("succeeded\n");
  164. }
  165. //
  166. // Simple try statement with an exception clause that is never executed
  167. // because there is no exception raised in the try clause.
  168. //
  169. DbgPrint(" test2...");
  170. Counter = 0;
  171. try {
  172. Counter += 1;
  173. } except (Counter) {
  174. Counter += 1;
  175. }
  176. if (Counter != 1) {
  177. DbgPrint("failed, count = %d\n", Counter);
  178. } else {
  179. DbgPrint("succeeded\n");
  180. }
  181. //
  182. // Simple try statement with an exception handler that is never executed
  183. // because the exception expression continues execution.
  184. //
  185. DbgPrint(" test3...");
  186. Counter = 0;
  187. try {
  188. Counter -= 1;
  189. RtlRaiseException(&ExceptionRecord);
  190. } except (Counter) {
  191. Counter -= 1;
  192. }
  193. if (Counter != - 1) {
  194. DbgPrint("failed, count = %d\n", Counter);
  195. } else {
  196. DbgPrint("succeeded\n");
  197. }
  198. //
  199. // Simple try statement with an exception clause that is always executed.
  200. //
  201. DbgPrint(" test4...");
  202. Counter = 0;
  203. try {
  204. Counter += 1;
  205. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  206. } except (Counter) {
  207. Counter += 1;
  208. }
  209. if (Counter != 2) {
  210. DbgPrint("failed, count = %d\n", Counter);
  211. } else {
  212. DbgPrint("succeeded\n");
  213. }
  214. //
  215. // Simple try statement with an exception clause that is always executed.
  216. //
  217. DbgPrint(" test5...");
  218. Counter = 0;
  219. try {
  220. Counter += 1;
  221. *BlackHole += *BadAddress;
  222. } except (Counter) {
  223. Counter += 1;
  224. }
  225. if (Counter != 2) {
  226. DbgPrint("failed, count = %d\n", Counter);
  227. } else {
  228. DbgPrint("succeeded\n");
  229. }
  230. //
  231. // Simply try statement with a finally clause that is entered as the
  232. // result of an exception.
  233. //
  234. DbgPrint(" test6...");
  235. Counter = 0;
  236. try {
  237. try {
  238. Counter += 1;
  239. RtlRaiseException(&ExceptionRecord);
  240. } finally {
  241. if (abnormal_termination() != FALSE) {
  242. Counter += 1;
  243. }
  244. }
  245. } except (Counter) {
  246. if (Counter == 2) {
  247. Counter += 1;
  248. }
  249. }
  250. if (Counter != 3) {
  251. DbgPrint("failed, count = %d\n", Counter);
  252. } else {
  253. DbgPrint("succeeded\n");
  254. }
  255. //
  256. // Simply try statement with a finally clause that is entered as the
  257. // result of an exception.
  258. //
  259. DbgPrint(" test7...");
  260. Counter = 0;
  261. try {
  262. try {
  263. Counter += 1;
  264. *BlackHole += *BadAddress;
  265. } finally {
  266. if (abnormal_termination() != FALSE) {
  267. Counter += 1;
  268. }
  269. }
  270. } except (Counter) {
  271. if (Counter == 2) {
  272. Counter += 1;
  273. }
  274. }
  275. if (Counter != 3) {
  276. DbgPrint("failed, count = %d\n", Counter);
  277. } else {
  278. DbgPrint("succeeded\n");
  279. }
  280. //
  281. // Simple try that calls a function which raises an exception.
  282. //
  283. DbgPrint(" test8...");
  284. Counter = 0;
  285. try {
  286. Counter += 1;
  287. foo1(STATUS_ACCESS_VIOLATION);
  288. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  289. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  290. Counter += 1;
  291. }
  292. if (Counter != 2) {
  293. DbgPrint("failed, count = %d\n", Counter);
  294. } else {
  295. DbgPrint("succeeded\n");
  296. }
  297. //
  298. // Simple try that calls a function which raises an exception.
  299. //
  300. DbgPrint(" test9...");
  301. Counter = 0;
  302. try {
  303. Counter += 1;
  304. foo2(BlackHole, BadAddress);
  305. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  306. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  307. Counter += 1;
  308. }
  309. if (Counter != 2) {
  310. DbgPrint("failed, count = %d\n", Counter);
  311. } else {
  312. DbgPrint("succeeded\n");
  313. }
  314. //
  315. // Simple try that calls a function which calls a function that
  316. // raises an exception. The first function has a finally clause
  317. // that must be executed for this test to work.
  318. //
  319. DbgPrint(" test10...");
  320. Counter = 0;
  321. try {
  322. bar1(STATUS_ACCESS_VIOLATION, &Counter);
  323. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  324. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  325. Counter -= 1;
  326. }
  327. if (Counter != 98) {
  328. DbgPrint("failed, count = %d\n", Counter);
  329. } else {
  330. DbgPrint("succeeded\n");
  331. }
  332. //
  333. // Simple try that calls a function which calls a function that
  334. // raises an exception. The first function has a finally clause
  335. // that must be executed for this test to work.
  336. //
  337. DbgPrint(" test11...");
  338. Counter = 0;
  339. try {
  340. bar2(BlackHole, BadAddress, &Counter);
  341. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  342. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  343. Counter -= 1;
  344. }
  345. if (Counter != 98) {
  346. DbgPrint("failed, count = %d\n", Counter);
  347. } else {
  348. DbgPrint("succeeded\n");
  349. }
  350. //
  351. // A try within an except
  352. //
  353. DbgPrint(" test12...");
  354. Counter = 0;
  355. try {
  356. foo1(STATUS_ACCESS_VIOLATION);
  357. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  358. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  359. Counter += 1;
  360. try {
  361. foo1(STATUS_SUCCESS);
  362. } except ((GetExceptionCode() == STATUS_SUCCESS) ?
  363. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  364. if (Counter != 1) {
  365. DbgPrint("failed, count = %d\n", Counter);
  366. } else {
  367. DbgPrint("succeeded...");
  368. }
  369. Counter += 1;
  370. }
  371. }
  372. if (Counter != 2) {
  373. DbgPrint("failed, count = %d\n", Counter);
  374. } else {
  375. DbgPrint("succeeded\n");
  376. }
  377. //
  378. // A try within an except
  379. //
  380. DbgPrint(" test13...");
  381. Counter = 0;
  382. try {
  383. foo2(BlackHole, BadAddress);
  384. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  385. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  386. Counter += 1;
  387. try {
  388. foo1(STATUS_SUCCESS);
  389. } except ((GetExceptionCode() == STATUS_SUCCESS) ?
  390. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  391. if (Counter != 1) {
  392. DbgPrint("failed, count = %d\n", Counter);
  393. } else {
  394. DbgPrint("succeeded...");
  395. }
  396. Counter += 1;
  397. }
  398. }
  399. if (Counter != 2) {
  400. DbgPrint("failed, count = %d\n", Counter);
  401. } else {
  402. DbgPrint("succeeded\n");
  403. }
  404. //
  405. // A goto from an exception clause that needs to pass
  406. // through a finally
  407. //
  408. DbgPrint(" test14...");
  409. Counter = 0;
  410. try {
  411. try {
  412. foo1(STATUS_ACCESS_VIOLATION);
  413. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  414. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  415. Counter += 1;
  416. goto t9;
  417. }
  418. } finally {
  419. Counter += 1;
  420. }
  421. t9:;
  422. if (Counter != 2) {
  423. DbgPrint("failed, count = %d\n", Counter);
  424. } else {
  425. DbgPrint("succeeded\n");
  426. }
  427. //
  428. // A goto from an finally clause that needs to pass
  429. // through a finally
  430. //
  431. DbgPrint(" test15...");
  432. Counter = 0;
  433. try {
  434. try {
  435. Counter += 1;
  436. } finally {
  437. Counter += 1;
  438. goto t10;
  439. }
  440. } finally {
  441. Counter += 1;
  442. }
  443. t10:;
  444. if (Counter != 3) {
  445. DbgPrint("failed, count = %d\n", Counter);
  446. } else {
  447. DbgPrint("succeeded\n");
  448. }
  449. //
  450. // A goto from an exception clause that needs to pass
  451. // through a finally into the outer finally clause.
  452. //
  453. DbgPrint(" test16...");
  454. Counter = 0;
  455. try {
  456. try {
  457. try {
  458. Counter += 1;
  459. foo1(STATUS_INTEGER_OVERFLOW);
  460. } except (EXCEPTION_EXECUTE_HANDLER) {
  461. Counter += 1;
  462. goto t11;
  463. }
  464. } finally {
  465. Counter += 1;
  466. }
  467. t11:;
  468. } finally {
  469. Counter += 1;
  470. }
  471. if (Counter != 4) {
  472. DbgPrint("failed, count = %d\n", Counter);
  473. } else {
  474. DbgPrint("succeeded\n");
  475. }
  476. //
  477. // A goto from an finally clause that needs to pass
  478. // through a finally into the outer finally clause.
  479. //
  480. DbgPrint(" test17...");
  481. Counter = 0;
  482. try {
  483. try {
  484. Counter += 1;
  485. } finally {
  486. Counter += 1;
  487. goto t12;
  488. }
  489. t12:;
  490. } finally {
  491. Counter += 1;
  492. }
  493. if (Counter != 3) {
  494. DbgPrint("failed, count = %d\n", Counter);
  495. } else {
  496. DbgPrint("succeeded\n");
  497. }
  498. //
  499. // A return from an except clause
  500. //
  501. DbgPrint(" test18...");
  502. Counter = 0;
  503. try {
  504. Counter += 1;
  505. eret(STATUS_ACCESS_VIOLATION, &Counter);
  506. } finally {
  507. Counter += 1;
  508. }
  509. if (Counter != 4) {
  510. DbgPrint("failed, count = %d\n", Counter);
  511. } else {
  512. DbgPrint("succeeded\n");
  513. }
  514. //
  515. // A return from a finally clause
  516. //
  517. DbgPrint(" test19...");
  518. Counter = 0;
  519. try {
  520. Counter += 1;
  521. fret(&Counter);
  522. } finally {
  523. Counter += 1;
  524. }
  525. if (Counter != 5) {
  526. DbgPrint("failed, count = %d\n", Counter);
  527. } else {
  528. DbgPrint("succeeded\n");
  529. }
  530. //
  531. // A simple set jump followed by a long jump.
  532. //
  533. DbgPrint(" test20...");
  534. Counter = 0;
  535. if (setjmp(JumpBuffer) == 0) {
  536. Counter += 1;
  537. longjmp(JumpBuffer, 1);
  538. } else {
  539. Counter += 1;
  540. }
  541. if (Counter != 2) {
  542. DbgPrint("failed, count = %d\n", Counter);
  543. } else {
  544. DbgPrint("succeeded\n");
  545. }
  546. //
  547. // A set jump followed by a long jump out of a finally clause that is
  548. // sequentially executed.
  549. //
  550. DbgPrint(" test21...");
  551. Counter = 0;
  552. if (setjmp(JumpBuffer) == 0) {
  553. try {
  554. Counter += 1;
  555. } finally {
  556. Counter += 1;
  557. longjmp(JumpBuffer, 1);
  558. }
  559. } else {
  560. Counter += 1;
  561. }
  562. if (Counter != 3) {
  563. DbgPrint("failed, count = %d\n", Counter);
  564. } else {
  565. DbgPrint("succeeded\n");
  566. }
  567. //
  568. // A set jump within a try clause followed by a long jump out of a
  569. // finally clause that is sequentially executed.
  570. //
  571. DbgPrint(" test22...");
  572. Counter = 0;
  573. try {
  574. if (setjmp(JumpBuffer) == 0) {
  575. Counter += 1;
  576. } else {
  577. Counter += 1;
  578. }
  579. } finally {
  580. Counter += 1;
  581. if (Counter == 2) {
  582. Counter += 1;
  583. longjmp(JumpBuffer, 1);
  584. }
  585. }
  586. if (Counter != 5) {
  587. DbgPrint("failed, count = %d\n", Counter);
  588. } else {
  589. DbgPrint("succeeded\n");
  590. }
  591. //
  592. // A set jump followed by a try/except, followed by a try/finally where
  593. // the try body of the try/finally raises an exception that is handled
  594. // by the try/excecpt which causes the try/finally to do a long jump out
  595. // of a finally clause. This will create a collided unwind.
  596. //
  597. DbgPrint(" test23...");
  598. Counter = 0;
  599. if (setjmp(JumpBuffer) == 0) {
  600. try {
  601. try {
  602. Counter += 1;
  603. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  604. } finally {
  605. Counter += 1;
  606. longjmp(JumpBuffer, 1);
  607. }
  608. } except(EXCEPTION_EXECUTE_HANDLER) {
  609. Counter += 1;
  610. }
  611. } else {
  612. Counter += 1;
  613. }
  614. if (Counter != 3) {
  615. DbgPrint("failed, count = %d\n", Counter);
  616. } else {
  617. DbgPrint("succeeded\n");
  618. }
  619. //
  620. // A set jump followed by a try/except, followed by a several nested
  621. // try/finally's where the inner try body of the try/finally raises an
  622. // exception that is handled by the try/except which causes the
  623. // try/finally to do a long jump out of a finally clause. This will
  624. // create a collided unwind.
  625. //
  626. DbgPrint(" test24...");
  627. Counter = 0;
  628. if (setjmp(JumpBuffer) == 0) {
  629. try {
  630. try {
  631. try {
  632. try {
  633. Counter += 1;
  634. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  635. } finally {
  636. Counter += 1;
  637. }
  638. } finally {
  639. Counter += 1;
  640. longjmp(JumpBuffer, 1);
  641. }
  642. } finally {
  643. Counter += 1;
  644. }
  645. } except(EXCEPTION_EXECUTE_HANDLER) {
  646. Counter += 1;
  647. }
  648. } else {
  649. Counter += 1;
  650. }
  651. if (Counter != 5) {
  652. DbgPrint("failed, count = %d\n", Counter);
  653. } else {
  654. DbgPrint("succeeded\n");
  655. }
  656. //
  657. // A set jump followed by a try/except, followed by a try/finally which
  658. // calls a subroutine which contains a try finally that raises an
  659. // exception that is handled to the try/except.
  660. //
  661. DbgPrint(" test25...");
  662. Counter = 0;
  663. if (setjmp(JumpBuffer) == 0) {
  664. try {
  665. try {
  666. try {
  667. Counter += 1;
  668. dojump(JumpBuffer, &Counter);
  669. } finally {
  670. Counter += 1;
  671. }
  672. } finally {
  673. Counter += 1;
  674. }
  675. } except(EXCEPTION_EXECUTE_HANDLER) {
  676. Counter += 1;
  677. }
  678. } else {
  679. Counter += 1;
  680. }
  681. if (Counter != 7) {
  682. DbgPrint("failed, count = %d\n", Counter);
  683. } else {
  684. DbgPrint("succeeded\n");
  685. }
  686. //
  687. // A set jump followed by a try/except, followed by a try/finally which
  688. // calls a subroutine which contains a try finally that raises an
  689. // exception that is handled to the try/except.
  690. //
  691. DbgPrint(" test26...");
  692. Counter = 0;
  693. if (setjmp(JumpBuffer) == 0) {
  694. try {
  695. try {
  696. try {
  697. try {
  698. Counter += 1;
  699. dojump(JumpBuffer, &Counter);
  700. } finally {
  701. Counter += 1;
  702. }
  703. } finally {
  704. Counter += 1;
  705. longjmp(JumpBuffer, 1);
  706. }
  707. } finally {
  708. Counter += 1;
  709. }
  710. } except(EXCEPTION_EXECUTE_HANDLER) {
  711. Counter += 1;
  712. }
  713. } else {
  714. Counter += 1;
  715. }
  716. if (Counter != 8) {
  717. DbgPrint("failed, count = %d\n", Counter);
  718. } else {
  719. DbgPrint("succeeded\n");
  720. }
  721. //
  722. // Test nested exceptions.
  723. //
  724. DbgPrint(" test27...");
  725. Counter = 0;
  726. try {
  727. try {
  728. Counter += 1;
  729. except1(&Counter);
  730. } except(except2(GetExceptionInformation(), &Counter)) {
  731. Counter += 2;
  732. }
  733. } except(EXCEPTION_EXECUTE_HANDLER) {
  734. Counter += 3;
  735. }
  736. if (Counter != 55) {
  737. DbgPrint("failed, count = %d\n", Counter);
  738. } else {
  739. DbgPrint("succeeded\n");
  740. }
  741. //
  742. // Simple try that causes an integer overflow exception.
  743. //
  744. DbgPrint(" test28...");
  745. Counter = 0;
  746. try {
  747. Counter += 1;
  748. addtwo(0x7fff0000, 0x10000, &Counter);
  749. } except ((GetExceptionCode() == STATUS_INTEGER_OVERFLOW) ?
  750. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  751. Counter += 1;
  752. }
  753. if (Counter != 2) {
  754. DbgPrint("failed, count = %d\n", Counter);
  755. } else {
  756. DbgPrint("succeeded\n");
  757. }
  758. //
  759. // Simple try that raises an misaligned data exception.
  760. //
  761. #if 0
  762. DbgPrint(" test29...");
  763. Counter = 0;
  764. try {
  765. Counter += 1;
  766. foo2(BlackHole, (PLONG)BadByte);
  767. } except ((GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) ?
  768. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  769. Counter += 1;
  770. }
  771. if (Counter != 2) {
  772. DbgPrint("failed, count = %d\n", Counter);
  773. } else {
  774. DbgPrint("succeeded\n");
  775. }
  776. #endif
  777. //
  778. // Continue from a try body with an exception clause in a loop.
  779. //
  780. DbgPrint(" test30...");
  781. Counter = 0;
  782. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  783. try {
  784. if ((Index1 & 0x1) == 0) {
  785. continue;
  786. } else {
  787. Counter += 1;
  788. }
  789. } except (EXCEPTION_EXECUTE_HANDLER) {
  790. Counter += 40;
  791. }
  792. Counter += 2;
  793. }
  794. if (Counter != 15) {
  795. DbgPrint("failed, count = %d\n", Counter);
  796. } else {
  797. DbgPrint("succeeded\n");
  798. }
  799. //
  800. // Continue from a try body with an finally clause in a loop.
  801. //
  802. DbgPrint(" test31...");
  803. Counter = 0;
  804. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  805. try {
  806. if ((Index1 & 0x1) == 0) {
  807. continue;
  808. } else {
  809. Counter += 1;
  810. }
  811. } finally {
  812. Counter += 2;
  813. }
  814. Counter += 3;
  815. }
  816. if (Counter != 40) {
  817. DbgPrint("failed, count = %d\n", Counter);
  818. } else {
  819. DbgPrint("succeeded\n");
  820. }
  821. //
  822. // Continue from doubly nested try body with an exception clause in a
  823. // loop.
  824. //
  825. DbgPrint(" test32...");
  826. Counter = 0;
  827. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  828. try {
  829. try {
  830. if ((Index1 & 0x1) == 0) {
  831. continue;
  832. } else {
  833. Counter += 1;
  834. }
  835. } except (EXCEPTION_EXECUTE_HANDLER) {
  836. Counter += 10;
  837. }
  838. Counter += 2;
  839. } except (EXCEPTION_EXECUTE_HANDLER) {
  840. Counter += 20;
  841. }
  842. Counter += 3;
  843. }
  844. if (Counter != 30) {
  845. DbgPrint("failed, count = %d\n", Counter);
  846. } else {
  847. DbgPrint("succeeded\n");
  848. }
  849. //
  850. // Continue from doubly nested try body with an finally clause in a loop.
  851. //
  852. DbgPrint(" test33...");
  853. Counter = 0;
  854. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  855. try {
  856. try {
  857. if ((Index1 & 0x1) == 0) {
  858. continue;
  859. } else {
  860. Counter += 1;
  861. }
  862. } finally {
  863. Counter += 2;
  864. }
  865. Counter += 3;
  866. } finally {
  867. Counter += 4;
  868. }
  869. Counter += 5;
  870. }
  871. if (Counter != 105) {
  872. DbgPrint("failed, count = %d\n", Counter);
  873. } else {
  874. DbgPrint("succeeded\n");
  875. }
  876. //
  877. // Continue from a finally clause in a loop.
  878. //
  879. DbgPrint(" test34...");
  880. Counter = 0;
  881. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  882. try {
  883. if ((Index1 & 0x1) == 0) {
  884. Counter += 1;
  885. }
  886. } finally {
  887. Counter += 2;
  888. continue;
  889. }
  890. Counter += 4;
  891. }
  892. if (Counter != 25) {
  893. DbgPrint("failed, count = %d\n", Counter);
  894. } else {
  895. DbgPrint("succeeded\n");
  896. }
  897. //
  898. // Continue from a doubly nested finally clause in a loop.
  899. //
  900. DbgPrint(" test35...");
  901. Counter = 0;
  902. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  903. try {
  904. try {
  905. if ((Index1 & 0x1) == 0) {
  906. Counter += 1;
  907. }
  908. } finally {
  909. Counter += 2;
  910. continue;
  911. }
  912. Counter += 4;
  913. } finally {
  914. Counter += 5;
  915. }
  916. Counter += 6;
  917. }
  918. if (Counter != 75) {
  919. DbgPrint("failed, count = %d\n", Counter);
  920. } else {
  921. DbgPrint("succeeded\n");
  922. }
  923. //
  924. // Continue from a doubly nested finally clause in a loop.
  925. //
  926. DbgPrint(" test36...");
  927. Counter = 0;
  928. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  929. try {
  930. try {
  931. if ((Index1 & 0x1) == 0) {
  932. Counter += 1;
  933. }
  934. } finally {
  935. Counter += 2;
  936. }
  937. Counter += 4;
  938. } finally {
  939. Counter += 5;
  940. continue;
  941. }
  942. Counter += 6;
  943. }
  944. if (Counter != 115) {
  945. DbgPrint("failed, count = %d\n", Counter);
  946. } else {
  947. DbgPrint("succeeded\n");
  948. }
  949. //
  950. // Break from a try body with an exception clause in a loop.
  951. //
  952. DbgPrint(" test37...");
  953. Counter = 0;
  954. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  955. try {
  956. if ((Index1 & 0x1) == 1) {
  957. break;
  958. } else {
  959. Counter += 1;
  960. }
  961. } except (EXCEPTION_EXECUTE_HANDLER) {
  962. Counter += 40;
  963. }
  964. Counter += 2;
  965. }
  966. if (Counter != 3) {
  967. DbgPrint("failed, count = %d\n", Counter);
  968. } else {
  969. DbgPrint("succeeded\n");
  970. }
  971. //
  972. // Break from a try body with an finally clause in a loop.
  973. //
  974. DbgPrint(" test38...");
  975. Counter = 0;
  976. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  977. try {
  978. if ((Index1 & 0x1) == 1) {
  979. break;
  980. } else {
  981. Counter += 1;
  982. }
  983. } finally {
  984. Counter += 2;
  985. }
  986. Counter += 3;
  987. }
  988. if (Counter != 8) {
  989. DbgPrint("failed, count = %d\n", Counter);
  990. } else {
  991. DbgPrint("succeeded\n");
  992. }
  993. //
  994. // Break from doubly nested try body with an exception clause in a
  995. // loop.
  996. //
  997. DbgPrint(" test39...");
  998. Counter = 0;
  999. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1000. try {
  1001. try {
  1002. if ((Index1 & 0x1) == 1) {
  1003. break;
  1004. } else {
  1005. Counter += 1;
  1006. }
  1007. } except (EXCEPTION_EXECUTE_HANDLER) {
  1008. Counter += 10;
  1009. }
  1010. Counter += 2;
  1011. } except (EXCEPTION_EXECUTE_HANDLER) {
  1012. Counter += 20;
  1013. }
  1014. Counter += 3;
  1015. }
  1016. if (Counter != 6) {
  1017. DbgPrint("failed, count = %d\n", Counter);
  1018. } else {
  1019. DbgPrint("succeeded\n");
  1020. }
  1021. //
  1022. // Break from doubly nested try body with an finally clause in a loop.
  1023. //
  1024. DbgPrint(" test40...");
  1025. Counter = 0;
  1026. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1027. try {
  1028. try {
  1029. if ((Index1 & 0x1) == 1) {
  1030. break;
  1031. } else {
  1032. Counter += 1;
  1033. }
  1034. } finally {
  1035. Counter += 2;
  1036. }
  1037. Counter += 3;
  1038. } finally {
  1039. Counter += 4;
  1040. }
  1041. Counter += 5;
  1042. }
  1043. if (Counter != 21) {
  1044. DbgPrint("failed, count = %d\n", Counter);
  1045. } else {
  1046. DbgPrint("succeeded\n");
  1047. }
  1048. //
  1049. // Break from a finally clause in a loop.
  1050. //
  1051. DbgPrint(" test41...");
  1052. Counter = 0;
  1053. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1054. try {
  1055. if ((Index1 & 0x1) == 1) {
  1056. Counter += 1;
  1057. }
  1058. } finally {
  1059. Counter += 2;
  1060. break;
  1061. }
  1062. Counter += 4;
  1063. }
  1064. if (Counter != 2) {
  1065. DbgPrint("failed, count = %d\n", Counter);
  1066. } else {
  1067. DbgPrint("succeeded\n");
  1068. }
  1069. //
  1070. // Break from a doubly nested finally clause in a loop.
  1071. //
  1072. DbgPrint(" test42...");
  1073. Counter = 0;
  1074. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1075. try {
  1076. try {
  1077. if ((Index1 & 0x1) == 1) {
  1078. Counter += 1;
  1079. }
  1080. } finally {
  1081. Counter += 2;
  1082. break;
  1083. }
  1084. Counter += 4;
  1085. } finally {
  1086. Counter += 5;
  1087. }
  1088. Counter += 6;
  1089. }
  1090. if (Counter != 7) {
  1091. DbgPrint("failed, count = %d\n", Counter);
  1092. } else {
  1093. DbgPrint("succeeded\n");
  1094. }
  1095. //
  1096. // Break from a doubly nested finally clause in a loop.
  1097. //
  1098. DbgPrint(" test43...");
  1099. Counter = 0;
  1100. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1101. try {
  1102. try {
  1103. if ((Index1 & 0x1) == 1) {
  1104. Counter += 1;
  1105. }
  1106. } finally {
  1107. Counter += 2;
  1108. }
  1109. Counter += 4;
  1110. } finally {
  1111. Counter += 5;
  1112. break;
  1113. }
  1114. Counter += 6;
  1115. }
  1116. if (Counter != 11) {
  1117. DbgPrint("failed, count = %d\n", Counter);
  1118. } else {
  1119. DbgPrint("succeeded\n");
  1120. }
  1121. //
  1122. // Break from a try body with an exception clause in a switch.
  1123. //
  1124. DbgPrint(" test44...");
  1125. Counter = 0;
  1126. Index1 = 1;
  1127. switch (Index2) {
  1128. case BLUE:
  1129. Counter += 100;
  1130. break;
  1131. case RED:
  1132. try {
  1133. if ((Index1 & 0x1) == 1) {
  1134. break;
  1135. } else {
  1136. Counter += 1;
  1137. }
  1138. } except (EXCEPTION_EXECUTE_HANDLER) {
  1139. Counter += 40;
  1140. }
  1141. Counter += 2;
  1142. break;
  1143. }
  1144. if (Counter != 0) {
  1145. DbgPrint("failed, count = %d\n", Counter);
  1146. } else {
  1147. DbgPrint("succeeded\n");
  1148. }
  1149. //
  1150. // Break from a try body with an finally clause in a switch.
  1151. //
  1152. DbgPrint(" test45...");
  1153. Counter = 0;
  1154. Index1 = 1;
  1155. switch (Index2) {
  1156. case BLUE:
  1157. Counter += 100;
  1158. break;
  1159. case RED:
  1160. try {
  1161. if ((Index1 & 0x1) == 1) {
  1162. break;
  1163. } else {
  1164. Counter += 1;
  1165. }
  1166. } finally {
  1167. Counter += 2;
  1168. }
  1169. Counter += 3;
  1170. }
  1171. if (Counter != 2) {
  1172. DbgPrint("failed, count = %d\n", Counter);
  1173. } else {
  1174. DbgPrint("succeeded\n");
  1175. }
  1176. //
  1177. // Break from doubly nested try body with an exception clause in a
  1178. // switch.
  1179. //
  1180. DbgPrint(" test46...");
  1181. Counter = 0;
  1182. Index1 = 1;
  1183. switch (Index2) {
  1184. case BLUE:
  1185. Counter += 100;
  1186. break;
  1187. case RED:
  1188. try {
  1189. try {
  1190. if ((Index1 & 0x1) == 1) {
  1191. break;
  1192. } else {
  1193. Counter += 1;
  1194. }
  1195. } except (EXCEPTION_EXECUTE_HANDLER) {
  1196. Counter += 10;
  1197. }
  1198. Counter += 2;
  1199. } except (EXCEPTION_EXECUTE_HANDLER) {
  1200. Counter += 20;
  1201. }
  1202. Counter += 3;
  1203. }
  1204. if (Counter != 0) {
  1205. DbgPrint("failed, count = %d\n", Counter);
  1206. } else {
  1207. DbgPrint("succeeded\n");
  1208. }
  1209. //
  1210. // Break from doubly nested try body with an finally clause in a switch.
  1211. //
  1212. DbgPrint(" test47...");
  1213. Counter = 0;
  1214. Index1 = 1;
  1215. switch (Index2) {
  1216. case BLUE:
  1217. Counter += 100;
  1218. break;
  1219. case RED:
  1220. try {
  1221. try {
  1222. if ((Index1 & 0x1) == 1) {
  1223. break;
  1224. } else {
  1225. Counter += 1;
  1226. }
  1227. } finally {
  1228. Counter += 2;
  1229. }
  1230. Counter += 3;
  1231. } finally {
  1232. Counter += 4;
  1233. }
  1234. Counter += 5;
  1235. }
  1236. if (Counter != 6) {
  1237. DbgPrint("failed, count = %d\n", Counter);
  1238. } else {
  1239. DbgPrint("succeeded\n");
  1240. }
  1241. //
  1242. // Break from a finally clause in a switch.
  1243. //
  1244. DbgPrint(" test48...");
  1245. Counter = 0;
  1246. Index1 = 1;
  1247. switch (Index2) {
  1248. case BLUE:
  1249. Counter += 100;
  1250. break;
  1251. case RED:
  1252. try {
  1253. if ((Index1 & 0x1) == 1) {
  1254. Counter += 1;
  1255. }
  1256. } finally {
  1257. Counter += 2;
  1258. break;
  1259. }
  1260. Counter += 4;
  1261. }
  1262. if (Counter != 3) {
  1263. DbgPrint("failed, count = %d\n", Counter);
  1264. } else {
  1265. DbgPrint("succeeded\n");
  1266. }
  1267. //
  1268. // Break from a doubly nested finally clause in a switch.
  1269. //
  1270. DbgPrint(" test49...");
  1271. Counter = 0;
  1272. Index1 = 1;
  1273. switch (Index2) {
  1274. case BLUE:
  1275. Counter += 100;
  1276. break;
  1277. case RED:
  1278. try {
  1279. try {
  1280. if ((Index1 & 0x1) == 1) {
  1281. Counter += 1;
  1282. }
  1283. } finally {
  1284. Counter += 2;
  1285. break;
  1286. }
  1287. Counter += 4;
  1288. } finally {
  1289. Counter += 5;
  1290. }
  1291. Counter += 6;
  1292. }
  1293. if (Counter != 8) {
  1294. DbgPrint("failed, count = %d\n", Counter);
  1295. } else {
  1296. DbgPrint("succeeded\n");
  1297. }
  1298. //
  1299. // Break from a doubly nested finally clause in a switch.
  1300. //
  1301. DbgPrint(" test50...");
  1302. Counter = 0;
  1303. Index1 = 1;
  1304. switch (Index2) {
  1305. case BLUE:
  1306. Counter += 100;
  1307. break;
  1308. case RED:
  1309. try {
  1310. try {
  1311. if ((Index1 & 0x1) == 1) {
  1312. Counter += 1;
  1313. }
  1314. } finally {
  1315. Counter += 2;
  1316. }
  1317. Counter += 4;
  1318. } finally {
  1319. Counter += 5;
  1320. break;
  1321. }
  1322. Counter += 6;
  1323. }
  1324. if (Counter != 12) {
  1325. DbgPrint("failed, count = %d\n", Counter);
  1326. } else {
  1327. DbgPrint("succeeded\n");
  1328. }
  1329. //
  1330. // Leave from an if in a simple try/finally.
  1331. //
  1332. DbgPrint(" test51...");
  1333. Counter = 0;
  1334. try {
  1335. if (Echo(Counter) == Counter) {
  1336. Counter += 3;
  1337. leave;
  1338. } else {
  1339. Counter += 100;
  1340. }
  1341. } finally {
  1342. if (abnormal_termination() == FALSE) {
  1343. Counter += 5;
  1344. }
  1345. }
  1346. if (Counter != 8) {
  1347. DbgPrint("failed, count = %d\n", Counter);
  1348. } else {
  1349. DbgPrint("succeeded\n");
  1350. }
  1351. //
  1352. // Leave from a loop in a simple try/finally.
  1353. //
  1354. DbgPrint(" test52...");
  1355. Counter = 0;
  1356. try {
  1357. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1358. if (Echo(Index1) == Index1) {
  1359. Counter += 3;
  1360. leave;
  1361. }
  1362. Counter += 100;
  1363. }
  1364. } finally {
  1365. if (abnormal_termination() == FALSE) {
  1366. Counter += 5;
  1367. }
  1368. }
  1369. if (Counter != 8) {
  1370. DbgPrint("failed, count = %d\n", Counter);
  1371. } else {
  1372. DbgPrint("succeeded\n");
  1373. }
  1374. //
  1375. // Leave from a switch in a simple try/finally.
  1376. //
  1377. DbgPrint(" test53...");
  1378. Counter = 0;
  1379. try {
  1380. switch (Index2) {
  1381. case BLUE:
  1382. break;
  1383. case RED:
  1384. Counter += 3;
  1385. leave;
  1386. }
  1387. Counter += 100;
  1388. } finally {
  1389. if (abnormal_termination() == FALSE) {
  1390. Counter += 5;
  1391. }
  1392. }
  1393. if (Counter != 8) {
  1394. DbgPrint("failed, count = %d\n", Counter);
  1395. } else {
  1396. DbgPrint("succeeded\n");
  1397. }
  1398. //
  1399. // Leave from an if in doubly nested try/finally followed by a leave
  1400. // from an if in the outer try/finally.
  1401. //
  1402. DbgPrint(" test54...");
  1403. Counter = 0;
  1404. try {
  1405. try {
  1406. if (Echo(Counter) == Counter) {
  1407. Counter += 3;
  1408. leave;
  1409. } else {
  1410. Counter += 100;
  1411. }
  1412. } finally {
  1413. if (abnormal_termination() == FALSE) {
  1414. Counter += 5;
  1415. }
  1416. }
  1417. if (Echo(Counter) == Counter) {
  1418. Counter += 3;
  1419. leave;
  1420. } else {
  1421. Counter += 100;
  1422. }
  1423. } finally {
  1424. if (abnormal_termination() == FALSE) {
  1425. Counter += 5;
  1426. }
  1427. }
  1428. if (Counter != 16) {
  1429. DbgPrint("failed, count = %d\n", Counter);
  1430. } else {
  1431. DbgPrint("succeeded\n");
  1432. }
  1433. //
  1434. // Leave from an if in doubly nested try/finally followed by a leave
  1435. // from the finally of the outer try/finally.
  1436. //
  1437. DbgPrint(" test55...");
  1438. Counter = 0;
  1439. try {
  1440. try {
  1441. if (Echo(Counter) == Counter) {
  1442. Counter += 3;
  1443. leave;
  1444. } else {
  1445. Counter += 100;
  1446. }
  1447. } finally {
  1448. if (abnormal_termination() == FALSE) {
  1449. Counter += 5;
  1450. leave;
  1451. }
  1452. }
  1453. Counter += 100;
  1454. } finally {
  1455. if (abnormal_termination() == FALSE) {
  1456. Counter += 5;
  1457. }
  1458. }
  1459. if (Counter != 13) {
  1460. DbgPrint("failed, count = %d\n", Counter);
  1461. } else {
  1462. DbgPrint("succeeded\n");
  1463. }
  1464. //
  1465. // Try/finally within the except clause of a try/except that is always
  1466. // executed.
  1467. //
  1468. DbgPrint(" test56...");
  1469. Counter = 0;
  1470. try {
  1471. Counter += 1;
  1472. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1473. } except (Counter) {
  1474. try {
  1475. Counter += 3;
  1476. } finally {
  1477. if (abnormal_termination() == FALSE) {
  1478. Counter += 5;
  1479. }
  1480. }
  1481. }
  1482. if (Counter != 9) {
  1483. DbgPrint("failed, count = %d\n", Counter);
  1484. } else {
  1485. DbgPrint("succeeded\n");
  1486. }
  1487. //
  1488. // Try/finally within the finally clause of a try/finally.
  1489. //
  1490. DbgPrint(" test57...");
  1491. Counter = 0;
  1492. try {
  1493. Counter += 1;
  1494. } finally {
  1495. if (abnormal_termination() == FALSE) {
  1496. try {
  1497. Counter += 3;
  1498. } finally {
  1499. if (abnormal_termination() == FALSE) {
  1500. Counter += 5;
  1501. }
  1502. }
  1503. }
  1504. }
  1505. if (Counter != 9) {
  1506. DbgPrint("failed, count = %d\n", Counter);
  1507. } else {
  1508. DbgPrint("succeeded\n");
  1509. }
  1510. //
  1511. // Try/except within the finally clause of a try/finally.
  1512. //
  1513. DbgPrint(" test58...");
  1514. Counter = 0;
  1515. try {
  1516. Counter -= 1;
  1517. } finally {
  1518. try {
  1519. Counter += 2;
  1520. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1521. } except (Counter) {
  1522. try {
  1523. Counter += 3;
  1524. } finally {
  1525. if (abnormal_termination() == FALSE) {
  1526. Counter += 5;
  1527. }
  1528. }
  1529. }
  1530. }
  1531. if (Counter != 9) {
  1532. DbgPrint("failed, count = %d\n", Counter);
  1533. } else {
  1534. DbgPrint("succeeded\n");
  1535. }
  1536. //
  1537. // Try/except within the except clause of a try/except that is always
  1538. // executed.
  1539. //
  1540. DbgPrint(" test59...");
  1541. Counter = 0;
  1542. try {
  1543. Counter += 1;
  1544. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1545. } except (Counter) {
  1546. try {
  1547. Counter += 3;
  1548. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1549. } except(Counter - 3) {
  1550. Counter += 5;
  1551. }
  1552. }
  1553. if (Counter != 9) {
  1554. DbgPrint("failed, count = %d\n", Counter);
  1555. } else {
  1556. DbgPrint("succeeded\n");
  1557. }
  1558. //
  1559. // Try with a Try which exits the scope with a goto
  1560. //
  1561. DbgPrint(" test60...");
  1562. Counter = 0;
  1563. try {
  1564. try {
  1565. goto outside;
  1566. } except(1) {
  1567. Counter += 1;
  1568. }
  1569. outside:
  1570. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1571. } except(1) {
  1572. Counter += 3;
  1573. }
  1574. if (Counter != 3) {
  1575. DbgPrint("failed, count = %d\n", Counter);
  1576. } else {
  1577. DbgPrint("succeeded\n");
  1578. }
  1579. //
  1580. // Try/except which gets an exception from a subfunction within
  1581. // a try/finally which has a try/except in the finally clause
  1582. //
  1583. DbgPrint(" test61...");
  1584. Counter = 0;
  1585. try {
  1586. Test61Part2 (&Counter);
  1587. } except (EXCEPTION_EXECUTE_HANDLER) {
  1588. Counter += 11;
  1589. }
  1590. if (Counter != 24) {
  1591. DbgPrint("failed, count = %d\n", Counter);
  1592. } else {
  1593. DbgPrint("succeeded\n");
  1594. }
  1595. //
  1596. // Try/except within a try/except where the outer try/except gets
  1597. // a floating overflow exception.
  1598. //
  1599. DbgPrint(" test62...");
  1600. _controlfp(_controlfp(0,0) & ~EM_OVERFLOW, _MCW_EM);
  1601. Counter = 0;
  1602. try {
  1603. doubleresult = SquareDouble(1.7e300);
  1604. try {
  1605. doubleresult = SquareDouble (1.0);
  1606. } except (EXCEPTION_EXECUTE_HANDLER) {
  1607. Counter += 3;
  1608. }
  1609. } except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ?
  1610. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1611. Counter += 1;
  1612. }
  1613. if (Counter != 1) {
  1614. DbgPrint("failed, count = %d\n", Counter);
  1615. } else {
  1616. DbgPrint("succeeded\n");
  1617. }
  1618. _clearfp ();
  1619. //
  1620. // Try/except within a try/except where the outer try/except gets
  1621. // a floating overflow exception in a subfunction.
  1622. //
  1623. DbgPrint(" test63...");
  1624. Counter = 0;
  1625. try {
  1626. SquareDouble17E300((PVOID)&doubleresult);
  1627. try {
  1628. SquareDouble17E300((PVOID)&doubleresult);
  1629. } except (EXCEPTION_EXECUTE_HANDLER) {
  1630. Counter += 3;
  1631. }
  1632. } except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ?
  1633. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1634. Counter += 1;
  1635. }
  1636. if (Counter != 1) {
  1637. DbgPrint("failed, count = %d\n", Counter);
  1638. } else {
  1639. DbgPrint("succeeded\n");
  1640. }
  1641. _clearfp ();
  1642. //
  1643. // Try/finally within a try/except where the finally body causes an
  1644. // exception that leads to a collided unwind during the exception
  1645. // dispatch.
  1646. //
  1647. DbgPrint(" test64...");
  1648. Counter = 0;
  1649. try {
  1650. Counter += 1;
  1651. try {
  1652. Counter += 1;
  1653. FAULT;
  1654. Counter += 20;
  1655. } finally {
  1656. if (abnormal_termination() == FALSE) {
  1657. Counter += 20;
  1658. } else {
  1659. Counter += 1;
  1660. FAULT;
  1661. }
  1662. }
  1663. } except (EXCEPTION_EXECUTE_HANDLER) {
  1664. Counter += 10;
  1665. }
  1666. if (Counter != 13) {
  1667. DbgPrint("failed, count = %d\n", Counter);
  1668. } else {
  1669. DbgPrint("succeeded\n");
  1670. }
  1671. //
  1672. // Try/finally within a try/finally within a try/except that leads to a
  1673. // collided unwind during the exception dispatch.
  1674. //
  1675. DbgPrint(" test65...");
  1676. Counter = 0;
  1677. try {
  1678. Counter += 1;
  1679. try {
  1680. Counter += 1;
  1681. FAULT;
  1682. Counter += 20;
  1683. } finally {
  1684. if (abnormal_termination() == FALSE) {
  1685. Counter += 20;
  1686. } else {
  1687. try {
  1688. Counter += 1;
  1689. FAULT;
  1690. Counter += 20;
  1691. } finally {
  1692. if (abnormal_termination() == FALSE) {
  1693. Counter += 20;
  1694. } else {
  1695. Counter += 1;
  1696. }
  1697. }
  1698. }
  1699. FAULT;
  1700. }
  1701. } except (EXCEPTION_EXECUTE_HANDLER) {
  1702. Counter += 10;
  1703. }
  1704. if (Counter != 14) {
  1705. DbgPrint("failed, count = %d\n", Counter);
  1706. } else {
  1707. DbgPrint("succeeded\n");
  1708. }
  1709. //
  1710. // A call to a function with a try/finally that returns out of the try
  1711. // body.
  1712. //
  1713. DbgPrint(" test66...");
  1714. Counter = 0;
  1715. if ((test66sub(&Counter) + 1) != Counter) {
  1716. DbgPrint("failed, count = %d\n", Counter);
  1717. } else {
  1718. DbgPrint("succeeded\n");
  1719. }
  1720. //
  1721. // A call to a function with a try finally that returnss out of the
  1722. // termination hander.
  1723. //
  1724. DbgPrint(" test67...");
  1725. Counter = 0;
  1726. if (test67sub(&Counter) != Counter) {
  1727. DbgPrint("failed, count = %d\n", Counter);
  1728. } else {
  1729. DbgPrint("succeeded\n");
  1730. }
  1731. //
  1732. // Announce end of exception test.
  1733. //
  1734. DbgBreakPoint();
  1735. DbgPrint("End of exception test\n");
  1736. return;
  1737. }
  1738. VOID
  1739. addtwo (
  1740. long First,
  1741. long Second,
  1742. long *Place
  1743. )
  1744. {
  1745. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1746. *Place = First + Second;
  1747. return;
  1748. }
  1749. VOID
  1750. bar1 (
  1751. IN NTSTATUS Status,
  1752. IN PLONG Counter
  1753. )
  1754. {
  1755. try {
  1756. foo1(Status);
  1757. } finally {
  1758. if (abnormal_termination() != FALSE) {
  1759. *Counter = 99;
  1760. } else {
  1761. *Counter = 100;
  1762. }
  1763. }
  1764. return;
  1765. }
  1766. VOID
  1767. bar2 (
  1768. IN PLONG BlackHole,
  1769. IN PLONG BadAddress,
  1770. IN PLONG Counter
  1771. )
  1772. {
  1773. try {
  1774. foo2(BlackHole, BadAddress);
  1775. } finally {
  1776. if (abnormal_termination() != FALSE) {
  1777. *Counter = 99;
  1778. } else {
  1779. *Counter = 100;
  1780. }
  1781. }
  1782. return;
  1783. }
  1784. VOID
  1785. dojump (
  1786. IN jmp_buf JumpBuffer,
  1787. IN PLONG Counter
  1788. )
  1789. {
  1790. try {
  1791. try {
  1792. *Counter += 1;
  1793. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1794. } finally {
  1795. *Counter += 1;
  1796. }
  1797. } finally {
  1798. *Counter += 1;
  1799. longjmp(JumpBuffer, 1);
  1800. }
  1801. }
  1802. VOID
  1803. eret(
  1804. IN NTSTATUS Status,
  1805. IN PLONG Counter
  1806. )
  1807. {
  1808. try {
  1809. try {
  1810. foo1(Status);
  1811. } except ((GetExceptionCode() == Status) ?
  1812. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1813. *Counter += 1;
  1814. return;
  1815. }
  1816. } finally {
  1817. *Counter += 1;
  1818. }
  1819. return;
  1820. }
  1821. VOID
  1822. except1 (
  1823. IN PLONG Counter
  1824. )
  1825. {
  1826. try {
  1827. *Counter += 5;
  1828. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1829. } except (except3(GetExceptionInformation(), Counter)) {
  1830. *Counter += 7;
  1831. }
  1832. *Counter += 9;
  1833. return;
  1834. }
  1835. ULONG
  1836. except2 (
  1837. IN PEXCEPTION_POINTERS ExceptionPointers,
  1838. IN PLONG Counter
  1839. )
  1840. {
  1841. PEXCEPTION_RECORD ExceptionRecord;
  1842. ExceptionRecord = ExceptionPointers->ExceptionRecord;
  1843. if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) &&
  1844. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) {
  1845. *Counter += 11;
  1846. return EXCEPTION_EXECUTE_HANDLER;
  1847. } else {
  1848. *Counter += 13;
  1849. return EXCEPTION_CONTINUE_SEARCH;
  1850. }
  1851. }
  1852. ULONG
  1853. except3 (
  1854. IN PEXCEPTION_POINTERS ExceptionPointers,
  1855. IN PLONG Counter
  1856. )
  1857. {
  1858. PEXCEPTION_RECORD ExceptionRecord;
  1859. ExceptionRecord = ExceptionPointers->ExceptionRecord;
  1860. if ((ExceptionRecord->ExceptionCode == STATUS_INTEGER_OVERFLOW) &&
  1861. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) {
  1862. *Counter += 17;
  1863. RtlRaiseStatus(STATUS_UNSUCCESSFUL);
  1864. } else if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) &&
  1865. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) != 0)) {
  1866. *Counter += 19;
  1867. return EXCEPTION_CONTINUE_SEARCH;
  1868. }
  1869. *Counter += 23;
  1870. return EXCEPTION_EXECUTE_HANDLER;
  1871. }
  1872. VOID
  1873. foo1 (
  1874. IN NTSTATUS Status
  1875. )
  1876. {
  1877. //
  1878. // Raise exception.
  1879. //
  1880. RtlRaiseStatus(Status);
  1881. return;
  1882. }
  1883. VOID
  1884. foo2 (
  1885. IN PLONG BlackHole,
  1886. IN PLONG BadAddress
  1887. )
  1888. {
  1889. //
  1890. // Raise exception.
  1891. //
  1892. *BlackHole += *BadAddress;
  1893. return;
  1894. }
  1895. VOID
  1896. fret (
  1897. IN PLONG Counter
  1898. )
  1899. {
  1900. try {
  1901. try {
  1902. *Counter += 1;
  1903. } finally {
  1904. *Counter += 1;
  1905. return;
  1906. }
  1907. } finally {
  1908. *Counter += 1;
  1909. }
  1910. return;
  1911. }
  1912. LONG
  1913. Echo (
  1914. IN LONG Value
  1915. )
  1916. {
  1917. return Value;
  1918. }
  1919. VOID
  1920. Test61Part2 (
  1921. IN OUT PULONG Counter
  1922. )
  1923. {
  1924. try {
  1925. *Counter -= 1;
  1926. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1927. } finally {
  1928. *Counter += 2;
  1929. *Counter += 5;
  1930. *Counter += 7;
  1931. }
  1932. }
  1933. double
  1934. SquareDouble (
  1935. IN double op
  1936. )
  1937. {
  1938. return op * op;
  1939. }
  1940. VOID
  1941. SquareDouble17E300 (
  1942. OUT PVOID output
  1943. )
  1944. {
  1945. double ans;
  1946. ans = SquareDouble (1.7e300);
  1947. *(double *) output = ans;
  1948. }
  1949. LONG
  1950. test66sub (
  1951. IN PLONG Counter
  1952. )
  1953. {
  1954. *Counter += 1;
  1955. try {
  1956. *Counter += 1;
  1957. return(*Counter);
  1958. } finally {
  1959. *Counter += 1;
  1960. }
  1961. }
  1962. LONG
  1963. test67sub (
  1964. IN PLONG Counter
  1965. )
  1966. {
  1967. *Counter += 1;
  1968. try {
  1969. *Counter += 1;
  1970. } finally {
  1971. *Counter += 1;
  1972. return(*Counter);
  1973. }
  1974. }