passenger 2.0.6 → 2.1.2

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 (497) hide show
  1. data/DEVELOPERS.TXT +10 -4
  2. data/LICENSE +1 -1
  3. data/NEWS +0 -0
  4. data/Rakefile +183 -117
  5. data/benchmark/dispatcher.rb +5 -9
  6. data/bin/passenger-install-apache2-module +52 -18
  7. data/bin/passenger-memory-stats +67 -13
  8. data/bin/passenger-spawn-server +8 -4
  9. data/bin/passenger-status +21 -46
  10. data/bin/passenger-stress-test +5 -5
  11. data/debian/postinst +1 -1
  12. data/doc/ApplicationPool algorithm.txt +180 -128
  13. data/doc/Architectural overview.html +1 -778
  14. data/doc/Security of user switching support.html +1 -643
  15. data/doc/Users guide Apache.html +3127 -0
  16. data/doc/Users guide Nginx.html +1458 -0
  17. data/doc/Users guide.html +1404 -467
  18. data/doc/Users guide.txt +843 -105
  19. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
  20. data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
  21. data/doc/cxxapi/Application_8h-source.html +494 -394
  22. data/doc/cxxapi/Bucket_8h-source.html +21 -15
  23. data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
  24. data/doc/cxxapi/Configuration_8h-source.html +311 -149
  25. data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
  26. data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
  27. data/doc/cxxapi/Exceptions_8h-source.html +182 -165
  28. data/doc/cxxapi/FileChecker_8h-source.html +130 -0
  29. data/doc/cxxapi/Hooks_8h-source.html +2 -3
  30. data/doc/cxxapi/Logging_8h-source.html +92 -89
  31. data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
  32. data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
  33. data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
  34. data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
  35. data/doc/cxxapi/SystemTime_8h-source.html +104 -0
  36. data/doc/cxxapi/Utils_8h-source.html +331 -227
  37. data/doc/cxxapi/annotated.html +6 -7
  38. data/doc/cxxapi/classClient-members.html +1 -2
  39. data/doc/cxxapi/classClient.html +1 -2
  40. data/doc/cxxapi/classHooks-members.html +5 -2
  41. data/doc/cxxapi/classHooks.html +112 -2
  42. data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
  43. data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
  44. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
  45. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
  46. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
  47. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
  48. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  49. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
  50. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
  51. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
  52. data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
  53. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
  54. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
  55. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
  56. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
  57. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
  58. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
  59. data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
  60. data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
  61. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
  62. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
  63. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  64. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
  65. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
  66. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  67. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
  68. data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
  69. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  70. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
  71. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
  72. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
  73. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
  74. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
  75. data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
  76. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
  77. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
  78. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
  79. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
  80. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
  82. data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
  83. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  84. data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
  85. data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
  86. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
  87. data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
  88. data/doc/cxxapi/definitions_8h-source.html +1 -2
  89. data/doc/cxxapi/files.html +6 -3
  90. data/doc/cxxapi/functions.html +98 -35
  91. data/doc/cxxapi/functions_func.html +60 -32
  92. data/doc/cxxapi/functions_type.html +1 -2
  93. data/doc/cxxapi/functions_vars.html +27 -2
  94. data/doc/cxxapi/graph_legend.html +1 -2
  95. data/doc/cxxapi/graph_legend.png +0 -0
  96. data/doc/cxxapi/group__Configuration.html +3 -4
  97. data/doc/cxxapi/group__Configuration.png +0 -0
  98. data/doc/cxxapi/group__Core.html +3 -4
  99. data/doc/cxxapi/group__Core.png +0 -0
  100. data/doc/cxxapi/group__Exceptions.html +4 -2
  101. data/doc/cxxapi/group__Hooks.html +1 -6
  102. data/doc/cxxapi/group__Hooks.png +0 -0
  103. data/doc/cxxapi/group__Support.html +259 -36
  104. data/doc/cxxapi/hierarchy.html +6 -7
  105. data/doc/cxxapi/inherit__graph__0.map +1 -1
  106. data/doc/cxxapi/inherit__graph__0.md5 +1 -1
  107. data/doc/cxxapi/inherit__graph__0.png +0 -0
  108. data/doc/cxxapi/inherit__graph__1.map +1 -1
  109. data/doc/cxxapi/inherit__graph__1.md5 +1 -1
  110. data/doc/cxxapi/inherit__graph__1.png +0 -0
  111. data/doc/cxxapi/inherit__graph__10.map +1 -1
  112. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  113. data/doc/cxxapi/inherit__graph__10.png +0 -0
  114. data/doc/cxxapi/inherit__graph__11.map +1 -1
  115. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  116. data/doc/cxxapi/inherit__graph__11.png +0 -0
  117. data/doc/cxxapi/inherit__graph__12.map +2 -1
  118. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  119. data/doc/cxxapi/inherit__graph__12.png +0 -0
  120. data/doc/cxxapi/inherit__graph__13.map +1 -1
  121. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  122. data/doc/cxxapi/inherit__graph__13.png +0 -0
  123. data/doc/cxxapi/inherit__graph__14.map +1 -2
  124. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  125. data/doc/cxxapi/inherit__graph__14.png +0 -0
  126. data/doc/cxxapi/inherit__graph__15.map +1 -1
  127. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__15.png +0 -0
  129. data/doc/cxxapi/inherit__graph__16.map +1 -1
  130. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__16.png +0 -0
  132. data/doc/cxxapi/inherit__graph__17.png +0 -0
  133. data/doc/cxxapi/inherit__graph__18.png +0 -0
  134. data/doc/cxxapi/inherit__graph__19.png +0 -0
  135. data/doc/cxxapi/inherit__graph__2.map +1 -1
  136. data/doc/cxxapi/inherit__graph__2.md5 +1 -1
  137. data/doc/cxxapi/inherit__graph__2.png +0 -0
  138. data/doc/cxxapi/inherit__graph__20.map +1 -1
  139. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  140. data/doc/cxxapi/inherit__graph__20.png +0 -0
  141. data/doc/cxxapi/inherit__graph__21.map +1 -1
  142. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  143. data/doc/cxxapi/inherit__graph__21.png +0 -0
  144. data/doc/cxxapi/inherit__graph__3.map +1 -1
  145. data/doc/cxxapi/inherit__graph__3.md5 +1 -1
  146. data/doc/cxxapi/inherit__graph__3.png +0 -0
  147. data/doc/cxxapi/inherit__graph__4.map +1 -1
  148. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  149. data/doc/cxxapi/inherit__graph__4.png +0 -0
  150. data/doc/cxxapi/inherit__graph__5.map +2 -1
  151. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  152. data/doc/cxxapi/inherit__graph__5.png +0 -0
  153. data/doc/cxxapi/inherit__graph__6.map +1 -1
  154. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  155. data/doc/cxxapi/inherit__graph__6.png +0 -0
  156. data/doc/cxxapi/inherit__graph__7.map +1 -1
  157. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  158. data/doc/cxxapi/inherit__graph__7.png +0 -0
  159. data/doc/cxxapi/inherit__graph__8.map +1 -1
  160. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  161. data/doc/cxxapi/inherit__graph__8.png +0 -0
  162. data/doc/cxxapi/inherit__graph__9.map +1 -2
  163. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  164. data/doc/cxxapi/inherit__graph__9.png +0 -0
  165. data/doc/cxxapi/inherits.html +30 -31
  166. data/doc/cxxapi/main.html +1 -2
  167. data/doc/cxxapi/modules.html +1 -2
  168. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
  169. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
  170. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
  171. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
  172. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
  173. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
  174. data/doc/cxxapi/tree.html +18 -20
  175. data/doc/images/conservative_spawning.png +0 -0
  176. data/doc/images/conservative_spawning.svg +248 -0
  177. data/doc/images/smart-lv2.png +0 -0
  178. data/doc/images/smart-lv2.svg +320 -0
  179. data/doc/rdoc/classes/ConditionVariable.html +68 -34
  180. data/doc/rdoc/classes/Exception.html +16 -16
  181. data/doc/rdoc/classes/GC.html +9 -9
  182. data/doc/rdoc/classes/IO.html +36 -17
  183. data/doc/rdoc/classes/PhusionPassenger.html +183 -0
  184. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
  185. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
  186. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
  187. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
  188. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
  189. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
  190. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  191. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  192. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
  193. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  194. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
  195. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
  196. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
  197. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
  198. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
  199. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
  200. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  201. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
  202. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
  203. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  204. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
  205. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
  206. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  207. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
  208. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  209. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  210. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
  211. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  212. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
  213. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
  214. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
  215. data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
  216. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
  217. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  218. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  219. data/doc/rdoc/classes/PlatformInfo.html +663 -159
  220. data/doc/rdoc/classes/RakeExtensions.html +4 -4
  221. data/doc/rdoc/classes/Signal.html +134 -0
  222. data/doc/rdoc/created.rid +1 -1
  223. data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
  224. data/doc/rdoc/files/README.html +5 -7
  225. data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
  226. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
  227. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
  228. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
  229. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
  230. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
  231. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
  232. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
  233. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
  234. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
  235. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
  236. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
  237. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
  238. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
  239. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
  240. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
  241. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
  242. data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
  243. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  244. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
  245. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
  246. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
  247. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
  248. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
  249. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
  250. data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
  251. data/doc/rdoc/fr_class_index.html +37 -19
  252. data/doc/rdoc/fr_file_index.html +25 -14
  253. data/doc/rdoc/fr_method_index.html +145 -74
  254. data/ext/apache2/Application.h +145 -44
  255. data/ext/apache2/ApplicationPool.h +27 -29
  256. data/ext/apache2/ApplicationPoolServer.h +183 -72
  257. data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
  258. data/ext/apache2/Bucket.cpp +61 -9
  259. data/ext/apache2/Bucket.h +15 -8
  260. data/ext/apache2/CachedFileStat.cpp +114 -0
  261. data/ext/apache2/CachedFileStat.h +169 -0
  262. data/ext/apache2/Configuration.cpp +213 -22
  263. data/ext/apache2/Configuration.h +176 -13
  264. data/ext/apache2/DirectoryMapper.h +287 -0
  265. data/ext/apache2/Exceptions.h +30 -12
  266. data/ext/apache2/FileChecker.h +108 -0
  267. data/ext/apache2/Hooks.cpp +709 -493
  268. data/ext/apache2/LICENSE-CNRI.TXT +15 -0
  269. data/ext/apache2/Logging.h +26 -22
  270. data/ext/apache2/MessageChannel.h +124 -15
  271. data/ext/apache2/PoolOptions.h +283 -0
  272. data/ext/apache2/SpawnManager.h +75 -99
  273. data/ext/apache2/StandardApplicationPool.h +296 -195
  274. data/ext/apache2/SystemTime.cpp +28 -0
  275. data/ext/apache2/SystemTime.h +82 -0
  276. data/ext/apache2/Utils.cpp +172 -18
  277. data/ext/apache2/Utils.h +124 -19
  278. data/ext/boost/cstdint.hpp +4 -2
  279. data/ext/boost/current_function.hpp +67 -0
  280. data/ext/boost/detail/sp_counted_base.hpp +4 -4
  281. data/ext/boost/thread/exceptions.hpp +2 -1
  282. data/ext/boost/thread/pthread/thread.hpp +11 -3
  283. data/ext/boost/thread/pthread/thread_data.hpp +2 -1
  284. data/ext/oxt/backtrace.cpp +172 -0
  285. data/ext/oxt/backtrace.hpp +135 -0
  286. data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
  287. data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
  288. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
  289. data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
  290. data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
  291. data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
  292. data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
  293. data/ext/oxt/macros.hpp +58 -0
  294. data/ext/oxt/spin_lock.hpp +55 -0
  295. data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
  296. data/ext/oxt/system_calls.hpp +234 -0
  297. data/ext/oxt/thread.cpp +32 -0
  298. data/ext/oxt/thread.hpp +223 -0
  299. data/ext/oxt/tracable_exception.cpp +87 -0
  300. data/ext/oxt/tracable_exception.hpp +35 -0
  301. data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
  302. data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
  303. data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
  304. data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
  305. data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
  306. data/lib/phusion_passenger/admin_tools.rb +25 -0
  307. data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
  308. data/lib/{passenger → phusion_passenger}/application.rb +13 -16
  309. data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
  310. data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
  311. data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
  312. data/lib/phusion_passenger/events.rb +45 -0
  313. data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
  314. data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
  315. data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
  316. data/lib/phusion_passenger/platform_info.rb +500 -0
  317. data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
  318. data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
  319. data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
  320. data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
  321. data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
  322. data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
  323. data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
  324. data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
  325. data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
  326. data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  327. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
  328. data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
  329. data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
  330. data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
  331. data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
  332. data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
  333. data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
  334. data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
  335. data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
  336. data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
  337. data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
  338. data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  339. data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
  340. data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
  341. data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
  342. data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
  343. data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
  344. data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
  345. data/man/passenger-memory-stats.8 +1 -1
  346. data/misc/render_error_pages.rb +1 -1
  347. data/test/ApplicationPoolServerTest.cpp +0 -28
  348. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
  349. data/test/ApplicationPoolTest.cpp +307 -69
  350. data/test/CachedFileStatTest.cpp +262 -0
  351. data/test/FileCheckerTest.cpp +79 -0
  352. data/test/MessageChannelTest.cpp +3 -3
  353. data/test/PoolOptionsTest.cpp +37 -0
  354. data/test/SpawnManagerTest.cpp +4 -4
  355. data/test/StandardApplicationPoolTest.cpp +4 -0
  356. data/test/SystemTimeTest.cpp +37 -0
  357. data/test/UtilsTest.cpp +137 -0
  358. data/test/integration_tests.rb +270 -23
  359. data/test/oxt/backtrace_test.cpp +128 -0
  360. data/test/oxt/oxt_test_main.cpp +25 -0
  361. data/test/oxt/syscall_interruption_test.cpp +50 -0
  362. data/test/ruby/abstract_request_handler_spec.rb +83 -0
  363. data/test/ruby/abstract_server_collection_spec.rb +246 -0
  364. data/test/ruby/application_spec.rb +3 -3
  365. data/test/ruby/message_channel_spec.rb +2 -2
  366. data/test/ruby/rack/application_spawner_spec.rb +3 -5
  367. data/test/ruby/rails/application_spawner_spec.rb +54 -15
  368. data/test/ruby/rails/framework_spawner_spec.rb +6 -8
  369. data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
  370. data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
  371. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
  372. data/test/ruby/spawn_manager_spec.rb +23 -12
  373. data/test/ruby/utils_spec.rb +36 -2
  374. data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
  375. data/test/stub/apache2/httpd.conf.erb +3 -5
  376. data/test/stub/message_channel.rb +2 -2
  377. data/test/stub/message_channel_2.rb +2 -2
  378. data/test/stub/message_channel_3.rb +3 -3
  379. data/test/stub/minimal-railsapp/README +0 -0
  380. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  381. data/test/stub/minimal-railsapp/config/environment.rb +0 -0
  382. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  383. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
  384. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  385. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  386. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
  387. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  388. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
  389. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  390. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  391. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
  392. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
  393. data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
  394. data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
  395. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
  396. data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
  397. data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
  398. data/test/stub/railsapp/app/controllers/application.rb +0 -0
  399. data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
  400. data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
  401. data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
  402. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
  403. data/test/stub/railsapp/config/boot.rb +0 -0
  404. data/test/stub/railsapp/config/database.yml +0 -0
  405. data/test/stub/railsapp/config/environment.rb +0 -0
  406. data/test/stub/railsapp/config/environments/development.rb +0 -0
  407. data/test/stub/railsapp/config/environments/production.rb +0 -0
  408. data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
  409. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
  410. data/test/stub/railsapp/config/routes.rb +0 -0
  411. data/test/stub/railsapp/public/useless.txt +0 -0
  412. data/test/stub/spawn_server.rb +3 -4
  413. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  414. data/test/support/apache2_controller.rb +57 -7
  415. data/test/support/tut.h +15 -0
  416. data/vendor/README +12 -0
  417. data/vendor/README_FOR_PACKAGERS +1 -0
  418. data/vendor/rack-0.9.1/AUTHORS +8 -0
  419. data/vendor/rack-0.9.1/COPYING +18 -0
  420. data/vendor/rack-0.9.1/ChangeLog +1423 -0
  421. data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
  422. data/vendor/rack-0.9.1/README +306 -0
  423. data/vendor/rack-0.9.1/Rakefile +188 -0
  424. data/vendor/rack-0.9.1/SPEC +129 -0
  425. data/vendor/rack-0.9.1/lib/rack.rb +86 -0
  426. data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
  427. data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
  428. data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
  429. data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
  430. data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
  431. data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
  432. data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
  433. data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
  434. data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
  435. data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
  436. data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
  437. data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
  438. data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
  439. data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
  440. data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
  441. data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
  442. data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
  443. data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
  444. data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
  445. data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
  446. data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
  447. data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
  448. data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
  449. data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
  450. data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  451. data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
  452. data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
  453. data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
  454. data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
  455. data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
  456. data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
  457. data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
  458. data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
  459. data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
  460. data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
  461. data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
  462. data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
  463. data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
  464. data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
  465. data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
  466. data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
  467. data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
  468. data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
  469. data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
  470. data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
  471. data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
  472. metadata +1197 -1055
  473. data/doc/cxxapi/System_8h-source.html +0 -251
  474. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  475. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  476. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  477. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  478. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  479. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  480. data/doc/cxxapi/namespacePassenger.html +0 -208
  481. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  482. data/doc/cxxapi/namespacemembers.html +0 -70
  483. data/doc/cxxapi/namespacemembers_func.html +0 -66
  484. data/doc/cxxapi/namespacemembers_type.html +0 -46
  485. data/doc/cxxapi/namespaces.html +0 -35
  486. data/doc/rdoc/classes/Passenger.html +0 -136
  487. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
  488. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
  489. data/doc/rdoc/classes/Passenger/Utils.html +0 -578
  490. data/ext/apache2/System.h +0 -228
  491. data/lib/passenger/platform_info.rb +0 -302
  492. data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
  493. data/test/stub/apache2/httpd.conf +0 -75
  494. data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
  495. data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
  496. data/test/stub/railsapp/config/environments/test.rb +0 -22
  497. data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -36,13 +36,20 @@
