]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Avoid startup/shutdown crashes [by avoiding static non-POD globals].
authorAlex Rousskov <rousskov@measurement-factory.com>
Mon, 11 Apr 2016 15:14:58 +0000 (09:14 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Mon, 11 Apr 2016 15:14:58 +0000 (09:14 -0600)
Squid crashes on startup when the parent process exit()s after fork()ing
the kid process. Squid may also crash on shutdown after exiting main().

In both cases, the crashes are build- and environment-specific. Many
environments show no problems at all. Even disabling compiler
optimizations may prevent crashes. When crashes do happen, their
symptoms (e.g., backtrace) point to problems during destruction of
global objects, but the details point to innocent objects (e.g., PortCfg
or SSL_CTX).

In some environments, the following malloc error is printed on console
before the crash: "corrupted double-linked list".

This change replaces two StatHist globals used for SBuf statistics
collection with always-available singletons. The replaced globals could
be destructed before the last SBuf object using them, leading to memory
corruption (that would eventually crash Squid).

There are probably more such globals.

src/SBufStatsAction.cc
src/sbuf/DetailedStats.cc
src/sbuf/DetailedStats.h

index 296c9e390f1f0ac9e1720e0f64547990e754d8b0..d97fb03ce9e528b02795463c844028098d2b30f5 100644 (file)
@@ -38,8 +38,8 @@ SBufStatsAction::collect()
 {
     sbdata = SBuf::GetStats();
     mbdata = MemBlob::GetStats();
-    sbsizesatdestruct = *collectSBufDestructTimeStats();
-    mbsizesatdestruct = *collectMemBlobDestructTimeStats();
+    sbsizesatdestruct = collectSBufDestructTimeStats();
+    mbsizesatdestruct = collectMemBlobDestructTimeStats();
 }
 
 static void
index 3d1a181b1bb30615bfc6ebaed44d51a3fe70186c..8ffbf89de128b351741adc01e23a4bc964ba7d54 100644 (file)
  * external dependencies to the SBuf code
  */
 
-static StatHist sbufDestructTimeStats;
-static StatHist memblobDestructTimeStats;
-
-namespace SBufDetailedStatsHistInitializer
-{
-// run the post-instantiation initialization methods for StatHist objects
-struct Initializer {
-    Initializer() {
-        sbufDestructTimeStats.logInit(100,30.0,128000.0);
-        memblobDestructTimeStats.logInit(100,30.0,128000.0);
-    }
-};
-Initializer initializer;
+static StatHist *
+newStatHist() {
+    StatHist *stats = new StatHist;
+    stats->logInit(100, 30.0, 128000.0);
+    return stats;
 }
 
-void
-recordSBufSizeAtDestruct(SBuf::size_type sz)
+StatHist &
+collectSBufDestructTimeStats()
 {
-    sbufDestructTimeStats.count(static_cast<double>(sz));
+    static StatHist *stats = newStatHist();
+    return *stats;
 }
 
-const StatHist *
-collectSBufDestructTimeStats()
+StatHist &
+collectMemBlobDestructTimeStats()
 {
-    return &sbufDestructTimeStats;
+    static StatHist *stats = newStatHist();
+    return *stats;
 }
 
 void
-recordMemBlobSizeAtDestruct(SBuf::size_type sz)
+recordSBufSizeAtDestruct(SBuf::size_type sz)
 {
-    memblobDestructTimeStats.count(static_cast<double>(sz));
+    collectSBufDestructTimeStats().count(static_cast<double>(sz));
 }
 
-const StatHist *
-collectMemBlobDestructTimeStats()
+void
+recordMemBlobSizeAtDestruct(SBuf::size_type sz)
 {
-    return &memblobDestructTimeStats;
+    collectMemBlobDestructTimeStats().count(static_cast<double>(sz));
 }
 
index f5bc27f819a64e447f344774706334decfa7b722..97501ea5d542d9083406d27243063b66a681d158 100644 (file)
@@ -16,20 +16,14 @@ class StatHist;
 /// Record the size a SBuf had when it was destructed
 void recordSBufSizeAtDestruct(SBuf::size_type sz);
 
-/** Collect the SBuf size-at-destruct-time histogram
- *
- * \note the returned StatHist object must not be freed
- */
-const StatHist * collectSBufDestructTimeStats();
+/// the SBuf size-at-destruct-time histogram
+StatHist &collectSBufDestructTimeStats();
 
 /// Record the size a MemBlob had when it was destructed
 void recordMemBlobSizeAtDestruct(MemBlob::size_type sz);
 
-/** Collect the MemBlob size-at-destruct-time histogram
- *
- * \note the returned StatHist object must not be freed
- */
-const StatHist * collectMemBlobDestructTimeStats();
+/// the MemBlob size-at-destruct-time histogram
+StatHist &collectMemBlobDestructTimeStats();
 
 #endif /* SQUID_SBUFDETAILEDSTATS_H */