bug 1531: Crash when using NS_LOG in destructors of static objects
authorPeter D. Barnes, Jr. <barnes26@llnl.gov>
Sat, 08 Dec 2012 21:44:45 -0800
changeset 9184 065a297f6c9d
parent 9183 1a2abe07b53d
child 9185 23373993f110
bug 1531: Crash when using NS_LOG in destructors of static objects
src/core/model/log.cc
src/core/model/log.h
--- a/src/core/model/log.cc	Sat Dec 08 21:23:44 2012 -0800
+++ b/src/core/model/log.cc	Sat Dec 08 21:44:45 2012 -0800
@@ -127,7 +127,7 @@
           component = tmp;
           if (component == myName || component == "*")
             {
-              int level = LOG_ALL | LOG_PREFIX_TIME | LOG_PREFIX_FUNC | LOG_PREFIX_NODE | LOG_PREFIX_LEVEL;
+              int level = LOG_LEVEL_ALL | LOG_PREFIX_ALL;
               Enable ((enum LogLevel)level);
               return;
             }
@@ -140,6 +140,7 @@
               int level = 0;
               std::string::size_type cur_lev;
               std::string::size_type next_lev = equal;
+              bool pre_pipe = true;  // before the first '|', enables positional 'all', '*'
               do
                 {
                   cur_lev = next_lev + 1;
@@ -169,29 +170,31 @@
                     {
                       level |= LOG_LOGIC;
                     }
-                  else if (lev == "all")
+                  else if ( pre_pipe && ( (lev == "all") || (lev == "*") ) )
                     {
-                      level |= LOG_ALL;
+                      level |= LOG_LEVEL_ALL;
                     }
-                  else if (lev == "prefix_func")
+                  else if ( (lev == "prefix_func") || (lev == "func") )
                     {
                       level |= LOG_PREFIX_FUNC;
                     }
-                  else if (lev == "prefix_time")
+                  else if ( (lev == "prefix_time") || (lev == "time") )
                     {
                       level |= LOG_PREFIX_TIME;
                     }
-                  else if (lev == "prefix_node")
+                  else if ( (lev == "prefix_node") || (lev == "node") )
                     {
                       level |= LOG_PREFIX_NODE;
                     }
-                  else if (lev == "prefix_level")
+                  else if ( (lev == "prefix_level") || (lev == "level") )
                     {
                       level |= LOG_PREFIX_LEVEL;
                     }
-                  else if (lev == "prefix_all")
+                  else if ( (lev == "prefix_all") ||
+                            (!pre_pipe && ( (lev == "all") || (lev == "*") ) )
+                            )
                     {
-                      level |= LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_PREFIX_LEVEL;
+                      level |= LOG_PREFIX_ALL;
                     }
                   else if (lev == "level_error")
                     {
@@ -221,6 +224,12 @@
                     {
                       level |= LOG_LEVEL_ALL;
                     }
+                  else if (lev == "**")
+                    {
+                      level |= LOG_LEVEL_ALL | LOG_PREFIX_ALL;
+                    }
+
+                  pre_pipe = false;
                 } while (next_lev != std::string::npos);
 
               Enable ((enum LogLevel)level);
@@ -263,26 +272,38 @@
   return m_name;
 }
 
-std::map<enum LogLevel, std::string>
-LogComponent::LevelLabels() const
-{
-  std::map<enum LogLevel, std::string> labels;
-  labels[LOG_ERROR]    = "ERROR";
-  labels[LOG_WARN]     = "WARN";
-  labels[LOG_DEBUG]    = "DEBUG";
-  labels[LOG_INFO]     = "INFO";
-  labels[LOG_LOGIC]    = "LOGIC";
-
-  return labels;
-}
-
 std::string
 LogComponent::GetLevelLabel(const enum LogLevel level) const
 {
-  static std::map<enum LogLevel, std::string> levelLabel = LevelLabels ();
-  return levelLabel[level];
+  if (level == LOG_ERROR)
+    {
+      return "ERROR";
+    }
+  else if (level == LOG_WARN)
+    {
+      return "WARN ";
+    }
+  else if (level == LOG_DEBUG)
+    {
+      return "DEBUG";
+    }
+  else if (level == LOG_INFO)
+    {
+      return "INFO ";
+    }
+  else if (level == LOG_FUNCTION)
+    {
+      return "FUNCT";
+    }
+  else if (level == LOG_LOGIC)
+    {
+      return "LOGIC";
+    }
+  else
+    {
+      return "unknown";
+    }
 }
