merge with debug tree

This commit is contained in:
Mathieu Lacage
2007-02-16 09:32:02 +01:00
10 changed files with 376 additions and 62 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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.

View 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
View 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
View 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
View 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 */

View File

@@ -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

View File

@@ -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
View 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 */