passenger 3.0.21 → 3.9.1.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -0,0 +1,1126 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2010, 2011, 2012 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _GNU_SOURCE
26
+ #define _GNU_SOURCE
27
+ #endif
28
+
29
+ #include <oxt/initialize.hpp>
30
+ #include <oxt/system_calls.hpp>
31
+ #include <oxt/backtrace.hpp>
32
+ #include <sys/types.h>
33
+ #include <sys/select.h>
34
+ #ifdef __linux__
35
+ #include <sys/syscall.h>
36
+ #endif
37
+ #include <cstdio>
38
+ #include <cstdlib>
39
+ #include <cstring>
40
+ #include <cerrno>
41
+ #include <fcntl.h>
42
+ #include <poll.h>
43
+ #include <unistd.h>
44
+ #include <signal.h>
45
+ #include <libgen.h>
46
+
47
+ #if defined(__APPLE__) || defined(__linux__)
48
+ #define LIBC_HAS_BACKTRACE_FUNC
49
+ #endif
50
+ #ifdef LIBC_HAS_BACKTRACE_FUNC
51
+ #include <execinfo.h>
52
+ #endif
53
+
54
+ #include <string>
55
+ #include <vector>
56
+
57
+ #include <agents/Base.h>
58
+ #include <Constants.h>
59
+ #include <Exceptions.h>
60
+ #include <Logging.h>
61
+ #include <Utils.h>
62
+ #include <Utils/StrIntUtils.h>
63
+ #ifdef __linux__
64
+ #include <ResourceLocator.h>
65
+ #endif
66
+
67
+ namespace Passenger {
68
+
69
+
70
+ using namespace std;
71
+
72
+
73
+ struct AbortHandlerState {
74
+ pid_t pid;
75
+ int signo;
76
+ siginfo_t *info;
77
+ char messagePrefix[32];
78
+ char messageBuf[1024];
79
+ };
80
+
81
+ typedef void (*Callback)(AbortHandlerState &state, void *userData);
82
+
83
+
84
+ static bool _feedbackFdAvailable = false;
85
+ static const char digits[] = {
86
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
87
+ };
88
+ static const char hex_chars[] = "01234567890abcdef";
89
+
90
+ static bool shouldDumpWithCrashWatch = true;
91
+ static bool beepOnAbort = false;
92
+ static bool stopOnAbort = false;
93
+
94
+ // Pre-allocate an alternative stack for use in signal handlers in case
95
+ // the normal stack isn't usable.
96
+ static char *alternativeStack;
97
+ static unsigned int alternativeStackSize;
98
+
99
+ static char *argv0 = NULL;
100
+ static char *backtraceSanitizerPath = NULL;
101
+ static DiagnosticsDumper customDiagnosticsDumper = NULL;
102
+ static void *customDiagnosticsDumperUserData;
103
+
104
+
105
+ static void
106
+ ignoreSigpipe() {
107
+ struct sigaction action;
108
+ action.sa_handler = SIG_IGN;
109
+ action.sa_flags = 0;
110
+ sigemptyset(&action.sa_mask);
111
+ sigaction(SIGPIPE, &action, NULL);
112
+ }
113
+
114
+ static bool
115
+ hasEnvOption(const char *name, bool defaultValue = false) {
116
+ const char *value = getenv(name);
117
+ if (value != NULL) {
118
+ if (*value != '\0') {
119
+ return strcmp(value, "yes") == 0
120
+ || strcmp(value, "y") == 0
121
+ || strcmp(value, "1") == 0
122
+ || strcmp(value, "on") == 0
123
+ || strcmp(value, "true") == 0;
124
+ } else {
125
+ return defaultValue;
126
+ }
127
+ } else {
128
+ return defaultValue;
129
+ }
130
+ }
131
+
132
+ // Async-signal safe way to fork().
133
+ // http://sourceware.org/bugzilla/show_bug.cgi?id=4737
134
+ static pid_t
135
+ asyncFork() {
136
+ #if defined(__linux__)
137
+ return (pid_t) syscall(SYS_fork);
138
+ #else
139
+ return fork();
140
+ #endif
141
+ }
142
+
143
+ // No idea whether strlen() is async signal safe, but let's not risk it
144
+ // and write our own version instead that's guaranteed to be safe.
145
+ static size_t
146
+ safeStrlen(const char *str) {
147
+ size_t size = 0;
148
+ while (*str != '\0') {
149
+ str++;
150
+ size++;
151
+ }
152
+ return size;
153
+ }
154
+
155
+ // Async-signal safe way to print to stderr.
156
+ static void
157
+ safePrintErr(const char *message) {
158
+ write(STDERR_FILENO, message, strlen(message));
159
+ }
160
+
161
+ // Must be async signal safe.
162
+ static char *
163
+ appendText(char *buf, const char *text) {
164
+ size_t len = safeStrlen(text);
165
+ strcpy(buf, text);
166
+ return buf + len;
167
+ }
168
+
169
+ // Must be async signal safe.
170
+ static void
171
+ reverse(char *str, size_t len) {
172
+ char *p1, *p2;
173
+ if (*str == '\0') {
174
+ return;
175
+ }
176
+ for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) {
177
+ *p1 ^= *p2;
178
+ *p2 ^= *p1;
179
+ *p1 ^= *p2;
180
+ }
181
+ }
182
+
183
+ // Must be async signal safe.
184
+ static char *
185
+ appendULL(char *buf, unsigned long long value) {
186
+ unsigned long long remainder = value;
187
+ unsigned int size = 0;
188
+
189
+ do {
190
+ buf[size] = digits[remainder % 10];
191
+ remainder = remainder / 10;
192
+ size++;
193
+ } while (remainder != 0);
194
+
195
+ reverse(buf, size);
196
+ return buf + size;
197
+ }
198
+
199
+ // Must be async signal safe.
200
+ template<typename IntegerType>
201
+ static char *
202
+ appendIntegerAsHex(char *buf, IntegerType value) {
203
+ IntegerType remainder = value;
204
+ unsigned int size = 0;
205
+
206
+ do {
207
+ buf[size] = hex_chars[remainder % 16];
208
+ remainder = remainder / 16;
209
+ size++;
210
+ } while (remainder != 0);
211
+
212
+ reverse(buf, size);
213
+ return buf + size;
214
+ }
215
+
216
+ // Must be async signal safe.
217
+ static char *
218
+ appendPointerAsString(char *buf, void *pointer) {
219
+ // Use wierd union construction to avoid compiler warnings.
220
+ if (sizeof(void *) == sizeof(unsigned int)) {
221
+ union {
222
+ void *pointer;
223
+ unsigned int value;
224
+ } u;
225
+ u.pointer = pointer;
226
+ return appendIntegerAsHex(appendText(buf, "0x"), u.value);
227
+ } else if (sizeof(void *) == sizeof(unsigned long long)) {
228
+ union {
229
+ void *pointer;
230
+ unsigned long long value;
231
+ } u;
232
+ u.pointer = pointer;
233
+ return appendIntegerAsHex(appendText(buf, "0x"), u.value);
234
+ } else {
235
+ return appendText(buf, "(pointer size unsupported)");
236
+ }
237
+ }
238
+
239
+ static char *
240
+ appendSignalName(char *buf, int signo) {
241
+ switch (signo) {
242
+ case SIGABRT:
243
+ buf = appendText(buf, "SIGABRT");
244
+ break;
245
+ case SIGSEGV:
246
+ buf = appendText(buf, "SIGSEGV");
247
+ break;
248
+ case SIGBUS:
249
+ buf = appendText(buf, "SIGBUS");
250
+ break;
251
+ case SIGFPE:
252
+ buf = appendText(buf, "SIGFPE");
253
+ break;
254
+ default:
255
+ return appendULL(buf, (unsigned long long) signo);
256
+ }
257
+ buf = appendText(buf, "(");
258
+ buf = appendULL(buf, (unsigned long long) signo);
259
+ buf = appendText(buf, ")");
260
+ return buf;
261
+ }
262
+
263
+ #define SI_CODE_HANDLER(name) \
264
+ case name: \
265
+ buf = appendText(buf, #name); \
266
+ break
267
+
268
+ // Must be async signal safe.
269
+ static char *
270
+ appendSignalReason(char *buf, siginfo_t *info) {
271
+ bool handled = true;
272
+
273
+ switch (info->si_code) {
274
+ SI_CODE_HANDLER(SI_USER);
275
+ #ifdef SI_KERNEL
276
+ SI_CODE_HANDLER(SI_KERNEL);
277
+ #endif
278
+ SI_CODE_HANDLER(SI_QUEUE);
279
+ SI_CODE_HANDLER(SI_TIMER);
280
+ #ifdef SI_ASYNCIO
281
+ SI_CODE_HANDLER(SI_ASYNCIO);
282
+ #endif
283
+ #ifdef SI_MESGQ
284
+ SI_CODE_HANDLER(SI_MESGQ);
285
+ #endif
286
+ #ifdef SI_SIGIO
287
+ SI_CODE_HANDLER(SI_SIGIO);
288
+ #endif
289
+ #ifdef SI_TKILL
290
+ SI_CODE_HANDLER(SI_TKILL);
291
+ #endif
292
+ default:
293
+ switch (info->si_signo) {
294
+ case SIGSEGV:
295
+ switch (info->si_code) {
296
+ #ifdef SEGV_MAPERR
297
+ SI_CODE_HANDLER(SEGV_MAPERR);
298
+ #endif
299
+ #ifdef SEGV_ACCERR
300
+ SI_CODE_HANDLER(SEGV_ACCERR);
301
+ #endif
302
+ default:
303
+ handled = false;
304
+ break;
305
+ }
306
+ break;
307
+ case SIGBUS:
308
+ switch (info->si_code) {
309
+ #ifdef BUS_ADRALN
310
+ SI_CODE_HANDLER(BUS_ADRALN);
311
+ #endif
312
+ #ifdef BUS_ADRERR
313
+ SI_CODE_HANDLER(BUS_ADRERR);
314
+ #endif
315
+ #ifdef BUS_OBJERR
316
+ SI_CODE_HANDLER(BUS_OBJERR);
317
+ #endif
318
+ default:
319
+ handled = false;
320
+ break;
321
+ }
322
+ break;
323
+ default:
324
+ handled = false;
325
+ break;
326
+ }
327
+ if (!handled) {
328
+ buf = appendText(buf, "#");
329
+ buf = appendULL(buf, (unsigned long long) info->si_code);
330
+ }
331
+ break;
332
+ }
333
+
334
+ if (info->si_code <= 0) {
335
+ buf = appendText(buf, ", signal sent by PID ");
336
+ buf = appendULL(buf, (unsigned long long) info->si_pid);
337
+ buf = appendText(buf, " with UID ");
338
+ buf = appendULL(buf, (unsigned long long) info->si_uid);
339
+ }
340
+
341
+ buf = appendText(buf, ", si_addr=");
342
+ buf = appendPointerAsString(buf, info->si_addr);
343
+
344
+ return buf;
345
+ }
346
+
347
+ static void
348
+ runInSubprocessWithTimeLimit(AbortHandlerState &state, Callback callback, void *userData, int timeLimit) {
349
+ char *end;
350
+ pid_t child;
351
+ int p[2], e;
352
+
353
+ if (pipe(p) == -1) {
354
+ e = errno;
355
+ end = state.messageBuf;
356
+ end = appendText(end, "Could not dump diagnostics: pipe() failed with errno=");
357
+ end = appendULL(end, e);
358
+ end = appendText(end, "\n");
359
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
360
+ return;
361
+ }
362
+
363
+ child = asyncFork();
364
+ if (child == 0) {
365
+ close(p[0]);
366
+ callback(state, userData);
367
+ _exit(0);
368
+
369
+ } else if (child == -1) {
370
+ e = errno;
371
+ close(p[0]);
372
+ close(p[1]);
373
+ end = state.messageBuf;
374
+ end = appendText(end, "Could not dump diagnostics: fork() failed with errno=");
375
+ end = appendULL(end, e);
376
+ end = appendText(end, "\n");
377
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
378
+
379
+ } else {
380
+ close(p[1]);
381
+
382
+ // We give the child process a time limit. If it doesn't succeed in
383
+ // exiting within the time limit, we assume that it has frozen
384
+ // and we kill it.
385
+ struct pollfd fd;
386
+ fd.fd = p[0];
387
+ fd.events = POLLIN | POLLHUP | POLLERR;
388
+ if (poll(&fd, 1, timeLimit) <= 0) {
389
+ kill(child, SIGKILL);
390
+ safePrintErr("Could not dump diagnostics: child process did not exit in time\n");
391
+ }
392
+ close(p[0]);
393
+ waitpid(child, NULL, 0);
394
+ }
395
+ }
396
+
397
+ static void
398
+ dumpWithCrashWatch(AbortHandlerState &state) {
399
+ char *messageBuf = state.messageBuf;
400
+ const char *pidStr = messageBuf;
401
+ char *end = messageBuf;
402
+ end = appendULL(end, (unsigned long long) state.pid);
403
+ *end = '\0';
404
+
405
+ pid_t child = asyncFork();
406
+ if (child == 0) {
407
+ execlp("crash-watch", "crash-watch", "--dump", pidStr, (char * const) 0);
408
+ if (errno == ENOENT) {
409
+ safePrintErr("Crash-watch is not installed. Please install it with 'gem install crash-watch' "
410
+ "or download it from https://github.com/FooBarWidget/crash-watch.\n");
411
+ } else {
412
+ int e = errno;
413
+ end = messageBuf;
414
+ end = appendText(end, "crash-watch is installed, but it could not be executed! ");
415
+ end = appendText(end, "(execlp() returned errno=");
416
+ end = appendULL(end, e);
417
+ end = appendText(end, ") Please check your file permissions or something.\n");
418
+ write(STDERR_FILENO, messageBuf, end - messageBuf);
419
+ }
420
+ _exit(1);
421
+
422
+ } else if (child == -1) {
423
+ int e = errno;
424
+ end = messageBuf;
425
+ end = appendText(end, "Could not execute crash-watch: fork() failed with errno=");
426
+ end = appendULL(end, e);
427
+ end = appendText(end, "\n");
428
+ write(STDERR_FILENO, messageBuf, end - messageBuf);
429
+
430
+ } else {
431
+ waitpid(child, NULL, 0);
432
+ }
433
+ }
434
+
435
+ #ifdef LIBC_HAS_BACKTRACE_FUNC
436
+ static void
437
+ dumpBacktrace(AbortHandlerState &state, void *userData) {
438
+ void *backtraceStore[512];
439
+ int frames = backtrace(backtraceStore, sizeof(backtraceStore) / sizeof(void *));
440
+ char *end = state.messageBuf;
441
+ end = appendText(end, "--------------------------------------\n");
442
+ end = appendText(end, "[ pid=");
443
+ end = appendULL(end, (unsigned long long) state.pid);
444
+ end = appendText(end, " ] Backtrace with ");
445
+ end = appendULL(end, (unsigned long long) frames);
446
+ end = appendText(end, " frames:\n");
447
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
448
+
449
+ if (backtraceSanitizerPath != NULL) {
450
+ int p[2];
451
+ if (pipe(p) == -1) {
452
+ int e = errno;
453
+ end = state.messageBuf;
454
+ end = appendText(end, "Could not dump diagnostics: pipe() failed with errno=");
455
+ end = appendULL(end, e);
456
+ end = appendText(end, "\n");
457
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
458
+ return;
459
+ }
460
+
461
+ pid_t pid = asyncFork();
462
+ if (pid == 0) {
463
+ const char *pidStr = end = state.messageBuf;
464
+ end = appendULL(end, (unsigned long long) state.pid);
465
+ *end = '\0';
466
+
467
+ close(p[1]);
468
+ dup2(p[0], STDIN_FILENO);
469
+ execlp(backtraceSanitizerPath, backtraceSanitizerPath, argv0,
470
+ pidStr, (const char * const) 0);
471
+ safePrintErr("ERROR: cannot execute 'backtrace-sanitizer.rb', trying 'cat'...\n");
472
+ execlp("cat", "cat", (const char * const) 0);
473
+ safePrintErr("ERROR: cannot execute 'cat'\n");
474
+ _exit(1);
475
+
476
+ } else if (pid == -1) {
477
+ close(p[0]);
478
+ close(p[1]);
479
+
480
+ } else {
481
+ close(p[0]);
482
+ backtrace_symbols_fd(backtraceStore, frames, p[1]);
483
+ close(p[1]);
484
+ waitpid(pid, NULL, 0);
485
+ }
486
+
487
+ } else {
488
+ backtrace_symbols_fd(backtraceStore, frames, STDERR_FILENO);
489
+ }
490
+ }
491
+ #endif
492
+
493
+ static void
494
+ runCustomDiagnosticsDumper(AbortHandlerState &state, void *userData) {
495
+ customDiagnosticsDumper(customDiagnosticsDumperUserData);
496
+ }
497
+
498
+ static void
499
+ dumpDiagnostics(AbortHandlerState &state) {
500
+ char *messageBuf = state.messageBuf;
501
+
502
+ // It is important that writing the message and the backtrace are two
503
+ // seperate operations because it's not entirely clear whether the
504
+ // latter is async signal safe and thus can crash.
505
+ char *end = messageBuf;
506
+ end = appendText(end, state.messagePrefix);
507
+ #ifdef LIBC_HAS_BACKTRACE_FUNC
508
+ end = appendText(end, " ] libc backtrace available!\n");
509
+ #else
510
+ end = appendText(end, " ] libc backtrace not available.\n");
511
+ #endif
512
+ write(STDERR_FILENO, messageBuf, end - messageBuf);
513
+
514
+ #ifdef LIBC_HAS_BACKTRACE_FUNC
515
+ runInSubprocessWithTimeLimit(state, dumpBacktrace, NULL, 4000);
516
+ #endif
517
+
518
+ safePrintErr("--------------------------------------\n");
519
+
520
+ if (customDiagnosticsDumper != NULL) {
521
+ end = messageBuf;
522
+ end = appendText(end, state.messagePrefix);
523
+ end = appendText(end, " ] Dumping additional diagnostical information...\n");
524
+ write(STDERR_FILENO, messageBuf, end - messageBuf);
525
+ safePrintErr("--------------------------------------\n");
526
+ runInSubprocessWithTimeLimit(state, runCustomDiagnosticsDumper, NULL, 2000);
527
+ safePrintErr("--------------------------------------\n");
528
+ }
529
+
530
+ if (shouldDumpWithCrashWatch) {
531
+ end = messageBuf;
532
+ end = appendText(end, state.messagePrefix);
533
+ #ifdef LIBC_HAS_BACKTRACE_FUNC
534
+ end = appendText(end, " ] Dumping a more detailed backtrace with crash-watch...\n");
535
+ #else
536
+ end = appendText(end, " ] Dumping a backtrace with crash-watch...\n");
537
+ #endif
538
+ write(STDERR_FILENO, messageBuf, end - messageBuf);
539
+ dumpWithCrashWatch(state);
540
+ } else {
541
+ write(STDERR_FILENO, "\n", 1);
542
+ }
543
+ }
544
+
545
+ static void
546
+ abortHandler(int signo, siginfo_t *info, void *ctx) {
547
+ AbortHandlerState state;
548
+ state.pid = getpid();
549
+ state.signo = signo;
550
+ state.info = info;
551
+ pid_t child;
552
+
553
+ char *end = state.messagePrefix;
554
+ end = appendText(end, "[ pid=");
555
+ end = appendULL(end, (unsigned long long) state.pid);
556
+ *end = '\0';
557
+
558
+ end = state.messageBuf;
559
+ end = appendText(end, state.messagePrefix);
560
+ end = appendText(end, ", timestamp=");
561
+ end = appendULL(end, (unsigned long long) time(NULL));
562
+ end = appendText(end, " ] Process aborted! signo=");
563
+ end = appendSignalName(end, state.signo);
564
+ end = appendText(end, ", reason=");
565
+ end = appendSignalReason(end, state.info);
566
+ end = appendText(end, "\n");
567
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
568
+
569
+ if (beepOnAbort) {
570
+ end = state.messageBuf;
571
+ end = appendText(end, state.messagePrefix);
572
+ end = appendText(end, " ] PASSENGER_BEEP_ON_ABORT on, executing beep...\n");
573
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
574
+
575
+ child = asyncFork();
576
+ if (child == 0) {
577
+ #ifdef __APPLE__
578
+ execlp("osascript", "osascript", "-e", "beep 2", (const char * const) 0);
579
+ safePrintErr("Cannot execute 'osascript' command\n");
580
+ #else
581
+ execlp("beep", "beep", (const char * const) 0);
582
+ safePrintErr("Cannot execute 'beep' command\n");
583
+ #endif
584
+ _exit(1);
585
+
586
+ } else if (child == -1) {
587
+ int e = errno;
588
+ end = state.messageBuf;
589
+ end = appendText(end, state.messagePrefix);
590
+ end = appendText(end, " ] Could fork a child process for invoking a beep: fork() failed with errno=");
591
+ end = appendULL(end, e);
592
+ end = appendText(end, "\n");
593
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
594
+ }
595
+ }
596
+
597
+ if (stopOnAbort) {
598
+ end = state.messageBuf;
599
+ end = appendText(end, state.messagePrefix);
600
+ end = appendText(end, " ] PASSENGER_STOP_ON_ABORT on, so process stopped. Send SIGCONT when you want to continue.\n");
601
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
602
+ raise(SIGSTOP);
603
+ }
604
+
605
+ // It isn't safe to call any waiting functions in this signal handler,
606
+ // not even read() and waitpid() even though they're async signal safe.
607
+ // So we fork a child process and let it dump as much diagnostics as possible
608
+ // instead of doing it in this process.
609
+ child = asyncFork();
610
+ if (child == 0) {
611
+ // Sleep for a short while to allow the parent process to raise SIGSTOP.
612
+ // usleep() and nanosleep() aren't async signal safe so we use select()
613
+ // instead.
614
+ struct timeval tv;
615
+ tv.tv_sec = 0;
616
+ tv.tv_usec = 100000;
617
+ select(0, NULL, NULL, NULL, &tv);
618
+
619
+ resetSignalHandlersAndMask();
620
+
621
+ child = asyncFork();
622
+ if (child == 0) {
623
+ dumpDiagnostics(state);
624
+ // The child process may or may or may not resume the original process.
625
+ // We do it ourselves just to be sure.
626
+ kill(state.pid, SIGCONT);
627
+ _exit(0);
628
+
629
+ } else if (child == -1) {
630
+ int e = errno;
631
+ end = state.messageBuf;
632
+ end = appendText(end, state.messagePrefix);
633
+ end = appendText(end, "] Could fork a child process for dumping diagnostics: fork() failed with errno=");
634
+ end = appendULL(end, e);
635
+ end = appendText(end, "\n");
636
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
637
+ _exit(1);
638
+
639
+ } else {
640
+ // Exit immediately so that child process is adopted by init process.
641
+ _exit(0);
642
+ }
643
+
644
+ } else if (child == -1) {
645
+ int e = errno;
646
+ end = state.messageBuf;
647
+ end = appendText(end, state.messagePrefix);
648
+ end = appendText(end, " ] Could fork a child process for dumping diagnostics: fork() failed with errno=");
649
+ end = appendULL(end, e);
650
+ end = appendText(end, "\n");
651
+ write(STDERR_FILENO, state.messageBuf, end - state.messageBuf);
652
+
653
+ } else {
654
+ raise(SIGSTOP);
655
+ // Will continue after the child process has done its job.
656
+ }
657
+
658
+ // Run default signal handler.
659
+ raise(signo);
660
+ }
661
+
662
+ void
663
+ installAbortHandler() {
664
+ alternativeStackSize = MINSIGSTKSZ + 128 * 1024;
665
+ alternativeStack = (char *) malloc(alternativeStackSize);
666
+ if (alternativeStack == NULL) {
667
+ fprintf(stderr, "Cannot allocate an alternative with a size of %u bytes!\n",
668
+ alternativeStackSize);
669
+ fflush(stderr);
670
+ abort();
671
+ }
672
+
673
+ stack_t stack;
674
+ stack.ss_sp = alternativeStack;
675
+ stack.ss_size = alternativeStackSize;
676
+ stack.ss_flags = 0;
677
+ if (sigaltstack(&stack, NULL) != 0) {
678
+ int e = errno;
679
+ fprintf(stderr, "Cannot install an alternative stack for use in signal handlers: %s (%d)\n",
680
+ strerror(e), e);
681
+ fflush(stderr);
682
+ abort();
683
+ }
684
+
685
+ struct sigaction action;
686
+ action.sa_sigaction = abortHandler;
687
+ action.sa_flags = SA_RESETHAND | SA_SIGINFO;
688
+ sigemptyset(&action.sa_mask);
689
+ sigaction(SIGABRT, &action, NULL);
690
+ sigaction(SIGSEGV, &action, NULL);
691
+ sigaction(SIGBUS, &action, NULL);
692
+ sigaction(SIGFPE, &action, NULL);
693
+ }
694
+
695
+ void
696
+ installDiagnosticsDumper(DiagnosticsDumper func, void *userData) {
697
+ customDiagnosticsDumper = func;
698
+ customDiagnosticsDumperUserData = userData;
699
+ }
700
+
701
+ bool
702
+ feedbackFdAvailable() {
703
+ return _feedbackFdAvailable;
704
+ }
705
+
706
+ static int
707
+ lookupErrno(const char *name) {
708
+ struct Entry {
709
+ int errorCode;
710
+ const char * const name;
711
+ };
712
+ static const Entry entries[] = {
713
+ { EPERM, "EPERM" },
714
+ { ENOENT, "ENOENT" },
715
+ { ESRCH, "ESRCH" },
716
+ { EINTR, "EINTR" },
717
+ { EBADF, "EBADF" },
718
+ { ENOMEM, "ENOMEM" },
719
+ { EACCES, "EACCES" },
720
+ { EBUSY, "EBUSY" },
721
+ { EEXIST, "EEXIST" },
722
+ { ENOTDIR, "ENOTDIR" },
723
+ { EISDIR, "EISDIR" },
724
+ { EINVAL, "EINVAL" },
725
+ { ENFILE, "ENFILE" },
726
+ { EMFILE, "EMFILE" },
727
+ { ENOTTY, "ENOTTY" },
728
+ { ETXTBSY, "ETXTBSY" },
729
+ { ENOSPC, "ENOSPC" },
730
+ { ESPIPE, "ESPIPE" },
731
+ { EMLINK, "EMLINK" },
732
+ { EPIPE, "EPIPE" },
733
+ { EAGAIN, "EAGAIN" },
734
+ { EWOULDBLOCK, "EWOULDBLOCK" },
735
+ { EINPROGRESS, "EINPROGRESS" },
736
+ { EADDRINUSE, "EADDRINUSE" },
737
+ { EADDRNOTAVAIL, "EADDRNOTAVAIL" },
738
+ { ENETUNREACH, "ENETUNREACH" },
739
+ { ECONNABORTED, "ECONNABORTED" },
740
+ { ECONNRESET, "ECONNRESET" },
741
+ { EISCONN, "EISCONN" },
742
+ { ENOTCONN, "ENOTCONN" },
743
+ { ETIMEDOUT, "ETIMEDOUT" },
744
+ { ECONNREFUSED, "ECONNREFUSED" },
745
+ { EHOSTDOWN, "EHOSTDOWN" },
746
+ { EHOSTUNREACH, "EHOSTUNREACH" },
747
+ #ifdef EIO
748
+ { EIO, "EIO" },
749
+ #endif
750
+ #ifdef ENXIO
751
+ { ENXIO, "ENXIO" },
752
+ #endif
753
+ #ifdef E2BIG
754
+ { E2BIG, "E2BIG" },
755
+ #endif
756
+ #ifdef ENOEXEC
757
+ { ENOEXEC, "ENOEXEC" },
758
+ #endif
759
+ #ifdef ECHILD
760
+ { ECHILD, "ECHILD" },
761
+ #endif
762
+ #ifdef EDEADLK
763
+ { EDEADLK, "EDEADLK" },
764
+ #endif
765
+ #ifdef EFAULT
766
+ { EFAULT, "EFAULT" },
767
+ #endif
768
+ #ifdef ENOTBLK
769
+ { ENOTBLK, "ENOTBLK" },
770
+ #endif
771
+ #ifdef EXDEV
772
+ { EXDEV, "EXDEV" },
773
+ #endif
774
+ #ifdef ENODEV
775
+ { ENODEV, "ENODEV" },
776
+ #endif
777
+ #ifdef EFBIG
778
+ { EFBIG, "EFBIG" },
779
+ #endif
780
+ #ifdef EROFS
781
+ { EROFS, "EROFS" },
782
+ #endif
783
+ #ifdef EDOM
784
+ { EDOM, "EDOM" },
785
+ #endif
786
+ #ifdef ERANGE
787
+ { ERANGE, "ERANGE" },
788
+ #endif
789
+ #ifdef EALREADY
790
+ { EALREADY, "EALREADY" },
791
+ #endif
792
+ #ifdef ENOTSOCK
793
+ { ENOTSOCK, "ENOTSOCK" },
794
+ #endif
795
+ #ifdef EDESTADDRREQ
796
+ { EDESTADDRREQ, "EDESTADDRREQ" },
797
+ #endif
798
+ #ifdef EMSGSIZE
799
+ { EMSGSIZE, "EMSGSIZE" },
800
+ #endif
801
+ #ifdef EPROTOTYPE
802
+ { EPROTOTYPE, "EPROTOTYPE" },
803
+ #endif
804
+ #ifdef ENOPROTOOPT
805
+ { ENOPROTOOPT, "ENOPROTOOPT" },
806
+ #endif
807
+ #ifdef EPROTONOSUPPORT
808
+ { EPROTONOSUPPORT, "EPROTONOSUPPORT" },
809
+ #endif
810
+ #ifdef ESOCKTNOSUPPORT
811
+ { ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT" },
812
+ #endif
813
+ #ifdef ENOTSUP
814
+ { ENOTSUP, "ENOTSUP" },
815
+ #endif
816
+ #ifdef EOPNOTSUPP
817
+ { EOPNOTSUPP, "EOPNOTSUPP" },
818
+ #endif
819
+ #ifdef EPFNOSUPPORT
820
+ { EPFNOSUPPORT, "EPFNOSUPPORT" },
821
+ #endif
822
+ #ifdef EAFNOSUPPORT
823
+ { EAFNOSUPPORT, "EAFNOSUPPORT" },
824
+ #endif
825
+ #ifdef ENETDOWN
826
+ { ENETDOWN, "ENETDOWN" },
827
+ #endif
828
+ #ifdef ENETRESET
829
+ { ENETRESET, "ENETRESET" },
830
+ #endif
831
+ #ifdef ENOBUFS
832
+ { ENOBUFS, "ENOBUFS" },
833
+ #endif
834
+ #ifdef ESHUTDOWN
835
+ { ESHUTDOWN, "ESHUTDOWN" },
836
+ #endif
837
+ #ifdef ETOOMANYREFS
838
+ { ETOOMANYREFS, "ETOOMANYREFS" },
839
+ #endif
840
+ #ifdef ELOOP
841
+ { ELOOP, "ELOOP" },
842
+ #endif
843
+ #ifdef ENAMETOOLONG
844
+ { ENAMETOOLONG, "ENAMETOOLONG" },
845
+ #endif
846
+ #ifdef ENOTEMPTY
847
+ { ENOTEMPTY, "ENOTEMPTY" },
848
+ #endif
849
+ #ifdef EPROCLIM
850
+ { EPROCLIM, "EPROCLIM" },
851
+ #endif
852
+ #ifdef EUSERS
853
+ { EUSERS, "EUSERS" },
854
+ #endif
855
+ #ifdef EDQUOT
856
+ { EDQUOT, "EDQUOT" },
857
+ #endif
858
+ #ifdef ESTALE
859
+ { ESTALE, "ESTALE" },
860
+ #endif
861
+ #ifdef EREMOTE
862
+ { EREMOTE, "EREMOTE" },
863
+ #endif
864
+ #ifdef EBADRPC
865
+ { EBADRPC, "EBADRPC" },
866
+ #endif
867
+ #ifdef ERPCMISMATCH
868
+ { ERPCMISMATCH, "ERPCMISMATCH" },
869
+ #endif
870
+ #ifdef EPROGUNAVAIL
871
+ { EPROGUNAVAIL, "EPROGUNAVAIL" },
872
+ #endif
873
+ #ifdef EPROGMISMATCH
874
+ { EPROGMISMATCH, "EPROGMISMATCH" },
875
+ #endif
876
+ #ifdef EPROCUNAVAIL
877
+ { EPROCUNAVAIL, "EPROCUNAVAIL" },
878
+ #endif
879
+ #ifdef ENOLCK
880
+ { ENOLCK, "ENOLCK" },
881
+ #endif
882
+ #ifdef ENOSYS
883
+ { ENOSYS, "ENOSYS" },
884
+ #endif
885
+ #ifdef EFTYPE
886
+ { EFTYPE, "EFTYPE" },
887
+ #endif
888
+ #ifdef EAUTH
889
+ { EAUTH, "EAUTH" },
890
+ #endif
891
+ #ifdef ENEEDAUTH
892
+ { ENEEDAUTH, "ENEEDAUTH" },
893
+ #endif
894
+ #ifdef EPWROFF
895
+ { EPWROFF, "EPWROFF" },
896
+ #endif
897
+ #ifdef EDEVERR
898
+ { EDEVERR, "EDEVERR" },
899
+ #endif
900
+ #ifdef EOVERFLOW
901
+ { EOVERFLOW, "EOVERFLOW" },
902
+ #endif
903
+ #ifdef EBADEXEC
904
+ { EBADEXEC, "EBADEXEC" },
905
+ #endif
906
+ #ifdef EBADARCH
907
+ { EBADARCH, "EBADARCH" },
908
+ #endif
909
+ #ifdef ESHLIBVERS
910
+ { ESHLIBVERS, "ESHLIBVERS" },
911
+ #endif
912
+ #ifdef EBADMACHO
913
+ { EBADMACHO, "EBADMACHO" },
914
+ #endif
915
+ #ifdef ECANCELED
916
+ { ECANCELED, "ECANCELED" },
917
+ #endif
918
+ #ifdef EIDRM
919
+ { EIDRM, "EIDRM" },
920
+ #endif
921
+ #ifdef ENOMSG
922
+ { ENOMSG, "ENOMSG" },
923
+ #endif
924
+ #ifdef EILSEQ
925
+ { EILSEQ, "EILSEQ" },
926
+ #endif
927
+ #ifdef ENOATTR
928
+ { ENOATTR, "ENOATTR" },
929
+ #endif
930
+ #ifdef EBADMSG
931
+ { EBADMSG, "EBADMSG" },
932
+ #endif
933
+ #ifdef EMULTIHOP
934
+ { EMULTIHOP, "EMULTIHOP" },
935
+ #endif
936
+ #ifdef ENODATA
937
+ { ENODATA, "ENODATA" },
938
+ #endif
939
+ #ifdef ENOLINK
940
+ { ENOLINK, "ENOLINK" },
941
+ #endif
942
+ #ifdef ENOSR
943
+ { ENOSR, "ENOSR" },
944
+ #endif
945
+ #ifdef ENOSTR
946
+ { ENOSTR, "ENOSTR" },
947
+ #endif
948
+ #ifdef EPROTO
949
+ { EPROTO, "EPROTO" },
950
+ #endif
951
+ #ifdef ETIME
952
+ { ETIME, "ETIME" },
953
+ #endif
954
+ #ifdef EOPNOTSUPP
955
+ { EOPNOTSUPP, "EOPNOTSUPP" },
956
+ #endif
957
+ #ifdef ENOPOLICY
958
+ { ENOPOLICY, "ENOPOLICY" },
959
+ #endif
960
+ #ifdef ENOTRECOVERABLE
961
+ { ENOTRECOVERABLE, "ENOTRECOVERABLE" },
962
+ #endif
963
+ #ifdef EOWNERDEAD
964
+ { EOWNERDEAD, "EOWNERDEAD" },
965
+ #endif
966
+ };
967
+
968
+ for (unsigned int i = 0; i < sizeof(entries) / sizeof(Entry); i++) {
969
+ if (strcmp(entries[i].name, name) == 0) {
970
+ return entries[i].errorCode;
971
+ }
972
+ }
973
+ return -1;
974
+ }
975
+
976
+ static void
977
+ initializeSyscallFailureSimulation(const char *processName) {
978
+ // Format:
979
+ // PassengerWatchdog=EMFILE:0.1,ECONNREFUSED:0.25;PassengerHelperAgent=ESPIPE=0.4
980
+ const char *spec = getenv("PASSENGER_SIMULATE_SYSCALL_FAILURES");
981
+ string prefix = string(processName) + "=";
982
+ vector<string> components;
983
+ unsigned int i;
984
+
985
+ // Lookup this process in the specification string.
986
+ split(spec, ';', components);
987
+ for (i = 0; i < components.size(); i++) {
988
+ if (startsWith(components[i], prefix)) {
989
+ // Found!
990
+ string value = components[i].substr(prefix.size());
991
+ split(value, ',', components);
992
+ vector<string> keyAndValue;
993
+ vector<ErrorChance> chances;
994
+
995
+ // Process each errorCode:chance pair.
996
+ for (i = 0; i < components.size(); i++) {
997
+ split(components[i], ':', keyAndValue);
998
+ if (keyAndValue.size() != 2) {
999
+ fprintf(stderr, "%s: invalid syntax in PASSENGER_SIMULATE_SYSCALL_FAILURES: '%s'\n",
1000
+ processName, components[i].c_str());
1001
+ continue;
1002
+ }
1003
+
1004
+ int e = lookupErrno(keyAndValue[0].c_str());
1005
+ if (e == -1) {
1006
+ fprintf(stderr, "%s: invalid error code in PASSENGER_SIMULATE_SYSCALL_FAILURES: '%s'\n",
1007
+ processName, components[i].c_str());
1008
+ continue;
1009
+ }
1010
+
1011
+ ErrorChance chance;
1012
+ chance.chance = atof(keyAndValue[1].c_str());
1013
+ if (chance.chance < 0 || chance.chance > 1) {
1014
+ fprintf(stderr, "%s: invalid chance PASSENGER_SIMULATE_SYSCALL_FAILURES: '%s' - chance must be between 0 and 1\n",
1015
+ processName, components[i].c_str());
1016
+ continue;
1017
+ }
1018
+ chance.errorCode = e;
1019
+ chances.push_back(chance);
1020
+ }
1021
+
1022
+ // Install the chances.
1023
+ setup_random_failure_simulation(&chances[0], chances.size());
1024
+ return;
1025
+ }
1026
+ }
1027
+ }
1028
+
1029
+ VariantMap
1030
+ initializeAgent(int argc, char *argv[], const char *processName) {
1031
+ VariantMap options;
1032
+
1033
+ srand((unsigned int) time(NULL));
1034
+ srandom((unsigned int) time(NULL));
1035
+
1036
+ ignoreSigpipe();
1037
+ if (hasEnvOption("PASSENGER_ABORT_HANDLER", true)) {
1038
+ shouldDumpWithCrashWatch = hasEnvOption("PASSENGER_DUMP_WITH_CRASH_WATCH", true);
1039
+ beepOnAbort = hasEnvOption("PASSENGER_BEEP_ON_ABORT", false);
1040
+ stopOnAbort = hasEnvOption("PASSENGER_STOP_ON_ABORT", false);
1041
+ installAbortHandler();
1042
+ }
1043
+ oxt::initialize();
1044
+ setup_syscall_interruption_support();
1045
+ if (getenv("PASSENGER_SIMULATE_SYSCALL_FAILURES")) {
1046
+ initializeSyscallFailureSimulation(processName);
1047
+ }
1048
+ setvbuf(stdout, NULL, _IONBF, 0);
1049
+ setvbuf(stderr, NULL, _IONBF, 0);
1050
+
1051
+ TRACE_POINT();
1052
+ try {
1053
+ if (argc == 1) {
1054
+ int ret = fcntl(FEEDBACK_FD, F_GETFL);
1055
+ if (ret == -1) {
1056
+ if (errno == EBADF) {
1057
+ fprintf(stderr,
1058
+ "You're not supposed to start this program from the command line. "
1059
+ "It's used internally by Phusion Passenger.\n");
1060
+ exit(1);
1061
+ } else {
1062
+ int e = errno;
1063
+ fprintf(stderr,
1064
+ "Encountered an error in feedback file descriptor 3: %s (%d)\n",
1065
+ strerror(e), e);
1066
+ exit(1);
1067
+ }
1068
+ } else {
1069
+ _feedbackFdAvailable = true;
1070
+ options.readFrom(FEEDBACK_FD);
1071
+ if (options.getBool("fire_and_forget", false)) {
1072
+ _feedbackFdAvailable = false;
1073
+ close(FEEDBACK_FD);
1074
+ }
1075
+ }
1076
+ } else {
1077
+ options.readFrom((const char **) argv + 1, argc - 1);
1078
+ }
1079
+
1080
+ #ifdef __linux__
1081
+ if (options.has("passenger_root")) {
1082
+ ResourceLocator locator(options.get("passenger_root", true));
1083
+ backtraceSanitizerPath = strdup((locator.getHelperScriptsDir() + "/backtrace-sanitizer.rb").c_str());
1084
+ }
1085
+ #endif
1086
+
1087
+ setLogLevel(options.getInt("log_level", false, 0));
1088
+ if (!options.get("debug_log_file", false).empty()) {
1089
+ if (strcmp(processName, "PassengerWatchdog") == 0) {
1090
+ /* Have the watchdog set STDOUT and STDERR to the debug
1091
+ * log file so that system abort() calls that stuff
1092
+ * are properly logged.
1093
+ */
1094
+ string filename = options.get("debug_log_file");
1095
+ options.erase("debug_log_file");
1096
+
1097
+ int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644);
1098
+ if (fd == -1) {
1099
+ int e = errno;
1100
+ throw FileSystemException("Cannot open debug log file " +
1101
+ filename, e, filename);
1102
+ }
1103
+
1104
+ dup2(fd, STDOUT_FILENO);
1105
+ dup2(fd, STDERR_FILENO);
1106
+ close(fd);
1107
+ } else {
1108
+ setDebugFile(options.get("debug_log_file").c_str());
1109
+ }
1110
+ }
1111
+ } catch (const tracable_exception &e) {
1112
+ P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
1113
+ exit(1);
1114
+ }
1115
+
1116
+ // Change process title.
1117
+ argv0 = strdup(argv[0]);
1118
+ strncpy(argv[0], processName, strlen(argv[0]));
1119
+ for (int i = 1; i < argc; i++) {
1120
+ memset(argv[i], '\0', strlen(argv[i]));
1121
+ }
1122
+
1123
+ return options;
1124
+ }
1125
+
1126
+ } // namespace Passenger