-  
 
 void 
 LogComponentEnable (char const *name, enum LogLevel level)
@@ -362,33 +383,59 @@
           std::cout << "0" << std::endl;
           continue;
         }
-      if (i->second->IsEnabled (LOG_ERROR))
-        {
-          std::cout << "error";
-        }
-      if (i->second->IsEnabled (LOG_WARN))
+      if (i->second->IsEnabled (LOG_LEVEL_ALL))
         {
-          std::cout << "|warn";
+          std::cout << "all";
         }
-      if (i->second->IsEnabled (LOG_DEBUG))
-        {
-          std::cout << "|debug";
-        }
-      if (i->second->IsEnabled (LOG_INFO))
+      else
         {
-          std::cout << "|info";
-        }
-      if (i->second->IsEnabled (LOG_FUNCTION))
-        {
-          std::cout << "|function";
+          if (i->second->IsEnabled (LOG_ERROR))
+            {
+              std::cout << "error";
+            }
+          if (i->second->IsEnabled (LOG_WARN))
+            {
+              std::cout << "|warn";
+            }
+          if (i->second->IsEnabled (LOG_DEBUG))
+            {
+              std::cout << "|debug";
+            }
+          if (i->second->IsEnabled (LOG_INFO))
+            {
+              std::cout << "|info";
+            }
+          if (i->second->IsEnabled (LOG_FUNCTION))
+            {
+              std::cout << "|function";
+            }
+          if (i->second->IsEnabled (LOG_LOGIC))
+            {
+              std::cout << "|logic";
+            }
         }
-      if (i->second->IsEnabled (LOG_LOGIC))
+      if (i->second->IsEnabled (LOG_PREFIX_ALL))
         {
-          std::cout << "|logic";
+          std::cout << "|prefix_all";
         }
-      if (i->second->IsEnabled (LOG_ALL))
+      else
         {
-          std::cout << "|all";
+          if (i->second->IsEnabled (LOG_PREFIX_FUNC))
+            {
+              std::cout << "|func";
+            }
+          if (i->second->IsEnabled (LOG_PREFIX_TIME))
+            {
+              std::cout << "|time";
+            }
+          if (i->second->IsEnabled (LOG_PREFIX_NODE))
+            {
+              std::cout << "|node";
+            }
+          if (i->second->IsEnabled (LOG_PREFIX_LEVEL))
+            {
+              std::cout << "|level";
+            }
         }
       std::cout << std::endl;
     }
@@ -467,8 +514,14 @@
                       || lev == "logic"
                       || lev == "all"
                       || lev == "prefix_func"
+                      || lev == "func"
                       || lev == "prefix_time"
+                      || lev == "time"
                       || lev == "prefix_node"
+                      || lev == "node"
+                      || lev == "prefix_level"
+                      || lev == "level"
+                      || lev == "prefix_all"
                       || lev == "level_error"
                       || lev == "level_warn"
                       || lev == "level_debug"
@@ -477,6 +530,7 @@
                       || lev == "level_logic"
                       || lev == "level_all"
                       || lev == "*"
+                      || lev == "**"
 		     )
                     {
                       continue;
--- a/src/core/model/log.h	Sat Dec 08 21:23:44 2012 -0800
+++ b/src/core/model/log.h	Sat Dec 08 21:44:45 2012 -0800
@@ -18,8 +18,8 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-#ifndef LOG_H
-#define LOG_H
+#ifndef NS3_LOG_H
+#define NS3_LOG_H
 
 #include <string>
 #include <iostream>
@@ -55,7 +55,8 @@
   LOG_PREFIX_FUNC    = 0x80000000, // prefix all trace prints with function
   LOG_PREFIX_TIME    = 0x40000000, // prefix all trace prints with simulation time
   LOG_PREFIX_NODE    = 0x20000000, // prefix all trace prints with simulation node
-  LOG_PREFIX_LEVEL   = 0x10000000  // prefix all trace prints with log level (severity)
+  LOG_PREFIX_LEVEL   = 0x10000000, // prefix all trace prints with log level (severity)
+  LOG_PREFIX_ALL     = 0xf0000000  // all prefixes
 };
 
 /**
@@ -392,7 +393,6 @@
   char const *Name (void) const;
   std::string GetLevelLabel(const enum LogLevel level) const;
 private:
-  std::map<enum LogLevel, std::string> LevelLabels() const;
   int32_t     m_levels;
   char const *m_name;
 };
@@ -424,4 +424,4 @@
 } // namespace ns3
 
 
-#endif /* LOG_H */
+#endif /* NS3_LOG_H */