merge with debug tree
This commit is contained in:
25
SConstruct
25
SConstruct
@@ -18,6 +18,8 @@ ns3.add(core)
|
||||
core.add_sources([
|
||||
'reference-list-test.cc',
|
||||
'callback-test.cc',
|
||||
'debug.cc',
|
||||
'assert.cc',
|
||||
'ptr.cc',
|
||||
'debug.cc',
|
||||
'test.cc'
|
||||
@@ -41,9 +43,25 @@ core.add_inst_headers([
|
||||
'callback.h',
|
||||
'ptr.h',
|
||||
'debug.h',
|
||||
'assert.h',
|
||||
'fatal-error.h',
|
||||
'test.h'
|
||||
])
|
||||
|
||||
def config_core (env, config):
|
||||
retval = []
|
||||
# XXX This check is primitive but it should be
|
||||
# good enough for now.
|
||||
if config.CheckCHeader ('stdlib.h') == 1:
|
||||
retval.append ('#define HAVE_STDLIB_H 1')
|
||||
retval.append ('#define HAVE_GETENV 1')
|
||||
else:
|
||||
retval.append ('#undef HAVE_STDLIB_H')
|
||||
retval.append ('#undef HAVE_GETENV')
|
||||
return retval
|
||||
core.add_config (config_core)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# The Simu module
|
||||
@@ -247,6 +265,13 @@ replay_simu.add_source('replay-simulation.cc')
|
||||
|
||||
|
||||
# samples
|
||||
sample_debug = build.Ns3Module('sample-debug', 'samples')
|
||||
sample_debug.set_executable()
|
||||
ns3.add(sample_debug)
|
||||
sample_debug.add_dep('core')
|
||||
sample_debug.add_source('main-debug.cc')
|
||||
sample_debug.add_source('main-debug-other.cc')
|
||||
|
||||
sample_callback = build.Ns3Module('sample-callback', 'samples')
|
||||
sample_callback.set_executable()
|
||||
ns3.add(sample_callback)
|
||||
|
||||
12
build.py
12
build.py
@@ -458,8 +458,10 @@ class Ns3:
|
||||
|
||||
|
||||
dbg_env = env.Copy()
|
||||
env.Append(CFLAGS = debug_flags,
|
||||
CXXFLAGS = debug_flags, )
|
||||
dbg_env.Append(CFLAGS = debug_flags,
|
||||
CXXFLAGS = debug_flags,
|
||||
CPPDEFINES = ['NS3_DEBUG_ENABLE',
|
||||
'NS3_ASSERT_ENABLE'])
|
||||
# debug static support
|
||||
variant.static = True
|
||||
variant.env = dbg_env
|
||||
@@ -469,8 +471,10 @@ class Ns3:
|
||||
dbg_env.Alias('dbg-static', builder)
|
||||
|
||||
dbg_env = env.Copy()
|
||||
env.Append(CFLAGS=debug_flags,
|
||||
CXXFLAGS=debug_flags, )
|
||||
dbg_env.Append(CFLAGS=debug_flags,
|
||||
CXXFLAGS=debug_flags,
|
||||
CPPDEFINES = ['NS3_DEBUG_ENABLE',
|
||||
'NS3_ASSERT_ENABLE'])
|
||||
# debug shared support
|
||||
variant.static = False
|
||||
variant.env = dbg_env
|
||||
|
||||
@@ -996,7 +996,7 @@ INCLUDE_FILE_PATTERNS =
|
||||
# undefined via #undef or recursively expanded use the := operator
|
||||
# instead of the = operator.
|
||||
|
||||
PREDEFINED = RUN_SELF_TESTS
|
||||
PREDEFINED = RUN_SELF_TESTS NS3_DEBUG_ENABLE
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
|
||||
13
samples/main-debug-other.cc
Normal file
13
samples/main-debug-other.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("MyComponentB");
|
||||
|
||||
namespace foo {
|
||||
|
||||
void OneFunction (void)
|
||||
{
|
||||
NS_DEBUG ("OneFunction debug");
|
||||
}
|
||||
|
||||
}; // namespace foo
|
||||
27
samples/main-debug.cc
Normal file
27
samples/main-debug.cc
Normal file
@@ -0,0 +1,27 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("MyComponentA");
|
||||
|
||||
// declare other function
|
||||
namespace foo {
|
||||
void OneFunction (void);
|
||||
}
|
||||
|
||||
int main (int argc, int argv)
|
||||
{
|
||||
NS_DEBUG ("nargc="<<argc);
|
||||
|
||||
foo::OneFunction ();
|
||||
|
||||
NS_DEBUG ("other debug output");
|
||||
|
||||
int a;
|
||||
a = 0;
|
||||
|
||||
NS_ASSERT (a == 0);
|
||||
NS_ASSERT_MSG (a == 0, "my msg");
|
||||
NS_ASSERT (a != 0)
|
||||
NS_ASSERT_MSG (a != 0, "my 2 msg");
|
||||
}
|
||||
41
src/core/assert.cc
Normal file
41
src/core/assert.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
void
|
||||
AssertBreakpoint (void)
|
||||
{
|
||||
int *a = 0;
|
||||
/**
|
||||
* we test here to allow a debugger to change the value of
|
||||
* the variable 'a' to allow the debugger to avoid the
|
||||
* subsequent segfault.
|
||||
*/
|
||||
if (a == 0)
|
||||
{
|
||||
*a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
95
src/core/assert.h
Normal file
95
src/core/assert.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef ASSERT_H
|
||||
#define ASSERT_H
|
||||
|
||||
/**
|
||||
* \defgroup assert
|
||||
* \brief assert functions and macros
|
||||
*
|
||||
* The assert macros are used to verify
|
||||
* at runtime that a certain condition is true. If it is
|
||||
* not true, the program halts. These checks are built
|
||||
* into the program only in debugging builds. They are
|
||||
* removed in optimized builds.
|
||||
*/
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup debugging
|
||||
*
|
||||
* When an NS_ASSERT cannot verify its condition,
|
||||
* this function is called. This is where you should
|
||||
* be able to put a breakpoint with a debugger if
|
||||
* you want to catch assertions before the program
|
||||
* halts.
|
||||
*/
|
||||
void AssertBreakpoint (void);
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#ifdef NS3_ASSERT_ENABLE
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* \ingroup assert
|
||||
* \param condition condition to verifiy.
|
||||
*
|
||||
* At runtime, in debugging builds, if this condition is not
|
||||
* true, the program prints the source file, line number and
|
||||
* unverified condition and halts in the ns3::AssertBreakpoint
|
||||
* function.
|
||||
*/
|
||||
#define NS_ASSERT(condition) \
|
||||
if (!(condition)) \
|
||||
{ \
|
||||
std::cout << "assert failed. file=" << __FILE__ << \
|
||||
", line=" << __LINE__ << ", cond=\""#condition << \
|
||||
"\"" << std::endl; \
|
||||
ns3::AssertBreakpoint (); \
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup assert
|
||||
* \param condition condition to verifiy.
|
||||
* \param message message to output
|
||||
*
|
||||
* At runtime, in debugging builds, if this condition is not
|
||||
* true, the program prints the message to output and
|
||||
* halts in the ns3::AssertBreakpoint function.
|
||||
*/
|
||||
#define NS_ASSERT_MSG(condition, message) \
|
||||
if (!(condition)) \
|
||||
{ \
|
||||
std::cout << message << std::endl; \
|
||||
ns3::AssertBreakpoint (); \
|
||||
}
|
||||
|
||||
#else /* NS3_ASSERT_ENABLE */
|
||||
|
||||
#define NS_ASSERT(cond)
|
||||
#define NS_ASSERT_MSG(cond,msg)
|
||||
|
||||
#endif /* NS3_ASSERT_ENABLE */
|
||||
|
||||
#endif /* ASSERT_H */
|
||||
@@ -23,8 +23,7 @@
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include "debug.h"
|
||||
|
||||
// #include "ns3/core-config.h"
|
||||
#include "ns3/core-config.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@@ -53,33 +52,51 @@ DebugComponentEnableEnvVar (void)
|
||||
while (true)
|
||||
{
|
||||
next = env.find_first_of (";", cur);
|
||||
if (next == std::string::npos)
|
||||
{
|
||||
std::string tmp = env.substr (cur, next);
|
||||
bool found = false;
|
||||
for (ComponentListI i = g_components.begin ();
|
||||
i != g_components.end ();
|
||||
i++)
|
||||
std::string tmp = std::string (env, cur, next);
|
||||
{
|
||||
/* The following code is a workaround for a bug in the g++
|
||||
* c++ string library. Its goal is to remove any trailing ';'
|
||||
* from the string even though there should not be any in
|
||||
* it. This code should be safe even if the bug is not there.
|
||||
*/
|
||||
std::string::size_type trailing = tmp.find_first_of (";");
|
||||
tmp = tmp.substr (0, trailing);
|
||||
}
|
||||
if (tmp.size () == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
bool found = false;
|
||||
for (ComponentListI i = g_components.begin ();
|
||||
i != g_components.end ();
|
||||
i++)
|
||||
{
|
||||
if (i->first.compare (tmp) == 0)
|
||||
{
|
||||
if (i->first.compare (tmp) == 0)
|
||||
{
|
||||
found = true;
|
||||
i->second->Enable ();
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
i->second->Enable ();
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
std::cout << "No debug component named=\"" << tmp << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
std::cout << "No debug component named=\"" << tmp << "\"" << std::endl;
|
||||
}
|
||||
if (next == std::string::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
cur = next + 1;
|
||||
if (cur >= env.size ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
DebugComponent::DebugComponent (std::string name)
|
||||
DebugComponent::DebugComponent (char const * name)
|
||||
: m_isEnabled (false)
|
||||
{
|
||||
for (ComponentListI i = g_components.begin ();
|
||||
@@ -93,15 +110,15 @@ DebugComponent::DebugComponent (std::string name)
|
||||
bool
|
||||
DebugComponent::IsEnabled (void)
|
||||
{
|
||||
if (g_firstDebug) {
|
||||
DebugComponentEnableEnvVar ();
|
||||
g_firstDebug = false;
|
||||
}
|
||||
return m_isEnabled;
|
||||
}
|
||||
void
|
||||
DebugComponent::Enable (void)
|
||||
{
|
||||
if (g_firstDebug) {
|
||||
DebugComponentEnableEnvVar ();
|
||||
g_firstDebug = false;
|
||||
}
|
||||
m_isEnabled = true;
|
||||
}
|
||||
void
|
||||
@@ -151,6 +168,6 @@ DebugComponentPrintList (void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
|
||||
107
src/core/debug.h
107
src/core/debug.h
@@ -21,38 +21,49 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define NS3_DEBUG_ENABLE
|
||||
#endif
|
||||
|
||||
#ifdef NS3_DEBUG_ENABLE
|
||||
#define NS3_DEBUG(x) x
|
||||
#else
|
||||
#define NS3_DEBUG(x)
|
||||
#endif
|
||||
|
||||
#define NS3_TRACEALL(traceout) NS3_DEBUG(std::cerr << traceout << std::endl;)
|
||||
|
||||
#define NS3_TRACE(boolLevel, traceout) \
|
||||
NS3_DEBUG( \
|
||||
if (boolLevel) { \
|
||||
std::cerr << traceout << std::endl; \
|
||||
} \
|
||||
)
|
||||
|
||||
/**
|
||||
* \defgroup debugging
|
||||
* \brief Debugging functions and macros
|
||||
*
|
||||
* - DEBUG functionality: macros which allow developers to
|
||||
* send information out on screen only in debugging builds.
|
||||
* All debug messages are disabled by default. To enable
|
||||
* selected debug messages, use the ns3::DebugComponentEnable
|
||||
* function. Alternatively, you can use the NS_DEBUG
|
||||
* environment variable to define a ';'-separated list of
|
||||
* messages to enable. For example, NS_DEBUG=a;b;c;DAFD;GH
|
||||
* would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'.
|
||||
*/
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \param name a debug component name
|
||||
* \ingroup debugging
|
||||
*
|
||||
* Enable the debugging output associated with that debug component.
|
||||
* The debugging output can be later disabled with a call
|
||||
* to ns3::DebugComponentDisable.
|
||||
*/
|
||||
void DebugComponentEnable (char const *name);
|
||||
/**
|
||||
* \param name a debug component name
|
||||
* \ingroup debugging
|
||||
*
|
||||
* Disable the debugging output associated with that debug component.
|
||||
* The debugging output can be later re-enabled with a call
|
||||
* to ns3::DebugComponentEnable.
|
||||
*/
|
||||
void DebugComponentDisable (char const *name);
|
||||
/**
|
||||
* \ingroup debugging
|
||||
* Print the list of debugging messages available.
|
||||
*/
|
||||
void DebugComponentPrintList (void);
|
||||
|
||||
class DebugComponent {
|
||||
public:
|
||||
DebugComponent (std::string name);
|
||||
DebugComponent (char const *name);
|
||||
bool IsEnabled (void);
|
||||
void Enable (void);
|
||||
void Disable (void);
|
||||
@@ -65,18 +76,56 @@ private:
|
||||
|
||||
#ifdef NS3_DEBUG_ENABLE
|
||||
|
||||
#define DEBUG_COMPONENT_DEFINE(name) \
|
||||
static DebugComponent g_debug = DebugComponent (name);
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#define DEBUG(x) \
|
||||
|
||||
/**
|
||||
* \ingroup debugging
|
||||
* \param name a string
|
||||
*
|
||||
* Define a Debug component with a specific name. This macro
|
||||
* should be used at the top of every file in which you want
|
||||
* to use the NS_DEBUG macro. This macro defines a new
|
||||
* "debug component" which can be later selectively enabled
|
||||
* or disabled with the ns3::DebugComponentEnable and
|
||||
* ns3::DebugComponentDisable functions or with the NS_DEBUG
|
||||
* environment variable.
|
||||
*/
|
||||
#define NS_DEBUG_COMPONENT_DEFINE(name) \
|
||||
static ns3::DebugComponent g_debug = ns3::DebugComponent (name);
|
||||
|
||||
/**
|
||||
* \ingroup debugging
|
||||
* \param msg message to output
|
||||
*
|
||||
* Generate debugging output in the "debug component" of the
|
||||
* current file. i.e., every call to NS_DEBUG from within
|
||||
* a file implicitely generates out within the component
|
||||
* defined with the NS_DEBUG_COMPONENT_DEFINE macro in the
|
||||
* same file.
|
||||
*/
|
||||
#define NS_DEBUG(msg) \
|
||||
if (g_debug.IsEnabled ()) \
|
||||
{ \
|
||||
std::cout << x << std::endl; \
|
||||
std::cout << msg << std::endl; \
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup debugging
|
||||
* \param msg message to output
|
||||
*
|
||||
* Generate debugging output unconditionally in all
|
||||
* debug builds.
|
||||
*/
|
||||
#define NS_DEBUG_UNCOND (msg) \
|
||||
std::cout << msg << std::endl;
|
||||
|
||||
#else /* NS3_DEBUG_ENABLE */
|
||||
|
||||
#define DEBUG_COMPONENT_DEFINE(name)
|
||||
#define DEBUG(x)
|
||||
#define NS_DEBUG_COMPONENT_DEFINE(name)
|
||||
#define NS_DEBUG(x)
|
||||
#define NS_DEBUG_UNCOND(msg)
|
||||
|
||||
#endif /* NS3_DEBUG_ENABLE */
|
||||
|
||||
|
||||
43
src/core/fatal-error.h
Normal file
43
src/core/fatal-error.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef FATAL_ERROR_H
|
||||
#define FATAL_ERROR_H
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
/**
|
||||
* \defgroup error
|
||||
* \brief fatal error handling
|
||||
*
|
||||
* \param msg message to output when this macro is hit.
|
||||
*
|
||||
* When this macro is hit at runtime, the user-specified
|
||||
* error message is output and the program is halted by calling
|
||||
* the ns3::AssertBreakpoint function. This macro is enabled
|
||||
* unconditionally in all builds, including debug and optimized
|
||||
* builds.
|
||||
*/
|
||||
#define NS_FATAL_ERROR(msg) \
|
||||
std::cout << msg << std::endl; \
|
||||
ns3::AssertBreakpoint ();
|
||||
|
||||
|
||||
#endif /* FATAL_ERROR_H */
|
||||
Reference in New Issue
Block a user