1// for OBJC2 mac only
2/* TEST_CONFIG SDK=macos ARCH=x86_64
3   TEST_CRASHES
4
5TEST_RUN_OUTPUT
6objc\[\d+\]: objc_removeExceptionHandler\(\) called with unknown alt handler; this is probably a bug in multithreaded AppKit use. Set environment variable OBJC_DEBUG_ALT_HANDLERS=YES or break in objc_alt_handler_error\(\) to debug.
7CRASHED: SIGILL
8END
9*/
10
11#include "test.h"
12
13#include <objc/objc-exception.h>
14
15/*
16  rdar://6888838
17  Mail installs an alt handler on one thread and deletes it on another.
18  This confuses the alt handler machinery, which halts the process.
19*/
20
21uintptr_t Token;
22
23void handler(id unused __unused, void *context __unused)
24{
25}
26
27int main()
28{
29#if __clang__ && __cplusplus
30    // alt handlers need the objc personality
31    // catch (id) workaround forces the objc personality
32    @try {
33        testwarn("rdar://9183014 clang uses wrong exception personality");
34    } @catch (id e __unused) {
35    }
36#endif
37
38    @try {
39        // Install 4 alt handlers
40        uintptr_t t1, t2, t3, t4;
41        t1 = objc_addExceptionHandler(&handler, NULL);
42        t2 = objc_addExceptionHandler(&handler, NULL);
43        t3 = objc_addExceptionHandler(&handler, NULL);
44        t4 = objc_addExceptionHandler(&handler, NULL);
45
46        // Remove 3 of them.
47        objc_removeExceptionHandler(t1);
48        objc_removeExceptionHandler(t2);
49        objc_removeExceptionHandler(t3);
50        
51        // Create an alt handler on another thread 
52        // that collides with one of the removed handlers
53        testonthread(^{
54            @try {
55                Token = objc_addExceptionHandler(&handler, NULL);
56            } @catch (...) {
57            }
58        });
59        
60        // Incorrectly remove the other thread's handler
61        objc_removeExceptionHandler(Token);
62        // Remove the 4th handler
63        objc_removeExceptionHandler(t4);
64        
65        // Install 8 more handlers.
66        // If the other thread's handler was not ignored, 
67        // this will fail.
68        objc_addExceptionHandler(&handler, NULL);
69        objc_addExceptionHandler(&handler, NULL);
70        objc_addExceptionHandler(&handler, NULL);
71        objc_addExceptionHandler(&handler, NULL);
72        objc_addExceptionHandler(&handler, NULL);
73        objc_addExceptionHandler(&handler, NULL);
74        objc_addExceptionHandler(&handler, NULL);
75        objc_addExceptionHandler(&handler, NULL);
76    } @catch (...) {
77    }
78
79    // This should have crashed earlier.
80    fail(__FILE__);
81}
82