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.

140 lines
4.8 KiB

  1. mysql is not accounting for the "guard page" when setting thread stack size
  2. requests. This is fatal on PPC systems, which may use guard pages as large
  3. as 64K. This patch also documents the IA64 situation a bit better.
  4. Note: there are quite a few other setstacksize calls besides the two in
  5. mysqld.cc; is it important to fix any of the others?
  6. Filed upstream at http://bugs.mysql.com/bug.php?id=35019
  7. diff -Naur mysql-5.1.30.orig/sql/mysqld.cc mysql-5.1.30/sql/mysqld.cc
  8. --- mysql-5.1.30.orig/sql/mysqld.cc 2008-11-14 11:37:13.000000000 -0500
  9. +++ mysql-5.1.30/sql/mysqld.cc 2009-01-13 12:08:35.000000000 -0500
  10. @@ -2653,6 +2653,70 @@
  11. }
  12. +/* pthread_attr_setstacksize without so much platform-dependency */
  13. +/* returns the actual stack size if possible */
  14. +static size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
  15. +{
  16. + size_t guard_size = 0;
  17. +
  18. +#if defined(__ia64__) || defined(__ia64)
  19. + /*
  20. + On IA64, half of the requested stack size is used for "normal stack"
  21. + and half for "register stack". The space measured by check_stack_overrun
  22. + is the "normal stack", so double the request to make sure we have the
  23. + caller-expected amount of normal stack.
  24. +
  25. + NOTE: there is no guarantee that the register stack can't grow faster
  26. + than normal stack, so it's very unclear that we won't dump core due to
  27. + stack overrun despite check_stack_overrun's efforts. Experimentation
  28. + shows that in the execution_constants test, the register stack grows
  29. + less than half as fast as normal stack, but perhaps other scenarios are
  30. + less forgiving. If it turns out that more space is needed for the
  31. + register stack, that could be forced (rather inefficiently) by using a
  32. + multiplier higher than 2 here.
  33. + */
  34. + stacksize *= 2;
  35. +#endif
  36. +
  37. + /*
  38. + On many machines, the "guard space" is subtracted from the requested
  39. + stack size, and that space is quite large on some platforms. So add
  40. + it to our request, if we can find out what it is.
  41. +
  42. + FIXME: autoconfiscate use of pthread_attr_getguardsize
  43. + */
  44. + if (pthread_attr_getguardsize(attr, &guard_size))
  45. + guard_size = 0; /* if can't find it out, treat as 0 */
  46. +
  47. + pthread_attr_setstacksize(attr, stacksize + guard_size);
  48. +
  49. + /* Retrieve actual stack size if possible */
  50. +#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
  51. + {
  52. + size_t real_stack_size= 0;
  53. + /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
  54. + if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
  55. + real_stack_size > guard_size)
  56. + {
  57. + real_stack_size -= guard_size;
  58. + if (real_stack_size < stacksize)
  59. + {
  60. + if (global_system_variables.log_warnings)
  61. + sql_print_warning("Asked for %ld thread stack, but got %ld",
  62. + (long) stacksize, (long) real_stack_size);
  63. + stacksize= real_stack_size;
  64. + }
  65. + }
  66. + }
  67. +#endif
  68. +
  69. +#if defined(__ia64__) || defined(__ia64)
  70. + stacksize /= 2;
  71. +#endif
  72. + return stacksize;
  73. +}
  74. +
  75. +
  76. static void start_signal_handler(void)
  77. {
  78. int error;
  79. @@ -2663,15 +2727,7 @@
  80. #if !defined(HAVE_DEC_3_2_THREADS)
  81. pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  82. (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
  83. -#if defined(__ia64__) || defined(__ia64)
  84. - /*
  85. - Peculiar things with ia64 platforms - it seems we only have half the
  86. - stack size in reality, so we have to double it here
  87. - */
  88. - pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
  89. -#else
  90. - pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
  91. -#endif
  92. + (void) my_setstacksize(&thr_attr,my_thread_stack_size);
  93. #endif
  94. mysql_mutex_lock(&LOCK_thread_count);
  95. @@ -4445,37 +4501,7 @@
  96. unireg_abort(1); // Will do exit
  97. init_signals();
  98. -#if defined(__ia64__) || defined(__ia64)
  99. - /*
  100. - Peculiar things with ia64 platforms - it seems we only have half the
  101. - stack size in reality, so we have to double it here
  102. - */
  103. - pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
  104. -#else
  105. - pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
  106. -#endif
  107. -#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
  108. - {
  109. - /* Retrieve used stack size; Needed for checking stack overflows */
  110. - size_t stack_size= 0;
  111. - pthread_attr_getstacksize(&connection_attrib, &stack_size);
  112. -#if defined(__ia64__) || defined(__ia64)
  113. - stack_size/= 2;
  114. -#endif
  115. - /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
  116. - if (stack_size && stack_size < my_thread_stack_size)
  117. - {
  118. - if (global_system_variables.log_warnings)
  119. - sql_print_warning("Asked for %lu thread stack, but got %ld",
  120. - my_thread_stack_size, (long) stack_size);
  121. -#if defined(__ia64__) || defined(__ia64)
  122. - my_thread_stack_size= stack_size*2;
  123. -#else
  124. - my_thread_stack_size= stack_size;
  125. -#endif
  126. - }
  127. - }
  128. -#endif
  129. + my_thread_stack_size = my_setstacksize(&connection_attrib,my_thread_stack_size);
  130. (void) thr_setconcurrency(concurrency); // 10 by default