36
36
  #include <boost/bind.hpp>
37
37
  #include <boost/thread/thread.hpp>
38
38
 
39
+ #include <oxt/system_calls.hpp>
40
+ #include <oxt/thread.hpp>
41
+ #include <oxt/backtrace.hpp>
42
+
39
43
  #include <sys/types.h>
40
44
  #include <sys/stat.h>
41
45
  #include <sys/time.h>
42
46
  #include <sys/resource.h>
43
47
  #include <unistd.h>
44
48
  #include <signal.h>
49
+ #include <errno.h>
50
+ #include <pwd.h>
45
51
  #include <string>
52
+ #include <sstream>
46
53
  #include <vector>
47
54
  #include <set>
48
55
  #include <map>
@@ -51,12 +58,12 @@
51
58
  #include "StandardApplicationPool.h"
52
59
  #include "Application.h"
53
60
  #include "Logging.h"
54
- #include "System.h"
55
61
  #include "Exceptions.h"
56
62
 
57
63
 
58
64
  using namespace boost;
59
65
  using namespace std;
66
+ using namespace oxt;
60
67
  using namespace Passenger;
61
68
 
62
69
  class Server;
@@ -65,6 +72,15 @@ typedef shared_ptr<Client> ClientPtr;
65
72
 
66
73
  #define SERVER_SOCKET_FD 3
