passenger 5.3.4 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +69 -0
  3. data/CONTRIBUTORS +1 -0
  4. data/README.md +2 -1
  5. data/Rakefile +0 -5
  6. data/build/agent.rb +6 -3
  7. data/build/cxx_tests.rb +28 -19
  8. data/build/integration_tests.rb +6 -2
  9. data/build/misc.rb +2 -1
  10. data/build/packaging.rb +2 -0
  11. data/build/support/cplusplus.rb +2 -2
  12. data/build/support/cxx_dependency_map.rb +2651 -2189
  13. data/dev/colorize-logs +272 -0
  14. data/dev/show-latest-crashlog-dir +27 -0
  15. data/resources/templates/standalone/http.erb +2 -0
  16. data/resources/templates/standalone/server.erb +1 -0
  17. data/src/agent/AgentMain.cpp +4 -0
  18. data/src/agent/Core/AdminPanelConnector.h +6 -6
  19. data/src/agent/Core/ApiServer.h +4 -4
  20. data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +2 -2
  21. data/src/agent/Core/ApplicationPool/Context.h +5 -1
  22. data/src/agent/Core/ApplicationPool/Group/InternalUtils.cpp +2 -2
  23. data/src/agent/Core/ApplicationPool/Group/LifetimeAndBasics.cpp +5 -0
  24. data/src/agent/Core/ApplicationPool/Group/Miscellaneous.cpp +2 -1
  25. data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +3 -3
  26. data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +1 -1
  27. data/src/agent/Core/ApplicationPool/Group/StateInspection.cpp +13 -20
  28. data/src/agent/Core/ApplicationPool/Group.h +4 -2
  29. data/src/agent/Core/ApplicationPool/Implementation.cpp +5 -5
  30. data/src/agent/Core/ApplicationPool/Options.h +42 -38
  31. data/src/agent/Core/ApplicationPool/Pool/GroupUtils.cpp +2 -1
  32. data/src/agent/Core/ApplicationPool/Pool.h +4 -4
  33. data/src/agent/Core/ApplicationPool/Process.h +13 -15
  34. data/src/agent/Core/ApplicationPool/Socket.h +5 -5
  35. data/src/agent/Core/ApplicationPool/TestSession.h +3 -3
  36. data/src/agent/Core/Config.h +50 -10
  37. data/src/agent/Core/ConfigChange.cpp +13 -1
  38. data/src/agent/Core/Controller/Config.h +41 -17
  39. data/src/agent/Core/Controller/ForwardResponse.cpp +4 -0
  40. data/src/agent/Core/Controller/InitRequest.cpp +14 -8
  41. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +5 -0
  42. data/src/agent/Core/Controller/SendRequest.cpp +9 -9
  43. data/src/agent/Core/Controller/TurboCaching.h +2 -2
  44. data/src/agent/Core/Controller.h +7 -5
  45. data/src/agent/Core/CoreMain.cpp +204 -60
  46. data/src/agent/Core/OptionParser.h +20 -3
  47. data/src/agent/Core/ResponseCache.h +3 -3
  48. data/src/agent/Core/SecurityUpdateChecker.h +4 -2
  49. data/src/agent/Core/SpawningKit/Config/AutoGeneratedCode.h +1 -1
  50. data/src/agent/Core/SpawningKit/Config.h +3 -2
  51. data/src/agent/Core/SpawningKit/Context.h +8 -2
  52. data/src/agent/Core/SpawningKit/DirectSpawner.h +4 -4
  53. data/src/agent/Core/SpawningKit/DummySpawner.h +3 -3
  54. data/src/agent/Core/SpawningKit/ErrorRenderer.h +1 -1
  55. data/src/agent/Core/SpawningKit/Exceptions.h +21 -14
  56. data/src/agent/Core/SpawningKit/Factory.h +1 -1
  57. data/src/agent/Core/SpawningKit/Handshake/BackgroundIOCapturer.h +1 -1
  58. data/src/agent/Core/SpawningKit/Handshake/Perform.h +14 -2
  59. data/src/agent/Core/SpawningKit/Handshake/Prepare.h +3 -3
  60. data/src/agent/Core/SpawningKit/Handshake/WorkDir.h +1 -1
  61. data/src/agent/Core/SpawningKit/Journey.h +4 -5
  62. data/src/agent/Core/SpawningKit/PipeWatcher.h +1 -1
  63. data/src/agent/Core/SpawningKit/README.md +34 -17
  64. data/src/agent/Core/SpawningKit/Result/AutoGeneratedCode.h +1 -1
  65. data/src/agent/Core/SpawningKit/Result.h +20 -8
  66. data/src/agent/Core/SpawningKit/SmartSpawner.h +7 -7
  67. data/src/agent/Core/SpawningKit/Spawner.h +25 -8
  68. data/src/agent/Core/SpawningKit/UserSwitchingRules.h +17 -7
  69. data/src/agent/Core/TelemetryCollector.h +681 -0
  70. data/src/agent/ExecHelper/ExecHelperMain.cpp +1 -1
  71. data/src/agent/FileReadHelper/FileReadHelperMain.cpp +198 -0
  72. data/src/agent/README.md +1 -1
  73. data/src/agent/Shared/ApiAccountUtils.h +1 -1
  74. data/src/agent/Shared/ApiServerUtils.h +3 -3
  75. data/src/agent/Shared/ApplicationPoolApiKey.h +2 -2
  76. data/src/agent/Shared/Fundamentals/AbortHandler.cpp +324 -98
  77. data/src/agent/Shared/Fundamentals/AbortHandler.h +31 -4
  78. data/src/agent/Shared/Fundamentals/Initialization.cpp +4 -5
  79. data/src/agent/Shared/Fundamentals/Initialization.h +9 -1
  80. data/src/agent/SpawnEnvSetupper/SpawnEnvSetupperMain.cpp +1 -1
  81. data/src/agent/SystemMetrics/SystemMetricsMain.cpp +4 -3
  82. data/src/agent/TempDirToucher/TempDirToucherMain.cpp +3 -3
  83. data/src/agent/Watchdog/ApiServer.h +3 -3
  84. data/src/agent/Watchdog/Config.h +24 -5
  85. data/src/agent/Watchdog/CoreWatcher.cpp +2 -2
  86. data/src/agent/Watchdog/WatchdogMain.cpp +97 -28
  87. data/src/apache2_module/Config.cpp +14 -14
  88. data/src/apache2_module/Config.h +8 -16
  89. data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +510 -481
  90. data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp.cxxcodebuilder +39 -17
  91. data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
  92. data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +69 -1
  93. data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp.cxxcodebuilder +31 -1
  94. data/src/apache2_module/ConfigGeneral/Common.h +45 -0
  95. data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +17 -1
  96. data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp.cxxcodebuilder +16 -1
  97. data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +19 -5
  98. data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp.cxxcodebuilder +26 -9
  99. data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +19 -1
  100. data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp.cxxcodebuilder +10 -1
  101. data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +14 -1
  102. data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp.cxxcodebuilder +11 -1
  103. data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +36 -1
  104. data/src/apache2_module/DirConfig/AutoGeneratedStruct.h.cxxcodebuilder +34 -1
  105. data/src/apache2_module/DirectoryMapper.h +36 -37
  106. data/src/apache2_module/Hooks.cpp +27 -8
  107. data/src/apache2_module/ServerConfig/AutoGeneratedManifestGeneration.cpp +20 -0
  108. data/src/apache2_module/ServerConfig/AutoGeneratedStruct.h +48 -1
  109. data/src/apache2_module/ServerConfig/AutoGeneratedStruct.h.cxxcodebuilder +36 -1
  110. data/src/cxx_supportlib/{Utils → Algorithms}/Hasher.cpp +2 -2
  111. data/src/cxx_supportlib/{Utils → Algorithms}/Hasher.h +4 -4
  112. data/src/cxx_supportlib/AppLocalConfigFileUtils.h +148 -0
  113. data/src/cxx_supportlib/AppTypeDetector/CBindings.cpp +147 -0
  114. data/src/cxx_supportlib/AppTypeDetector/CBindings.h +75 -0
  115. data/src/cxx_supportlib/{AppTypes.h → AppTypeDetector/Detector.h} +92 -131
  116. data/src/cxx_supportlib/ConfigKit/README.md +90 -2
  117. data/src/cxx_supportlib/ConfigKit/Schema.h +60 -15
  118. data/src/cxx_supportlib/ConfigKit/Store.h +129 -5
  119. data/src/cxx_supportlib/Constants.h +1 -1
  120. data/src/cxx_supportlib/{Utils → DataStructures}/HashMap.h +4 -4
  121. data/src/cxx_supportlib/DataStructures/HashedStaticString.h +5 -5
  122. data/src/cxx_supportlib/DataStructures/LString.h +3 -3
  123. data/src/cxx_supportlib/{Utils → DataStructures}/StringMap.h +36 -36
  124. data/src/cxx_supportlib/FileTools/FileManip.cpp +1 -1
  125. data/src/cxx_supportlib/FileTools/PathManip.cpp +2 -2
  126. data/src/cxx_supportlib/FileTools/PathSecurityCheck.cpp +1 -1
  127. data/src/cxx_supportlib/Hooks.h +2 -2
  128. data/src/cxx_supportlib/{Utils → IOTools}/BufferedIO.h +5 -5
  129. data/src/cxx_supportlib/{Utils → IOTools}/IOUtils.cpp +4 -3
  130. data/src/cxx_supportlib/{Utils → IOTools}/IOUtils.h +3 -3
  131. data/src/cxx_supportlib/{Utils → IOTools}/MessageIO.h +7 -7
  132. data/src/cxx_supportlib/{MessageReadersWriters.h → IOTools/MessageSerialization.h} +5 -5
  133. data/src/cxx_supportlib/InstanceDirectory.h +4 -4
  134. data/src/cxx_supportlib/Integrations/LibevJsonUtils.h +3 -3
  135. data/src/cxx_supportlib/{Utils → JsonTools}/JsonUtils.h +5 -5
  136. data/src/cxx_supportlib/LoggingKit/Context.h +2 -2
  137. data/src/cxx_supportlib/LoggingKit/Implementation.cpp +3 -3
  138. data/src/cxx_supportlib/MemoryKit/mbuf.cpp +2 -2
  139. data/src/cxx_supportlib/ProcessManagement/Ruby.cpp +3 -3
  140. data/src/cxx_supportlib/ProcessManagement/Ruby.h +7 -2
  141. data/src/cxx_supportlib/ProcessManagement/Spawn.cpp +19 -12
  142. data/src/cxx_supportlib/ProcessManagement/Spawn.h +21 -2
  143. data/src/cxx_supportlib/ProcessManagement/Utils.h +10 -0
  144. data/src/cxx_supportlib/RandomGenerator.h +2 -2
  145. data/src/cxx_supportlib/ResourceLocator.h +1 -1
  146. data/src/cxx_supportlib/{Crypto.cpp → SecurityKit/Crypto.cpp} +4 -4
  147. data/src/cxx_supportlib/{Crypto.h → SecurityKit/Crypto.h} +4 -4
  148. data/src/cxx_supportlib/{Utils → SecurityKit}/MemZeroGuard.h +0 -0
  149. data/src/cxx_supportlib/ServerKit/AcceptLoadBalancer.h +2 -2
  150. data/src/cxx_supportlib/ServerKit/Channel.h +1 -1
  151. data/src/cxx_supportlib/ServerKit/ClientRef.h +17 -7
  152. data/src/cxx_supportlib/ServerKit/Context.h +2 -2
  153. data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +1 -1
  154. data/src/cxx_supportlib/ServerKit/HttpHeaderParser.h +3 -3
  155. data/src/cxx_supportlib/ServerKit/HttpHeaderParserState.h +2 -2
  156. data/src/cxx_supportlib/ServerKit/HttpRequestRef.h +17 -7
  157. data/src/cxx_supportlib/ServerKit/HttpServer.h +16 -10
  158. data/src/cxx_supportlib/ServerKit/Server.h +3 -4
  159. data/src/cxx_supportlib/{Utils → StrIntTools}/DateParsing.h +5 -5
  160. data/src/cxx_supportlib/{Utils → StrIntTools}/StrIntUtils.cpp +3 -3
  161. data/src/cxx_supportlib/{Utils → StrIntTools}/StrIntUtils.h +0 -0
  162. data/src/cxx_supportlib/{Utils → StrIntTools}/StrIntUtilsNoStrictAliasing.cpp +12 -12
  163. data/src/cxx_supportlib/{Utils → StrIntTools}/StringScanning.h +5 -5
  164. data/src/cxx_supportlib/{Utils → StrIntTools}/Template.h +30 -5
  165. data/src/cxx_supportlib/SystemTools/ContainerHelpers.h +88 -0
  166. data/src/cxx_supportlib/{Utils → SystemTools}/ProcessMetricsCollector.h +15 -12
  167. data/src/cxx_supportlib/{Utils → SystemTools}/SystemMetricsCollector.h +3 -3
  168. data/src/cxx_supportlib/{Utils → SystemTools}/SystemTime.cpp +1 -1
  169. data/src/cxx_supportlib/{Utils → SystemTools}/SystemTime.h +0 -0
  170. data/src/cxx_supportlib/SystemTools/UserDatabase.h +1 -1
  171. data/src/cxx_supportlib/Utils/CachedFileStat.hpp +3 -3
  172. data/src/cxx_supportlib/Utils/Curl.h +2 -2
  173. data/src/cxx_supportlib/Utils/FileChangeChecker.h +2 -2
  174. data/src/cxx_supportlib/Utils/MessagePassing.h +1 -1
  175. data/src/cxx_supportlib/Utils/SpeedMeter.h +2 -2
  176. data/src/cxx_supportlib/Utils/Timer.h +2 -2
  177. data/src/cxx_supportlib/Utils/VariantMap.h +3 -3
  178. data/src/cxx_supportlib/Utils.cpp +2 -2
  179. data/src/cxx_supportlib/WatchdogLauncher.h +3 -3
  180. data/src/cxx_supportlib/WebSocketCommandReverseServer.h +1 -1
  181. data/src/cxx_supportlib/WrapperRegistry/CBindings.cpp +85 -0
  182. data/src/cxx_supportlib/{Utils/MemoryBarrier.h → WrapperRegistry/CBindings.h} +30 -27
  183. data/src/cxx_supportlib/WrapperRegistry/Entry.h +112 -0
  184. data/src/cxx_supportlib/WrapperRegistry/README.md +37 -0
  185. data/src/cxx_supportlib/WrapperRegistry/Registry.h +309 -0
  186. data/src/cxx_supportlib/vendor-modified/psg_sysqueue.h +3 -0
  187. data/src/helper-scripts/download_binaries/extconf.rb +6 -2
  188. data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +32 -0
  189. data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +12 -0
  190. data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +36 -0
  191. data/src/nginx_module/Configuration.c +23 -3
  192. data/src/nginx_module/ContentHandler.c +331 -32
  193. data/src/nginx_module/ContentHandler.h +8 -3
  194. data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +10 -0
  195. data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c +27 -0
  196. data/src/nginx_module/LocationConfig/AutoGeneratedMergeFunction.c +3 -0
  197. data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +7 -0
  198. data/src/nginx_module/MainConfig/AutoGeneratedCreateFunction.c +11 -0
  199. data/src/nginx_module/MainConfig/AutoGeneratedManifestGeneration.c +23 -0
  200. data/src/nginx_module/MainConfig/AutoGeneratedStruct.h +8 -0
  201. data/src/nginx_module/config +2 -1
  202. data/src/nginx_module/ngx_http_passenger_module.c +9 -3
  203. data/src/nginx_module/ngx_http_passenger_module.h +10 -3
  204. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +19 -0
  205. data/src/ruby_supportlib/phusion_passenger/common_library.rb +19 -16
  206. data/src/ruby_supportlib/phusion_passenger/config/agent_compiler.rb +4 -4
  207. data/src/ruby_supportlib/phusion_passenger/config/download_agent_command.rb +6 -2
  208. data/src/ruby_supportlib/phusion_passenger/config/download_nginx_engine_command.rb +6 -2
  209. data/src/ruby_supportlib/phusion_passenger/config/nginx_engine_compiler.rb +1 -1
  210. data/src/ruby_supportlib/phusion_passenger/message_channel.rb +2 -2
  211. data/src/ruby_supportlib/phusion_passenger/native_support.rb +7 -3
  212. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +29 -0
  213. data/src/ruby_supportlib/phusion_passenger/packaging.rb +20 -19
  214. data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +22 -4
  215. data/src/ruby_supportlib/phusion_passenger/platform_info/ruby.rb +33 -13
  216. data/src/ruby_supportlib/phusion_passenger/standalone/app_finder.rb +1 -0
  217. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +22 -2
  218. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +4 -1
  219. data/src/ruby_supportlib/phusion_passenger.rb +7 -5
  220. data/src/schema_printer/SchemaPrinterMain.cpp +2 -0
  221. metadata +40 -89
  222. data/.editorconfig +0 -134
  223. data/CODE_OF_CONDUCT.md +0 -52
  224. data/dev/boost-patches/0001-Patch-boost-thread-so-that-oxt-thread-can-use-it.patch +0 -48
  225. data/dev/boost-patches/0002-Make-boost-thread_interrupted-derive-from-oxt-tracab.patch +0 -33
  226. data/dev/boost-patches/0003-Disable-a-Clang-pragma-to-prevent-warnings-on-OS-X.patch +0 -25
  227. data/dev/ci/README.md +0 -134
  228. data/dev/ci/lib/functions.sh +0 -129
  229. data/dev/ci/lib/set-container-envvars.sh +0 -53
  230. data/dev/ci/lib/setup-container.sh +0 -46
  231. data/dev/ci/run-tests-natively +0 -24
  232. data/dev/ci/run-tests-with-docker +0 -42
  233. data/dev/ci/scripts/debug-console-wrapper.sh +0 -29
  234. data/dev/ci/scripts/docker-entrypoint-stage2.sh +0 -17
  235. data/dev/ci/scripts/docker-entrypoint.sh +0 -17
  236. data/dev/ci/scripts/inituidgid +0 -17
  237. data/dev/ci/scripts/run-tests-natively-stage2.sh +0 -17
  238. data/dev/ci/scripts/setup-host-natively.sh +0 -11
  239. data/dev/ci/setup-host +0 -56
  240. data/dev/ci/tests/apache2/run +0 -6
  241. data/dev/ci/tests/apache2/setup +0 -4
  242. data/dev/ci/tests/binaries/Jenkinsfile +0 -105
  243. data/dev/ci/tests/binaries/build-linux +0 -38
  244. data/dev/ci/tests/binaries/build-macos +0 -40
  245. data/dev/ci/tests/binaries/prepare-macos +0 -38
  246. data/dev/ci/tests/binaries/test-linux +0 -45
  247. data/dev/ci/tests/binaries/test-macos +0 -38
  248. data/dev/ci/tests/cxx/run +0 -9
  249. data/dev/ci/tests/cxx/setup +0 -4
  250. data/dev/ci/tests/debian/Jenkinsfile +0 -89
  251. data/dev/ci/tests/debian/run +0 -60
  252. data/dev/ci/tests/nginx/run +0 -5
  253. data/dev/ci/tests/nginx/setup +0 -4
  254. data/dev/ci/tests/nginx-dynamic/run +0 -20
  255. data/dev/ci/tests/nginx-dynamic/setup +0 -4
  256. data/dev/ci/tests/nodejs/run +0 -4
  257. data/dev/ci/tests/nodejs/setup +0 -4
  258. data/dev/ci/tests/rpm/Jenkinsfile +0 -68
  259. data/dev/ci/tests/rpm/run +0 -63
  260. data/dev/ci/tests/ruby/run +0 -4
  261. data/dev/ci/tests/ruby/setup +0 -4
  262. data/dev/ci/tests/source-packaging/run +0 -4
  263. data/dev/ci/tests/source-packaging/setup +0 -4
  264. data/dev/ci/tests/standalone/run +0 -4
  265. data/dev/ci/tests/standalone/setup +0 -4
  266. data/dev/configkit-schemas/index.json +0 -1748
  267. data/dev/configkit-schemas/update_schema_inline_comments.rb +0 -118
  268. data/dev/rack.test/config.ru +0 -5
  269. data/dev/rack.test/public/asset.txt +0 -1
  270. data/dev/vagrant/apache_default_site.conf +0 -35
  271. data/dev/vagrant/apache_passenger.conf +0 -5
  272. data/dev/vagrant/apache_passenger.load +0 -1
  273. data/dev/vagrant/apache_ports.conf +0 -24
  274. data/dev/vagrant/apache_rack_test.conf +0 -9
  275. data/dev/vagrant/bashrc +0 -23
  276. data/dev/vagrant/nginx.conf +0 -39
  277. data/dev/vagrant/nginx_rakefile +0 -33
  278. data/dev/vagrant/nginx_start +0 -32
  279. data/dev/vagrant/provision.sh +0 -117
  280. data/dev/vagrant/sudoers.conf +0 -5
  281. data/resources/templates/error_renderer/.editorconfig +0 -19
  282. data/src/cxx_supportlib/AppTypes.cpp +0 -109
  283. data/src/cxx_supportlib/vendor-modified/SmallVector.h +0 -653
