badAltHandler.m 2.5 KB

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