67
74
 
75
+ // The following variables contain pre-calculated data which are used by
76
+ // Server::fatalSignalHandler(). It's not safe to allocate memory inside
77
+ // a signal handler.
78
+
79
+ /** The filename of the ApplicationPoolServerExecutable binary. */
80
+ static string exeFile;
81
+ static string gdbBacktraceGenerationCommand;
82
+ static const char *gdbBacktraceGenerationCommandStr;
83
+
68
84
 
69
85
  /*****************************************
70
86
  * Server
@@ -77,16 +93,19 @@ private:
77
93
  int serverSocket;
78
94
  StandardApplicationPool pool;
79
95
  set<ClientPtr> clients;
80
- mutex lock;
96
+ boost::mutex lock;
81
97
  string statusReportFIFO;
82
- shared_ptr<Thread> statusReportThread;
98
+ shared_ptr<oxt::thread> statusReportThread;
99
+ string user;
83
100
 
84
101
  void statusReportThreadMain() {
102
+ TRACE_POINT();
85
103
  try {
86
104
  while (!this_thread::interruption_requested()) {
87
105
  struct stat buf;
88
106
  int ret;
89
107
 
108
+ UPDATE_TRACE_POINT();
90
109
  do {
91
110
  ret = stat(statusReportFIFO.c_str(), &buf);
92
111
  } while (ret == -1 && errno == EINTR);
@@ -96,17 +115,32 @@ private:
96
115
  break;
97
116
  }
98
117
 
99
- FILE *f = InterruptableCalls::fopen(statusReportFIFO.c_str(), "w");
118
+ UPDATE_TRACE_POINT();
119
+ FILE *f = syscalls::fopen(statusReportFIFO.c_str(), "w");
100
120
  if (f == NULL) {
121
+ int e = errno;
122
+ P_ERROR("Cannot open status report FIFO " <<
123
+ statusReportFIFO << ": " <<
124
+ strerror(e) << " (" << e << ")");
101
125
  break;
102
126
  }
103
127
 
104
- string report(pool.toString());
105
- fwrite(report.c_str(), 1, report.size(), f);
106
- InterruptableCalls::fclose(f);
128
+ UPDATE_TRACE_POINT();
129
+ MessageChannel channel(fileno(f));
130
+ string report;
131
+ report.append("----------- Backtraces -----------\n");
132
+ report.append(oxt::thread::all_backtraces());
133
+ report.append("\n\n");
134
+ report.append(pool.toString());
107
135
 
108
- // Prevent sending too much data at once.
109
- sleep(1);
136
+ UPDATE_TRACE_POINT();
137
+ try {
138
+ channel.writeScalar(report);
139
+ channel.writeScalar(pool.toXml());
140
+ } catch (...) {
141
+ // Ignore write errors.
142
+ }
143
+ syscalls::fclose(f);
110
144
  }
111
145
  } catch (const boost::thread_interrupted &) {
112
146
  P_TRACE(2, "Status report thread interrupted.");
@@ -114,6 +148,7 @@ private:
114
148
  }
115
149
 
116
150
  void deleteStatusReportFIFO() {
151
+ TRACE_POINT();
117
152
  if (!statusReportFIFO.empty()) {
118
153
  int ret;
119
154
  do {
@@ -121,6 +156,134 @@ private:
121
156
  } while (ret == -1 && errno == EINTR);
122
157
  }
123
158
  }
159
+
160
+ /**
161
+ * Lowers this process's privilege to that of <em>username</em>,
162
+ * and sets stricter permissions for the Phusion Passenger temp
163
+ * directory.
164
+ */
165
+ void lowerPrivilege(const string &username) {
166
+ struct passwd *entry;
167
+ int ret, e;
168
+
169
+ entry = getpwnam(username.c_str());
170
+ if (entry != NULL) {
171
+ do {
172
+ ret = chown(getPassengerTempDir().c_str(),
173
+ entry->pw_uid, entry->pw_gid);
174
+ } while (ret == -1 && errno == EINTR);
175
+ if (ret == -1) {
176
+ e = errno;
177
+ P_WARN("WARNING: Unable to change owner for directory '" <<
178
+ getPassengerTempDir() << "' to '" << username <<
179
+ "': " << strerror(e) << " (" << e << ")");
180
+ } else {
181
+ do {
182
+ ret = chmod(getPassengerTempDir().c_str(),
183
+ S_IRUSR | S_IWUSR | S_IXUSR);
184
+ } while (ret == -1 && errno == EINTR);
185
+ if (ret == -1) {
186
+ e = errno;
187
+ P_WARN("WARNING: Unable to change "
188
+ "permissions for directory " <<
189
+ getPassengerTempDir() << ": " <<
190
+ strerror(e) <<
191
+ " (" << e << ")");
192
+ }
193
+ }
194
+
195
+ if (initgroups(username.c_str(), entry->pw_gid) != 0) {
196
+ int e = errno;
197
+ P_WARN("WARNING: Unable to lower ApplicationPoolServerExecutable's "
198
+ "privilege to that of user '" << username <<
199
+ "': cannot set supplementary groups for this "
200
+ "user: " << strerror(e) << " (" << e << ")");
201
+ }
202
+ if (setgid(entry->pw_gid) != 0) {
203
+ int e = errno;
204
+ P_WARN("WARNING: Unable to lower ApplicationPoolServerExecutable's "
205
+ "privilege to that of user '" << username <<
206
+ "': cannot set group ID: " << strerror(e) <<
207
+ " (" << e << ")");
208
+ }
209
+ if (setuid(entry->pw_uid) != 0) {
210
+ int e = errno;
211
+ P_WARN("WARNING: Unable to lower ApplicationPoolServerExecutable's "
212
+ "privilege to that of user '" << username <<
213
+ "': cannot set user ID: " << strerror(e) <<
214
+ " (" << e << ")");
215
+ }
216
+ } else {
217
+ P_WARN("WARNING: Unable to lower ApplicationPoolServerExecutable's "
218
+ "privilege to that of user '" << username <<
219
+ "': user does not exist.");
220
+ }
221
+ }
222
+
223
+ static void fatalSignalHandler(int signum) {
224
+ static void (* const defaultHandler)(int) = SIG_DFL;
225
+ static bool calledBefore = false;
226
+
227
+ if (calledBefore) {
228
+ // If we're here then it means that this signal
229
+ // handler crashed, and we weren't even able to
230
+ // call write() or system()! Abort immediately:
231
+ defaultHandler(signum);
232
+ } else {
233
+ calledBefore = true;
234
+ write(STDERR_FILENO,
235
+ "*** ERROR: ApplicationPoolServerExecutable received a "
236
+ "fatal signal. Running gdb to obtain the backtrace:\n\n",
237
+ sizeof("*** ERROR: ApplicationPoolServerExecutable caught "
238
+ "fatal signal. Running gdb to obtain the backtrace:\n\n") - 1
239
+ );
240
+ write(STDERR_FILENO, "----------------- Begin gdb output -----------------\n",
241
+ sizeof("----------------- Begin gdb output -----------------\n") - 1);
242
+ system(gdbBacktraceGenerationCommandStr);
243
+ write(STDERR_FILENO, "----------------- End gdb output -----------------\n",
244
+ sizeof("----------------- End gdb output -----------------\n") - 1);
245
+ defaultHandler(signum);
246
+ }
247
+ }
248
+
249
+ void setupSignalHandlers() {
250
+ // Ignore SIGPIPE and SIGHUP.
251
+ struct sigaction action;
252
+ action.sa_handler = SIG_IGN;
253
+ action.sa_flags = 0;
254
+ sigemptyset(&action.sa_mask);
255
+ sigaction(SIGPIPE, &action, NULL);
256
+ sigaction(SIGHUP, &action, NULL);
257
+
258
+ // Setup handlers for other signals.
259
+ FILE *f;
260
+ string gdbCommandFile;
261
+
262
+ gdbCommandFile = getPassengerTempDir() + "/gdb_backtrace_command.txt";
263
+ f = fopen(gdbCommandFile.c_str(), "w");
264
+ if (f != NULL) {
265
+ // Write a file which contains commands for gdb to obtain
266
+ // the backtrace of this process.
267
+ fprintf(f, "attach %lu\n", (unsigned long) getpid());
268
+ fprintf(f, "thread apply all bt full\n");
269
+ fclose(f);
270
+ chmod(gdbCommandFile.c_str(), S_IRUSR | S_IRGRP | S_IROTH);
271
+
272
+ gdbBacktraceGenerationCommand = "gdb -n -batch -x \"";
273
+ gdbBacktraceGenerationCommand.append(gdbCommandFile);
274
+ gdbBacktraceGenerationCommand.append("\" < /dev/null");
275
+ gdbBacktraceGenerationCommandStr = gdbBacktraceGenerationCommand.c_str();
276
+
277
+ // Install the signal handlers.
278
+ action.sa_handler = fatalSignalHandler;
279
+ action.sa_flags = 0;
280
+ sigemptyset(&action.sa_mask);
281
+ sigaction(SIGSEGV, &action, NULL);
282
+ sigaction(SIGABRT, &action, NULL);
283
+ sigaction(SIGILL, &action, NULL);
284
+ sigaction(SIGFPE, &action, NULL);
285
+ }
286
+ }
124
287
 