@@ -59,6 +59,7 @@
59
59
  #include <LoggingKit/LoggingKit.h>
60
60
  #include <LoggingKit/Context.h>
61
61
  #include <ResourceLocator.h>
62
+ #include <RandomGenerator.h>
62
63
  #include <ProcessManagement/Utils.h>
63
64
  #include <Utils.h>
64
65
  #include <Utils/AsyncSignalSafeUtils.h>
@@ -70,6 +71,9 @@ namespace Fundamentals {
70
71
  using namespace std;
71
72
  namespace ASSU = AsyncSignalSafeUtils;
72
73
 
74
+ #define RANDOM_TOKEN_SIZE 6
75
+ #define MAX_RANDOM_TOKENS 256
76
+
73
77
 
74
78
  struct AbortHandlerContext {
75
79
  const AbortHandlerConfig *config;
@@ -80,6 +84,12 @@ struct AbortHandlerContext {
80
84
  char *backtraceSanitizerCommand;
81
85
  bool backtraceSanitizerPassProgramInfo;
82
86
 
87
+ /**
88
+ * A string of RANDOM_TOKEN_SIZE * MAX_RANDOM_SIZES bytes.
89
+ * Used by createCrashLogDir() to find a unique directory name.
90
+ */
91
+ char *randomTokens;
92
+
83
93
  int emergencyPipe1[2];
84
94
  int emergencyPipe2[2];
85
95
 
@@ -92,8 +102,12 @@ struct AbortHandlerWorkingState {
92
102
  pid_t pid;
93
103
  int signo;
94
104
  siginfo_t *info;
105
+
95
106
  char messagePrefix[32];
96
107
  char messageBuf[1024];
108
+
109
+ char crashLogDir[256];
110
+ int crashLogDirFd;
97
111
  };
98
112
 
99
113
  typedef void (*Callback)(AbortHandlerWorkingState &state, void *userData);
@@ -116,6 +130,34 @@ write_nowarn(int fd, const void *buf, size_t n) {
116
130
  ASSU::writeNoWarn(fd, buf, n);
117
131
  }
118
132
 
133
+ static void
134
+ printCrashLogFileCreated(AbortHandlerWorkingState &state, const char *fname) {
135
+ const char *end = state.messageBuf + sizeof(state.messageBuf);
136
+ char *pos = state.messageBuf;
137
+ pos = ASSU::appendData(pos, end, "Dumping to ");
138
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
139
+ pos = ASSU::appendData(pos, end, "/");
140
+ pos = ASSU::appendData(pos, end, fname);
141
+ pos = ASSU::appendData(pos, end, "\n");
142
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
143
+ }
144
+
145
+ static void
146
+ printCrashLogFileCreationError(AbortHandlerWorkingState &state, const char *fname, int e) {
147
+ const char *end = state.messageBuf + sizeof(state.messageBuf);
148
+ char *pos = state.messageBuf;
149
+ pos = ASSU::appendData(pos, end, "Error creating ");
150
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
151
+ pos = ASSU::appendData(pos, end, "/");
152
+ pos = ASSU::appendData(pos, end, fname);
153
+ pos = ASSU::appendData(pos, end, ": ");
154
+ pos = ASSU::appendData(pos, end, ASSU::limitedStrerror(e));
155
+ pos = ASSU::appendData(pos, end, " (errno=");
156
+ pos = ASSU::appendInteger<int, 10>(pos, end, e);
157
+ pos = ASSU::appendData(pos, end, ")\n");
158
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
159
+ }
160
+
119
161
  static char *
120
162
  appendSignalName(char *pos, const char *end, int signo) {
121
163
  switch (signo) {
@@ -289,8 +331,61 @@ runInSubprocessWithTimeLimit(AbortHandlerWorkingState &state, Callback callback,
289
331
  }
290
332
  }
291
333
 
334
+ static void
335
+ dumpUlimits(AbortHandlerWorkingState &state) {
336
+ const char *end = state.messageBuf + sizeof(state.messageBuf);
337
+ char *pos = state.messageBuf;
338
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
339
+ pos = ASSU::appendData(pos, end, " ] Dumping ulimits...\n");
340
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
341
+
342
+ int fd = -1;
343
+ if (state.crashLogDirFd != -1) {
344
+ fd = openat(state.crashLogDirFd, "ulimits.log", O_WRONLY | O_CREAT | O_TRUNC, 0600);
345
+ if (fd != -1) {
346
+ printCrashLogFileCreated(state, "ulimits.log");
347
+ } else {
348
+ printCrashLogFileCreationError(state, "ulimits.log", errno);
349
+ }
350
+ }
351
+
352
+ pid_t pid = asyncFork();
353
+ int status;
354
+ if (pid == 0) {
355
+ if (fd != -1) {
356
+ dup2(fd, STDOUT_FILENO);
357
+ dup2(fd, STDERR_FILENO);
358
+ }
359
+ closeAllFileDescriptors(2, true);
360
+ execlp("ulimit", "ulimit", "-a", (char *) 0);
361
+ // On Linux 'ulimit' is a shell builtin, not a command.
362
+ execlp("/bin/sh", "/bin/sh", "-c", "ulimit -a", (char *) 0);
363
+ _exit(1);
364
+ } else if (pid == -1) {
365
+ ASSU::printError("ERROR: Could not fork a process to dump the ulimit!\n");
366
+ } else if (waitpid(pid, &status, 0) != pid || status != 0) {
367
+ ASSU::printError("ERROR: Could not run 'ulimit -a'!\n");
368
+ }
369
+
370
+ if (fd != -1) {
371
+ close(fd);
372
+ }
373
+ }
374
+
292
375
  static void
293
376
  dumpFileDescriptorInfoWithLsof(AbortHandlerWorkingState &state, void *userData) {
377
+ if (state.crashLogDirFd != -1) {
378
+ int fd = openat(state.crashLogDirFd, "fds.log", O_WRONLY | O_CREAT | O_TRUNC, 0600);
379
+ if (fd != -1) {
380
+ printCrashLogFileCreated(state, "fds.log");
381
+ dup2(fd, STDOUT_FILENO);
382
+ dup2(fd, STDERR_FILENO);
383
+ close(fd);
384
+ } else {
385
+ printCrashLogFileCreationError(state, "fds.log", errno);
386
+ }
387
+ }
388
+
294
389
  char *pos = state.messageBuf;
295
390
  const char *end = state.messageBuf + sizeof(state.messageBuf) - 1;
296
391
  pos = ASSU::appendInteger<pid_t, 10>(pos, end, state.pid);
@@ -298,7 +393,7 @@ dumpFileDescriptorInfoWithLsof(AbortHandlerWorkingState &state, void *userData)
298
393
 
299
394
  closeAllFileDescriptors(2, true);
300
395
 
301
- execlp("lsof", "lsof", "-p", state.messageBuf, "-nP", (const char * const) 0);
396
+ execlp("lsof", "lsof", "-p", state.messageBuf, "-nP", (char *) 0);
302
397
 
303
398
  const char *command[] = { "lsof", NULL };
304
399
  printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
@@ -306,15 +401,38 @@ dumpFileDescriptorInfoWithLsof(AbortHandlerWorkingState &state, void *userData)
306
401
  }
307
402
 
308
403
  static void
309
- dumpFileDescriptorInfoWithLs(AbortHandlerWorkingState &state) {
404
+ dumpFileDescriptorInfoWithLs(AbortHandlerWorkingState &state, const char *path) {
310
405
  pid_t pid;
406
+ int fd = -1;
311
407
  int status;
312
408
 
409
+ if (state.crashLogDirFd != -1) {
410
+ fd = openat(state.crashLogDirFd, "fds.log", O_WRONLY | O_CREAT | O_TRUNC, 0600);
411
+ if (fd != -1) {
412
+ printCrashLogFileCreated(state, "fds.log");
413
+ } else {
414
+ printCrashLogFileCreationError(state, "fds.log", errno);
415
+ }
416
+ }
417
+
313
418
  pid = asyncFork();
314
419
  if (pid == 0) {
420
+ if (fd != -1) {
421
+ dup2(fd, STDOUT_FILENO);
422
+ dup2(fd, STDERR_FILENO);
423
+ }
424
+
425
+ const char *end = state.messageBuf + sizeof(state.messageBuf);
426
+ char *pos = state.messageBuf;
427
+ pos = ASSU::appendData(pos, end, "Running: ls -lv ");
428
+ pos = ASSU::appendData(pos, end, path);
429
+ pos = ASSU::appendData(pos, end, "\n");
430
+ pos = ASSU::appendData(pos, end, "--------------------------\n");
431
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
432
+
315
433
  closeAllFileDescriptors(2, true);
316
434
  // The '-v' is for natural sorting on Linux. On BSD -v means something else but it's harmless.
317
- execlp("ls", "ls", "-lv", state.messageBuf, (const char * const) 0);
435
+ execlp("ls", "ls", "-lv", path, (char *) 0);
318
436
 
319
437
  const char *command[] = { "ls", NULL };
320
438
  printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
@@ -324,6 +442,10 @@ dumpFileDescriptorInfoWithLs(AbortHandlerWorkingState &state) {
324
442
  } else if (waitpid(pid, &status, 0) != pid || status != 0) {
325
443
  ASSU::printError("ERROR: Could not run 'ls' to dump file descriptor information!\n");
326
444
  }
445
+
446
+ if (fd != -1) {
447
+ close(fd);
448
+ }
327
449
  }
328
450
 
329
451
  static void
@@ -342,46 +464,63 @@ dumpFileDescriptorInfo(AbortHandlerWorkingState &state) {
342
464
  status = runInSubprocessWithTimeLimit(state, dumpFileDescriptorInfoWithLsof, NULL, 4000);
343
465
 
344
466
  if (status != 0) {
467
+ char path[256];
345
468
  ASSU::printError("Falling back to another mechanism for dumping file descriptors.\n");
346
469
 
347
- pos = messageBuf;
470
+ pos = path;
471
+ end = path + sizeof(path) - 1;
348
472
  pos = ASSU::appendData(pos, end, "/proc/");
349
473
  pos = ASSU::appendInteger<pid_t, 10>(pos, end, state.pid);
350
474
  pos = ASSU::appendData(pos, end, "/fd");
351
475
  *pos = '\0';
352
- if (stat(messageBuf, &buf) == 0) {
353
- dumpFileDescriptorInfoWithLs(state);
354
- } else {
355
- pos = messageBuf;
356
- pos = ASSU::appendData(pos, end, "/dev/fd");
357
- *pos = '\0';
358
- if (stat(messageBuf, &buf) == 0) {
359
- dumpFileDescriptorInfoWithLs(state);
360
- } else {
361
- pos = messageBuf;
362
- pos = ASSU::appendData(pos, end, "ERROR: No other file descriptor dumping mechanism on current platform detected.\n");
363
- write_nowarn(STDERR_FILENO, messageBuf, pos - messageBuf);
364
- }
476
+ if (stat(path, &buf) == 0) {
477
+ dumpFileDescriptorInfoWithLs(state, path);
478
+ return;
479
+ }
480
+
481
+ pos = path;
482
+ pos = ASSU::appendData(pos, end, "/dev/fd");
483
+ *pos = '\0';
484
+ if (stat(path, &buf) == 0) {
485
+ dumpFileDescriptorInfoWithLs(state, path);
486
+ return;
365
487
  }
488
+
489
+ pos = messageBuf;
490
+ pos = ASSU::appendData(pos, end, "ERROR: No other file descriptor dumping mechanism on current platform detected.\n");
491
+ write_nowarn(STDERR_FILENO, messageBuf, pos - messageBuf);
366
492
  }
367
493
  }
368
494
 
369
495
  static void
370
496
  dumpWithCrashWatch(AbortHandlerWorkingState &state) {
371
- char *pos;
372
- const char *end = state.messageBuf + sizeof(state.messageBuf) - 1;
497
+ int fd = -1;
373
498
 
374
- pos = state.messageBuf;
499
+ if (state.crashLogDirFd != -1) {
500
+ fd = openat(state.crashLogDirFd, "backtrace.log", O_WRONLY | O_CREAT | O_TRUNC, 0600);
501
+ if (fd != -1) {
502
+ printCrashLogFileCreated(state, "backtrace.log");
503
+ } else {
504
+ printCrashLogFileCreationError(state, "backtrace.log", errno);
505
+ }
506
+ }
507
+
508
+ char *pos = state.messageBuf;
509
+ const char *end = state.messageBuf + sizeof(state.messageBuf) - 1;
375
510
  pos = ASSU::appendInteger<pid_t, 10>(pos, end, state.pid);
376
511
  *pos = '\0';
377
512
 
378
513
  pid_t child = asyncFork();
379
514
  if (child == 0) {
515
+ if (fd != -1) {
516
+ dup2(fd, STDOUT_FILENO);
517
+ dup2(fd, STDERR_FILENO);
518
+ }
380
519
  closeAllFileDescriptors(2, true);
381
520
  execlp(ctx->config->ruby, ctx->config->ruby, ctx->crashWatchCommand,
382
521
  ctx->rubyLibDir, ctx->installSpec, "--dump",
383
522
  state.messageBuf, // PID string
384
- (char * const) 0);
523
+ (char *) 0);
385
524
 
386
525
  const char *command[] = { "crash-watch", NULL };
387
526
  printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
@@ -400,6 +539,10 @@ dumpWithCrashWatch(AbortHandlerWorkingState &state) {
400
539
  } else {
401
540
  waitpid(child, NULL, 0);
402
541
  }
542
+
543
+ if (fd != -1) {
544
+ close(fd);
545
+ }
403
546
  }
404
547
 
405
548
  #ifdef LIBC_HAS_BACKTRACE_FUNC
@@ -455,16 +598,16 @@ dumpWithCrashWatch(AbortHandlerWorkingState &state) {
455
598
  }
456
599
  *pos = '\0';
457
600
  pos++;
458
- execlp("/bin/sh", "/bin/sh", "-c", command, (const char * const) 0);
601
+ execlp("/bin/sh", "/bin/sh", "-c", command, (char *) 0);
459
602
 
460
603
  pos = state.messageBuf;
461
604
  pos = ASSU::appendData(pos, end, "ERROR: cannot execute '");
462
605
  pos = ASSU::appendData(pos, end, ctx->backtraceSanitizerCommand);
463
606
  pos = ASSU::appendData(pos, end, "' for sanitizing the backtrace, trying 'cat'...\n");
464
607
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
465
- execlp("cat", "cat", (const char * const) 0);
466
- execlp("/bin/cat", "cat", (const char * const) 0);
467
- execlp("/usr/bin/cat", "cat", (const char * const) 0);
608
+ execlp("cat", "cat", (char *) 0);
609
+ execlp("/bin/cat", "cat", (char *) 0);
610
+ execlp("/usr/bin/cat", "cat", (char *) 0);
468
611
 
469
612
  const char *commandArray[] = { "cat", NULL };
470
613
  printExecError2(commandArray, errno, state.messageBuf, sizeof(state.messageBuf));
@@ -508,7 +651,22 @@ dumpWithCrashWatch(AbortHandlerWorkingState &state) {
508
651
 
509
652
  static void
510
653
  runCustomDiagnosticsDumper(AbortHandlerWorkingState &state, void *userData) {
511
- ctx->config->diagnosticsDumper(ctx->config->diagnosticsDumperUserData);
654
+ unsigned int i = static_cast<unsigned int>(reinterpret_cast<boost::uintptr_t>(userData));
655
+ const AbortHandlerConfig::DiagnosticsDumper &dumper = ctx->config->diagnosticsDumpers[i];
656
+
657
+ if (state.crashLogDirFd != -1) {
658
+ int fd = openat(state.crashLogDirFd, dumper.logFileName, O_WRONLY | O_CREAT | O_TRUNC, 0600);
659
+ if (fd != -1) {
660
+ printCrashLogFileCreated(state, dumper.logFileName);
661
+ dup2(fd, STDOUT_FILENO);
662
+ dup2(fd, STDERR_FILENO);
663
+ close(fd);
664
+ } else {
665
+ printCrashLogFileCreationError(state, dumper.logFileName, errno);
666
+ }
667
+ }
668
+
669
+ dumper.func(dumper.userData);
512
670
  }
513
671
 
514
672
  // This function is performed in a child process.
@@ -521,14 +679,14 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
521
679
 
522
680
  pos = state.messageBuf;
523
681
  pos = ASSU::appendData(pos, end, state.messagePrefix);
524
- pos = ASSU::appendData(pos, end, " ] Date, uname and ulimits:\n");
682
+ pos = ASSU::appendData(pos, end, " ] Date and uname:\n");
525
683
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
526
684
 
527
685
  // Dump human-readable time string and string.
528
686
  pid = asyncFork();
529
687
  if (pid == 0) {
530
688
  closeAllFileDescriptors(2, true);
531
- execlp("date", "date", (const char * const) 0);
689
+ execlp("date", "date", (char *) 0);
532
690
  _exit(1);
533
691
  } else if (pid == -1) {
534
692
  ASSU::printError("ERROR: Could not fork a process to dump the time!\n");
@@ -540,7 +698,7 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
540
698
  pid = asyncFork();
541
699
  if (pid == 0) {
542
700
  closeAllFileDescriptors(2, true);
543
- execlp("uname", "uname", "-mprsv", (const char * const) 0);
701
+ execlp("uname", "uname", "-mprsv", (char *) 0);
544
702
  _exit(1);
545
703
  } else if (pid == -1) {
546
704
  ASSU::printError("ERROR: Could not fork a process to dump the uname!\n");
@@ -548,20 +706,6 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
548
706
  ASSU::printError("ERROR: Could not run 'uname -mprsv'!\n");
549
707
  }
550
708
 
551
- // Dump ulimit.
552
- pid = asyncFork();
553
- if (pid == 0) {
554
- closeAllFileDescriptors(2, true);
555
- execlp("ulimit", "ulimit", "-a", (const char * const) 0);
556
- // On Linux 'ulimit' is a shell builtin, not a command.
557
- execlp("/bin/sh", "/bin/sh", "-c", "ulimit -a", (const char * const) 0);
558
- _exit(1);
559
- } else if (pid == -1) {
560
- ASSU::printError("ERROR: Could not fork a process to dump the ulimit!\n");
561
- } else if (waitpid(pid, &status, 0) != pid || status != 0) {
562
- ASSU::printError("ERROR: Could not run 'ulimit -a'!\n");
563
- }
564
-
565
709
  pos = state.messageBuf;
566
710
  pos = ASSU::appendData(pos, end, state.messagePrefix);
567
711
  pos = ASSU::appendData(pos, end, " ] " PROGRAM_NAME " version: " PASSENGER_VERSION "\n");
@@ -604,13 +748,24 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
604
748
 
605
749
  ASSU::printError("--------------------------------------\n");
606
750
 
607
- if (ctx->config->diagnosticsDumper != NULL) {
751
+ dumpUlimits(state);
752
+
753
+ ASSU::printError("--------------------------------------\n");
754
+
755
+ for (unsigned int i = 0; i < AbortHandlerConfig::MAX_DIAGNOSTICS_DUMPERS; i++) {
756
+ const AbortHandlerConfig::DiagnosticsDumper &diagnosticsDumper = ctx->config->diagnosticsDumpers[i];
757
+ if (diagnosticsDumper.func == NULL) {
758
+ continue;
759
+ }
760
+
608
761
  pos = state.messageBuf;
609
762
  pos = ASSU::appendData(pos, end, state.messagePrefix);
610
- pos = ASSU::appendData(pos, end, " ] Dumping additional diagnostical information...\n");
763
+ pos = ASSU::appendData(pos, end, " ] Dumping ");
764
+ pos = ASSU::appendData(pos, end, diagnosticsDumper.name);
765
+ pos = ASSU::appendData(pos, end, "...\n");
611
766
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
612
- ASSU::printError("--------------------------------------\n");
613
- runInSubprocessWithTimeLimit(state, runCustomDiagnosticsDumper, NULL, 2000);
767
+ runInSubprocessWithTimeLimit(state, runCustomDiagnosticsDumper,
768
+ reinterpret_cast<void *>(static_cast<boost::uintptr_t>(i)), 2000);
614
769
  ASSU::printError("--------------------------------------\n");
615
770
  }
616
771
 
@@ -630,63 +785,128 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
630
785
  } else {
631
786
  write_nowarn(STDERR_FILENO, "\n", 1);
632
787
  }
788
+
789
+ if (state.crashLogDir[0] != '\0') {
790
+ ASSU::printError("--------------------------------------\n");
791
+ pos = state.messageBuf;
792
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
793
+ pos = ASSU::appendData(pos, end, " ] **************** LOOK HERE FOR CRASH DETAILS *****************\n\n");
794
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
795
+ pos = ASSU::appendData(pos, end, " ] Crash log dumped to this directory:\n");
796
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
797
+ pos = ASSU::appendData(pos, end, " ] ");
798
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
799
+ pos = ASSU::appendData(pos, end, "\n\n");
800
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
801
+ pos = ASSU::appendData(pos, end, " ] **************** LOOK ABOVE FOR CRASH DETAILS ****************\n");
802
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
803
+ }
633
804
  }
634
805
 
635
806
  static bool
636
- createCrashLogFile(char *filename, size_t bufSize, time_t t) {
637
- char *pos = filename;
638
- const char *end = filename + bufSize - 1;
639
- pos = ASSU::appendData(pos, end, "/var/tmp/passenger-crash-log.");
640
- pos = ASSU::appendInteger<time_t, 10>(pos, end, t);
641
- *pos = '\0';
642
-
643
- int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
644
- if (fd == -1) {
645
- pos = filename;
646
- pos = ASSU::appendData(pos, end, ctx->tmpDir);
647
- pos = ASSU::appendData(pos, end, "/passenger-crash-log.");
648
- pos = ASSU::appendInteger<time_t, 10>(pos, end, t);
807
+ createCrashLogDir(AbortHandlerWorkingState &state, time_t t) {
808
+ char *suffixBegin = state.crashLogDir;
809
+ const char *end = state.crashLogDir + sizeof(state.crashLogDir) - 1;
810
+ suffixBegin = ASSU::appendData(suffixBegin, end, "/var/tmp/passenger-crash-log.");
811
+ suffixBegin = ASSU::appendInteger<time_t, 10>(suffixBegin, end, t);
812
+ suffixBegin = ASSU::appendData(suffixBegin, end, ".");
813
+
814
+ // Try a bunch of times to find and create a unique path.
815
+ for (unsigned int i = 0; i < MAX_RANDOM_TOKENS; i++) {
816
+ char *pos = suffixBegin;
817
+ pos = ASSU::appendData(pos, end, ctx->randomTokens + RANDOM_TOKEN_SIZE * i,
818
+ RANDOM_TOKEN_SIZE);
649
819
  *pos = '\0';
650
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
651
- }
652
- if (fd == -1) {
653
- *filename = '\0';
654
- return false;
655
- } else {
656
- close(fd);
820
+
821
+ int ret;
822
+ do {
823
+ ret = mkdir(state.crashLogDir, 0700);
824
+ } while (ret == -1 && errno == EINTR);
825
+ if (ret == -1) {
826
+ if (errno == EEXIST) {
827
+ // Directory exists; try again.
828
+ continue;
829
+ } else {
830
+ int e = errno;
831
+ end = state.messageBuf + sizeof(state.messageBuf);
832
+ pos = state.messageBuf;
833
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
834
+ pos = ASSU::appendData(pos, end, " ] Error creating directory ");
835
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
836
+ pos = ASSU::appendData(pos, end, " for storing crash log: ");
837
+ pos = ASSU::appendData(pos, end, ASSU::limitedStrerror(e));
838
+ pos = ASSU::appendData(pos, end, " (errno=");
839
+ pos = ASSU::appendInteger<int, 10>(pos, end, e);
840
+ pos = ASSU::appendData(pos, end, ")\n");
841
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
842
+ state.crashLogDir[0] = '\0';
843
+ return false;
844
+ }
845
+ }
846
+
847
+ do {
848
+ state.crashLogDirFd = open(state.crashLogDir, O_RDONLY);
849
+ } while (state.crashLogDirFd == -1 && errno == EINTR);
850
+ if (state.crashLogDirFd == -1) {
851
+ int e = errno;
852
+ end = state.messageBuf + sizeof(state.messageBuf);
853
+ pos = state.messageBuf;
854
+ pos = ASSU::appendData(pos, end, state.messagePrefix);
855
+ pos = ASSU::appendData(pos, end, " ] Error opening created directory ");
856
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
857
+ pos = ASSU::appendData(pos, end, " for storing crash log: ");
858
+ pos = ASSU::appendData(pos, end, ASSU::limitedStrerror(e));
859
+ pos = ASSU::appendData(pos, end, " (errno=");
860
+ pos = ASSU::appendInteger<int, 10>(pos, end, e);
861
+ pos = ASSU::appendData(pos, end, ")\n");
862
+ write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
863
+ state.crashLogDir[0] = '\0';
864
+ return false;
865
+ }
866
+
657
867
  return true;
658
868
  }
869
+
870
+ state.crashLogDir[0] = '\0';
871
+ return false;
659
872
  }
660
873
 
661
- static void
662
- forkAndRedirectToTee(char *filename) {
663
- pid_t pid;
874
+ static bool
875
+ forkAndRedirectToTeeAndMainLogFile(const char *crashLogDir) {
664
876
  int p[2];
665
-
666
877
  if (pipe(p) == -1) {
667
- // Signal error condition.
668
- *filename = '\0';
669
- return;
878
+ return false;
670
879
  }
671
880
 
672
- pid = asyncFork();
881
+ char filename[300];
882
+ char *pos = filename;
883
+ const char *end = filename + sizeof(filename) - 1;
884
+
885
+ pos = ASSU::appendData(pos, end, crashLogDir);
886
+ pos = ASSU::appendData(pos, end, "/");
887
+ pos = ASSU::appendData(pos, end, "main.log");
888
+ *pos = '\0';
889
+
890
+ pid_t pid = asyncFork();
673
891
  if (pid == 0) {
674
892
  close(p[1]);
675
893
  dup2(p[0], STDIN_FILENO);
676
- execlp("tee", "tee", filename, (const char * const) 0);
677
- execlp("/usr/bin/tee", "tee", filename, (const char * const) 0);
678
- execlp("cat", "cat", (const char * const) 0);
679
- execlp("/bin/cat", "cat", (const char * const) 0);
680
- execlp("/usr/bin/cat", "cat", (const char * const) 0);
894
+ execlp("tee", "tee", filename, (char *) 0);
895
+ execlp("/usr/bin/tee", "tee", filename, (char *) 0);
896
+ execlp("cat", "cat", (char *) 0);
897
+ execlp("/bin/cat", "cat", (char *) 0);
898
+ execlp("/usr/bin/cat", "cat", (char *) 0);
681
899
  ASSU::printError("ERROR: cannot execute 'tee' or 'cat'; crash log will be lost!\n");
682
900
  _exit(1);
901
+ return false;
683
902
  } else if (pid == -1) {
684
903
  ASSU::printError("ERROR: cannot fork a process for executing 'tee'\n");
685
- *filename = '\0';
904
+ return false;
686
905
  } else {
687
906
  close(p[0]);
688
907
  dup2(p[1], STDOUT_FILENO);
689
908
  dup2(p[1], STDERR_FILENO);
909
+ return true;
690
910
  }
691
911
  }
692
912
 
@@ -717,7 +937,6 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
717
937
  state.info = info;
718
938
  pid_t child;
719
939
  time_t t = time(NULL);
720
- char crashLogFile[256];
721
940
 
722
941
  ctx->callCount++;
723
942
  if (ctx->callCount > 1) {
@@ -756,13 +975,6 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
756
975
 
757
976
  closeEmergencyPipes();
758
977
 
759
- /* We want to dump the entire crash log to both stderr and a log file.
760
- * We use 'tee' for this.
761
- */
762
- if (createCrashLogFile(crashLogFile, sizeof(crashLogFile), t)) {
763
- forkAndRedirectToTee(crashLogFile);
764
- }
765
-
766
978
  {
767
979
  const char *end = state.messagePrefix + sizeof(state.messagePrefix);
768
980
  char *pos = state.messagePrefix;
@@ -771,8 +983,19 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
771
983
  *pos = '\0';
772
984
  }
773
985
 
986
+ /* We want to dump the entire crash log to both stderr and a log file.
987
+ * We use 'tee' for this.
988
+ */
989
+ state.crashLogDir[0] = '\0';
990
+ state.crashLogDirFd = -1;
991
+ if (createCrashLogDir(state, t)) {
992
+ forkAndRedirectToTeeAndMainLogFile(state.crashLogDir);
993
+ }
994
+
774
995
  const char *end = state.messageBuf + sizeof(state.messageBuf);
775
996
  char *pos = state.messageBuf;
997
+ // Print a \n just in case we're aborting in the middle of a non-terminated line.
998
+ pos = ASSU::appendData(pos, end, "\n");
776
999
  pos = ASSU::appendData(pos, end, state.messagePrefix);
777
1000
  pos = ASSU::appendData(pos, end, ", timestamp=");
778
1001
  pos = ASSU::appendInteger<time_t, 10>(pos, end, t);
@@ -786,14 +1009,14 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
786
1009
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
787
1010
 
788
1011
  pos = state.messageBuf;
789
- if (*crashLogFile != '\0') {
1012
+ if (state.crashLogDir[0] != '\0') {
790
1013
  pos = ASSU::appendData(pos, end, state.messagePrefix);
791
- pos = ASSU::appendData(pos, end, " ] Crash log dumped to ");
792
- pos = ASSU::appendData(pos, end, crashLogFile);
793
- pos = ASSU::appendData(pos, end, "\n");
1014
+ pos = ASSU::appendData(pos, end, " ] Crash log files will be dumped to ");
1015
+ pos = ASSU::appendData(pos, end, state.crashLogDir);
1016
+ pos = ASSU::appendData(pos, end, " <--- ******* LOOK HERE FOR DETAILS!!! *******\n");
794
1017
  } else {
795
1018
  pos = ASSU::appendData(pos, end, state.messagePrefix);
796
- pos = ASSU::appendData(pos, end, " ] Could not create crash log file, so dumping to stderr only.\n");
1019
+ pos = ASSU::appendData(pos, end, " ] Could not create crash log directory, so dumping to stderr only.\n");
797
1020
  }
798
1021
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
799
1022
 
@@ -808,11 +1031,11 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
808
1031
  closeAllFileDescriptors(2, true);
809
1032
  #ifdef __APPLE__
810
1033
  const char *command[] = { "osascript", NULL };
811
- execlp("osascript", "osascript", "-e", "beep 2", (const char * const) 0);
1034
+ execlp("osascript", "osascript", "-e", "beep 2", (char *) 0);
812
1035
  printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
813
1036
  #else
814
1037
  const char *command[] = { "beep", NULL };
815
- execlp("beep", "beep", (const char * const) 0);
1038
+ execlp("beep", "beep", (char *) 0);
816
1039
  printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
817
1040
  #endif
818
1041
  _exit(1);
@@ -869,7 +1092,7 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
869
1092
  int e = errno;
870
1093
  pos = state.messageBuf;
871
1094
  pos = ASSU::appendData(pos, end, state.messagePrefix);
872
- pos = ASSU::appendData(pos, end, "] Could fork a child process for dumping diagnostics: fork() failed with errno=");
1095
+ pos = ASSU::appendData(pos, end, "] Could not fork a child process for dumping diagnostics: fork() failed with errno=");
873
1096
  pos = ASSU::appendInteger<int, 10>(pos, end, e);
874
1097
  pos = ASSU::appendData(pos, end, "\n");
875
1098
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
@@ -884,7 +1107,7 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
884
1107
  int e = errno;
885
1108
  pos = state.messageBuf;
886
1109
  pos = ASSU::appendData(pos, end, state.messagePrefix);
887
- pos = ASSU::appendData(pos, end, " ] Could fork a child process for dumping diagnostics: fork() failed with errno=");
1110
+ pos = ASSU::appendData(pos, end, " ] Could not fork a child process for dumping diagnostics: fork() failed with errno=");
888
1111
  pos = ASSU::appendInteger<int, 10>(pos, end, e);
889
1112
  pos = ASSU::appendData(pos, end, "\n");
890
1113
  write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
@@ -905,6 +1128,8 @@ installAbortHandler(const AbortHandlerConfig *config) {
905
1128
 
906
1129
  ctx->config = config;
907
1130
  ctx->backtraceSanitizerPassProgramInfo = true;
1131
+ ctx->randomTokens = strdup(RandomGenerator().generateAsciiString(
1132
+ MAX_RANDOM_TOKENS * RANDOM_TOKEN_SIZE).c_str());
908
1133
  ctx->emergencyPipe1[0] = -1;
909
1134
  ctx->emergencyPipe1[1] = -1;
910
1135
  ctx->emergencyPipe2[0] = -1;
@@ -1038,6 +1263,7 @@ shutdownAbortHandler() {
1038
1263
  free(ctx->tmpDir);
1039
1264
  free(ctx->crashWatchCommand);
1040
1265
  free(ctx->backtraceSanitizerCommand);
1266
+ free(ctx->randomTokens);
1041
1267
  free(ctx->alternativeStack);
1042
1268
  closeEmergencyPipes();
1043
1269
  delete ctx;