Bug #7: Better breakpoints.
--- a/src/core/assert.cc Thu Aug 02 08:55:56 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/* -*- 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
--- a/src/core/assert.h Thu Aug 02 08:55:56 2007 +0200
+++ b/src/core/assert.h Thu Aug 02 13:59:08 2007 +0100
@@ -21,36 +21,12 @@
#ifndef ASSERT_H
#define ASSERT_H
-/**
- * \defgroup assert 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>
+#include "breakpoint.h"
+
/**
* \ingroup assert
* \param condition condition to verifiy.
@@ -68,7 +44,7 @@
std::cerr << "assert failed. file=" << __FILE__ << \
", line=" << __LINE__ << ", cond=\""#condition << \
"\"" << std::endl; \
- ns3::AssertBreakpoint (); \
+ NS_BREAKPOINT (); \
} \
} \
while (false)
@@ -89,7 +65,7 @@
if (!(condition)) \
{ \
std::cerr << message << std::endl; \
- ns3::AssertBreakpoint (); \
+ NS_BREAKPOINT (); \
} \
} \
while (false)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/breakpoint.cc Thu Aug 02 13:59:08 2007 +0100
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006,2007 INRIA, INESC Porto
+ * 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>
+ * Author: Gustavo Carneiro <gjc@inescporto.pt>
+ */
+
+#include "breakpoint.h"
+#include "ns3/core-config.h"
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+namespace ns3 {
+
+#ifdef HAVE_SIGNAL_H
+
+void
+Breakpoint (void)
+{
+ raise (SIGTRAP);
+}
+
+#else
+
+void
+Breakpoint (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;
+ }
+}
+
+#endif // HAVE_SIGNAL_H
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/breakpoint.h Thu Aug 02 13:59:08 2007 +0100
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006,2007 INESC Porto, 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: Gustavo Carneiro <gjc@inescporto.pt>
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef BREAKPOINT_H
+#define BREAKPOINT_H
+
+namespace ns3 {
+
+/* Hacker macro to place breakpoints for selected machines.
+ * Actual use is strongly discouraged of course ;)
+ * Copied from GLib 2.12.9.
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/**
+ * \ingroup debugging
+ *
+ * Inserts a breakpoint instruction (or equivalent system call) into
+ * the code for selected machines. When an NS_ASSERT cannot verify its condition,
+ * this macro is used. Falls back to calling
+ * AssertBreakpoint() for architectures where breakpoint assembly
+ * instructions are not supported.
+ */
+#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2
+# define NS_BREAKPOINT() \
+ do{ __asm__ __volatile__ ("int $03"); }while(false)
+#elif defined (_MSC_VER) && defined (_M_IX86)
+# define NS_BREAKPOINT() \
+ do{ __asm int 3h }while(false)
+#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2
+# define NS_BREAKPOINT() \
+ do{ __asm__ __volatile__ ("bpt"); }while(false)
+#else /* !__i386__ && !__alpha__ */
+# define NS_BREAKPOINT() ns3::BreakpointFallback ()
+#endif
+
+/**
+ * \brief fallback breakpoint function
+ *
+ * This function is used by the NS_BREAKPOINT() macro as a fallback
+ * for when breakpoint assembly instructions are not available. It
+ * attempts to halt program execution either by a raising SIGTRAP, on
+ * unix systems, or by dereferencing a null pointer.
+ *
+ * Normally you should not call this function directly.
+ */
+void BreakpointFallback (void);
+
+
+}//namespace ns3
+
+
+#endif /* BREAKPOINT_H */
--- a/src/core/fatal-error.h Thu Aug 02 08:55:56 2007 +0200
+++ b/src/core/fatal-error.h Thu Aug 02 13:59:08 2007 +0100
@@ -21,7 +21,7 @@
#ifndef FATAL_ERROR_H
#define FATAL_ERROR_H
-#include "assert.h"
+#include "breakpoint.h"
#include <iostream>
/**
@@ -32,7 +32,7 @@
*
* 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
+ * the NS_DEBUG_BREAKPOINT macro. This macro is enabled
* unconditionally in all builds, including debug and optimized
* builds.
*/
@@ -40,7 +40,7 @@
do \
{ \
std::cout << msg << std::endl; \
- ns3::AssertBreakpoint (); \
+ NS_BREAKPOINT (); \
} \
while (false)
--- a/src/core/uid-manager.cc Thu Aug 02 08:55:56 2007 +0200
+++ b/src/core/uid-manager.cc Thu Aug 02 13:59:08 2007 +0100
@@ -20,6 +20,7 @@
*/
#include "uid-manager.h"
#include "ns3/fatal-error.h"
+#include "ns3/assert.h"
namespace ns3 {
--- a/src/core/wscript Thu Aug 02 08:55:56 2007 +0200
+++ b/src/core/wscript Thu Aug 02 13:59:08 2007 +0100
@@ -15,6 +15,12 @@
e.define = 'HAVE_GETENV'
e.run()
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'signal.h'
+ e.define = 'HAVE_SIGNAL_H'
+ e.run()
+
conf.write_config_header('ns3/core-config.h')
@@ -26,7 +32,7 @@
core.source = [
'callback-test.cc',
'debug.cc',
- 'assert.cc',
+ 'breakpoint.cc',
'ptr.cc',
'object.cc',
'test.cc',
@@ -58,6 +64,7 @@
'object.h',
'debug.h',
'assert.h',
+ 'breakpoint.h',
'fatal-error.h',
'test.h',
'random-variable.h',