125
288
  public:
126
289
  Server(int serverSocket,
@@ -135,21 +298,25 @@ public:
135
298
  Passenger::setLogLevel(logLevel);
136
299
  this->serverSocket = serverSocket;
137
300
  this->statusReportFIFO = statusReportFIFO;
301
+ this->user = user;
138
302
  }
139
303
 
140
304
  ~Server() {
305
+ TRACE_POINT();
141
306
  this_thread::disable_syscall_interruption dsi;
142
307
  this_thread::disable_interruption di;
143
308
 
144
309
  P_TRACE(2, "Shutting down server.");
145
310
 
146
- InterruptableCalls::close(serverSocket);
311
+ syscalls::close(serverSocket);
147
312
 
148
313
  if (statusReportThread != NULL) {
149
- statusReportThread->interruptAndJoin();
314
+ UPDATE_TRACE_POINT();
315
+ statusReportThread->interrupt_and_join();
150
316
  }
151
317
 
152
318
  // Wait for all clients to disconnect.
319
+ UPDATE_TRACE_POINT();
153
320
  set<ClientPtr> clientsCopy;
154
321
  {
155
322
  /* If we clear _clients_ directly, then it may result in a deadlock.
@@ -157,7 +324,7 @@ public:
157
324
  * the reference counts, and then we release all references outside the critical
158
325
  * section.
159
326
  */
160
- mutex::scoped_lock l(lock);
327
+ boost::mutex::scoped_lock l(lock);
161
328
  clientsCopy = clients;
162
329
  clients.clear();
163
330
  }
@@ -194,7 +361,7 @@ private:
194
361
  MessageChannel channel;
195
362
 
196
363
  /** The thread which handles the client connection. */
197
- Thread *thr;
364
+ oxt::thread *thr;
198
365
 
199
366
  /**
200
367
  * Maps session ID to sessions created by ApplicationPool::get(). Session IDs
@@ -207,15 +374,17 @@ private:
207
374
  int lastSessionID;
208
375
 
209
376
  void processGet(const vector<string> &args) {
377
+ TRACE_POINT();
210
378
  Application::SessionPtr session;
211
379
  bool failed = false;
212
380
 
213
381
  try {
214
- session = server.pool.get(args[1], args[2] == "true", args[3],
215
- args[4], args[5], args[6]);
382
+ PoolOptions options(args, 1);
383
+ session = server.pool.get(options);
216
384
  sessions[lastSessionID] = session;
217
385
  lastSessionID++;
218
386
  } catch (const SpawnException &e) {
387
+ UPDATE_TRACE_POINT();
219
388
  this_thread::disable_syscall_interruption dsi;
220
389
 
221
390
  if (e.hasErrorPage()) {
@@ -230,22 +399,27 @@ private:
230
399
  }
231
400
  failed = true;
232
401
  } catch (const BusyException &e) {
402
+ UPDATE_TRACE_POINT();
233
403
  this_thread::disable_syscall_interruption dsi;
234
404
  channel.write("BusyException", e.what(), NULL);
235
405
  failed = true;
236
406
  } catch (const IOException &e) {
407
+ UPDATE_TRACE_POINT();
237
408
  this_thread::disable_syscall_interruption dsi;
238
409
  channel.write("IOException", e.what(), NULL);
239
410
  failed = true;
240
411
  }
412
+ UPDATE_TRACE_POINT();
241
413
  if (!failed) {
242
414
  this_thread::disable_syscall_interruption dsi;
243
415
  try {
416
+ UPDATE_TRACE_POINT();
244
417
  channel.write("ok", toString(session->getPid()).c_str(),
245
418
  toString(lastSessionID - 1).c_str(), NULL);
246
419
  channel.writeFileDescriptor(session->getStream());
247
420
  session->closeStream();
248
421
  } catch (const exception &) {
422
+ UPDATE_TRACE_POINT();
249
423
  P_TRACE(3, "Client " << this << ": something went wrong "
250
424
  "while sending 'ok' back to the client.");
251
425
  sessions.erase(lastSessionID - 1);
@@ -255,42 +429,47 @@ private:
255
429
  }
256
430
 
257
431
  void processClose(const vector<string> &args) {
432
+ TRACE_POINT();
258
433
  sessions.erase(atoi(args[1]));
259
434
  }
260
435
 
261
436
  void processClear(const vector<string> &args) {
437
+ TRACE_POINT();
262
438
  server.pool.clear();
263
439
  }
264
440
 
265
441
  void processSetMaxIdleTime(const vector<string> &args) {
442
+ TRACE_POINT();
266
443
  server.pool.setMaxIdleTime(atoi(args[1]));
267
444
  }
268
445
 
269
446
  void processSetMax(const vector<string> &args) {
447
+ TRACE_POINT();
270
448
  server.pool.setMax(atoi(args[1]));
271
449
  }
272
450
 
273
451
  void processGetActive(const vector<string> &args) {
452
+ TRACE_POINT();
274
453
  channel.write(toString(server.pool.getActive()).c_str(), NULL);
275
454
  }
276
455
 
277
456
  void processGetCount(const vector<string> &args) {
457
+ TRACE_POINT();
278
458
  channel.write(toString(server.pool.getCount()).c_str(), NULL);
279
459
  }
280
460
 
281
461
  void processSetMaxPerApp(unsigned int maxPerApp) {
462
+ TRACE_POINT();
282
463
  server.pool.setMaxPerApp(maxPerApp);
283
464
  }
284
465
 
285
- void processSetUseGlobalQueue(bool value) {
286
- server.pool.setUseGlobalQueue(value);
287
- }
288
-
289
466
  void processGetSpawnServerPid(const vector<string> &args) {
467
+ TRACE_POINT();
290
468
  channel.write(toString(server.pool.getSpawnServerPid()).c_str(), NULL);
291
469
  }
292
470
 
293
471
  void processUnknownMessage(const vector<string> &args) {
472
+ TRACE_POINT();
294
473
  string name;
295
474
  if (args.empty()) {
296
475
  name = "(null)";
@@ -305,9 +484,11 @@ private:
305
484
  * The entry point of the thread that handles the client connection.
306
485
  */
307
486
  void threadMain(const weak_ptr<Client> self) {
487
+ TRACE_POINT();
308
488
  vector<string> args;
309
489
  try {
310
490
  while (!this_thread::interruption_requested()) {
491
+ UPDATE_TRACE_POINT();
311
492
  try {
312
493
  if (!channel.read(args)) {
313
494
  // Client closed connection.
@@ -322,7 +503,8 @@ private:
322
503
  P_TRACE(4, "Client " << this << ": received message: " <<
323
504
  toString(args));
324
505
 
325
- if (args[0] == "get" && args.size() == 7) {
506
+ UPDATE_TRACE_POINT();
507
+ if (args[0] == "get") {
326
508
  processGet(args);
327
509
  } else if (args[0] == "close" && args.size() == 2) {
328
510
  processClose(args);
@@ -338,8 +520,6 @@ private:
338
520
  processGetCount(args);
339
521
  } else if (args[0] == "setMaxPerApp" && args.size() == 2) {
340
522
  processSetMaxPerApp(atoi(args[1]));
341
- } else if (args[0] == "setUseGlobalQueue" && args.size() == 2) {
342
- processSetUseGlobalQueue(args[1] == "true");
343
523
  } else if (args[0] == "getSpawnServerPid" && args.size() == 1) {
344
524
  processGetSpawnServerPid(args);
345
525
  } else {
@@ -350,13 +530,23 @@ private:
350
530
  }
351
531
  } catch (const boost::thread_interrupted &) {
352
532
  P_TRACE(2, "Client thread " << this << " interrupted.");
533
+ } catch (const tracable_exception &e) {
534
+ P_TRACE(2, "Uncaught exception in ApplicationPoolServer client thread:\n"
535
+ << " message: " << toString(args) << "\n"
536
+ << " exception: " << e.what() << "\n"
537
+ << " backtrace:\n" << e.backtrace());
353
538
  } catch (const exception &e) {
354
539
  P_TRACE(2, "Uncaught exception in ApplicationPoolServer client thread:\n"
355
540
  << " message: " << toString(args) << "\n"
356
- << " exception: " << e.what());
541
+ << " exception: " << e.what() << "\n"
542
+ << " backtrace: not available");
543
+ } catch (...) {
544
+ P_TRACE(2, "Uncaught unknown exception in ApplicationPool client thread.");
545
+ throw;
357
546
  }
358
547
 
359
- mutex::scoped_lock l(server.lock);
548
+ UPDATE_TRACE_POINT();
549
+ boost::mutex::scoped_lock l(server.lock);
360
550
  ClientPtr myself(self.lock());
361
551
  if (myself != NULL) {
362
552
  server.clients.erase(myself);
@@ -390,55 +580,59 @@ public:
390
580
  * connection.
391
581
  */
392
582
  void start(const weak_ptr<Client> self) {
393
- thr = new Thread(
583
+ stringstream name;
584
+ name << "Client " << fd;
585
+ thr = new oxt::thread(
394
586
  bind(&Client::threadMain, this, self),
395
- CLIENT_THREAD_STACK_SIZE
587
+ name.str(), CLIENT_THREAD_STACK_SIZE
396
588
  );
397
589
  }
398
590
 
399
591
  ~Client() {
592
+ TRACE_POINT();
400
593
  this_thread::disable_syscall_interruption dsi;
401
594
  this_thread::disable_interruption di;
402
595
 
403
596
  if (thr != NULL) {
404
597
  if (thr->get_id() != this_thread::get_id()) {
405
- thr->interruptAndJoin();
598
+ thr->interrupt_and_join();
406
599
  }
407
600
  delete thr;
408
601
  }
409
- InterruptableCalls::close(fd);
602
+ syscalls::close(fd);
410
603
  }
411
604
  };
412
605
 
413
-
414
606
  int
415
607
  Server::start() {
416
- setupSyscallInterruptionSupport();
417
-
418
- // Ignore SIGPIPE.
419
- struct sigaction action;
420
- action.sa_handler = SIG_IGN;
421
- action.sa_flags = 0;
422
- sigemptyset(&action.sa_mask);
423
- sigaction(SIGPIPE, &action, NULL);
608
+ TRACE_POINT();
609
+ setup_syscall_interruption_support();
424
610
 
425
611
  try {
426
612
  if (!statusReportFIFO.empty()) {
427
613
  statusReportThread = ptr(
428
- new Thread(
614
+ new oxt::thread(
429
615
  bind(&Server::statusReportThreadMain, this),
616
+ "Status report thread",
430
617
  1024 * 128
431
618
  )
432
619
  );
433
620
  }
434
621
 
622
+ if (!user.empty()) {
623
+ lowerPrivilege(user);
624
+ }
625
+
626
+ setupSignalHandlers();
627
+
435
628
  while (!this_thread::interruption_requested()) {
436
629
  int fds[2], ret;
437
630
  char x;
438
631
 
439
632
  // The received data only serves to wake up the server socket,
440
633
  // and is not important.
441
- ret = InterruptableCalls::read(serverSocket, &x, 1);
634
+ UPDATE_TRACE_POINT();
635
+ ret = syscalls::read(serverSocket, &x, 1);
442
636
  if (ret == 0) {
443
637
  // All web server processes disconnected from this server.
444
638
  // So we can safely quit.
@@ -450,22 +644,28 @@ Server::start() {
450
644
 
451
645
  // We have an incoming connect request from an
452
646
  // ApplicationPool client.
647
+ UPDATE_TRACE_POINT();
453
648
  do {
454
649
  ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
455
650
  } while (ret == -1 && errno == EINTR);
456
651
  if (ret == -1) {
652
+ UPDATE_TRACE_POINT();
457
653
  throw SystemException("Cannot create an anonymous Unix socket", errno);
458
654
  }
459
655
 
656
+ UPDATE_TRACE_POINT();
460
657
  MessageChannel(serverSocket).writeFileDescriptor(fds[1]);
461
- InterruptableCalls::close(fds[1]);
658
+ syscalls::close(fds[1]);
462
659
 
660
+ UPDATE_TRACE_POINT();
463
661
  ClientPtr client(new Client(*this, fds[0]));
464
662
  pair<set<ClientPtr>::iterator, bool> p;
465
663
  {
466
- mutex::scoped_lock l(lock);
664
+ UPDATE_TRACE_POINT();
665
+ boost::mutex::scoped_lock l(lock);
467
666
  clients.insert(client);
468
667
  }
668
+ UPDATE_TRACE_POINT();
469
669
  client->start(client);
470
670
  }
471
671
  } catch (const boost::thread_interrupted &) {
@@ -477,12 +677,19 @@ Server::start() {
477
677
  int
478
678
  main(int argc, char *argv[]) {
479
679
  try {
680
+ exeFile = argv[0];
480
681
  Server server(SERVER_SOCKET_FD, atoi(argv[1]),
481
682
  argv[2], argv[3], argv[4], argv[5], argv[6]);
482
683
  return server.start();
684
+ } catch (const tracable_exception &e) {
685
+ P_ERROR("*** Fatal error: " << e.what() << "\n" << e.backtrace());
686
+ return 1;
483
687
  } catch (const exception &e) {
484
- P_ERROR(e.what());
688
+ P_ERROR("*** Fatal error: " << e.what());
485
689
  return 1;
690
+ } catch (...) {
691
+ P_ERROR("*** Fatal error: Unknown exception thrown in main thread.");
692
+ throw;
486
693
  }
487
694
  }
488
695