Patchwork RFC: add some static probes to libstdc++

login
register
mail settings
Submitter Tom Tromey
Date Feb. 27, 2013, 9:52 p.m.
Message ID <87sj4hzap2.fsf@fleche.redhat.com>
Download mbox | patch
Permalink /patch/223711/
State New
Headers show

Comments

Tom Tromey - Feb. 27, 2013, 9:52 p.m.
I've been working a bit on improving exception-related features in gdb.

I had two goals which led to this particular patch.

First, I wanted to be able to implement type-name-based filtering for
"catch catch" and friends.  (This feature was documented in the past,
but never implemented, and occasionally people run across the old docs
and are disappointed that it doesn't work.)

Second, I wanted to be able to expose the currently-thrown-or-caught
exception to the gdb user as a convenience variable.  I thought this
would make it simpler to write more sophisticated catch/throw condition
expressions.

After digging into libsupc++ a bit, I found that I needed some extra
information to be exposed.  The best way I know of to do that is to add
some static probes to the library.  These are cheap, work well with gdb,
and do not require debuginfo in order to work.

Note that this kind of probe is already in use in libgcc.  So, accepting
them into libstdc++ doesn't mean any extra dependencies or the like.

I needed 3 probes, one each for catch, throw, and rethrow.  SDT probes
take both a provider (I chose "libstdcxx") and a name (I chose the
obvious ones).

The arguments to the probes are chosen so that they expose the
information gdb needs, namely a pointer to the exception object and a
pointer to the exception's type_info.


I'm not totally sure if the unwind-cxx.h changes are written the best
way possible.


I'm posting this now to get reactions to the probe before cleaning up
the corresponding gdb patches for submission.  I've built it both with
and without sys/sdt.h, but I haven't yet run the test suite.

Tom

2013-02-27  Tom Tromey  <tromey@redhat.com>

	* libsupc++/unwind-cxx.h: Include ../config.h, sys/sdt.h.
	(PROBE2): New macro.
	* libsupc++/eh_throw.cc (__cxa_throw, __cxa_rethrow): Add probe.
	* libsupc++/eh_catch.cc (__cxa_begin_catch): Add probe.
	* configure.ac: Check for sys/sdt.h.
	* configure, config.h.in: Rebuild.
Dave Korn - Feb. 28, 2013, 12:32 p.m.
On 27/02/2013 21:52, Tom Tromey wrote:

> I'm posting this now to get reactions to the probe before cleaning up
> the corresponding gdb patches for submission.  I've built it both with
> and without sys/sdt.h, but I haven't yet run the test suite.

  How did it build in the without sys/sdt.h case?

> +#ifdef HAVE_SYS_SDT_H
> +#include <sys/sdt.h>
> +/* We only want to use stap probes starting with v3.  Earlier versions
> +   added too much startup cost.  */
> +#if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
> +#define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2)
> +#else
> +#define PROBE2(name, arg1, arg2)
> +#endif
> +#endif
> +

  Without HAVE_SYS_SDT_H, there's no definition of PROBE2 at all, but you use
it unconditionally in eh_{catch,throw}.cc.  Am I missing something?

    cheers,
      DaveK
Tom Tromey - Feb. 28, 2013, 2:23 p.m.
>>>>> "Dave" == Dave Korn <dave.korn.cygwin@gmail.com> writes:

Dave>   How did it build in the without sys/sdt.h case?

Dave> Without HAVE_SYS_SDT_H, there's no definition of PROBE2 at all,
Dave> but you use it unconditionally in eh_{catch,throw}.cc.  Am I
Dave> missing something?

Ugh.  I must have made some mistake in my testing.
I will fix it up.

Tom

Patch

diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 66164a2..d0b8c27 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -216,7 +216,7 @@  GLIBCXX_CHECK_SYSCTL_HW_NCPU
 AC_CHECK_HEADERS([endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \
 locale.h machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \
 strings.h sys/ipc.h sys/isa_defs.h sys/machine.h sys/param.h \
-sys/resource.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
+sys/resource.h sys/sdt.h sys/sem.h sys/stat.h sys/time.h sys/types.h unistd.h \
 wchar.h wctype.h])
 
 # Only do link tests if native. Else, hardcode.
diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc
index 779f5a3..43e875a 100644
--- a/libstdc++-v3/libsupc++/eh_catch.cc
+++ b/libstdc++-v3/libsupc++/eh_catch.cc
@@ -80,6 +80,9 @@  __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW
     }
 
   objectp = __gxx_caught_object(exceptionObject);
+
+  PROBE2 (catch, objectp, header->exceptionType);
+
 #ifdef __ARM_EABI_UNWINDER__
   _Unwind_Complete(exceptionObject);
 #endif
diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc
index 297aa04..a79a025 100644
--- a/libstdc++-v3/libsupc++/eh_throw.cc
+++ b/libstdc++-v3/libsupc++/eh_throw.cc
@@ -60,6 +60,8 @@  extern "C" void
 __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
 			 void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
 {
+  PROBE2 (throw, obj, tinfo);
+
   // Definitely a primary.
   __cxa_refcounted_exception *header
     = __get_refcounted_exception_header_from_obj (obj);
@@ -97,7 +99,12 @@  __cxxabiv1::__cxa_rethrow ()
       if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
 	globals->caughtExceptions = 0;
       else
-	header->handlerCount = -header->handlerCount;
+	{
+	  header->handlerCount = -header->handlerCount;
+	  // Only notify probe for C++ exceptions.
+	  PROBE2 (rethrow, __get_object_from_ambiguous_exception(header),
+		  header->exceptionType);
+	}
 
 #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
       _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h
index e2b945d..69a0c16 100644
--- a/libstdc++-v3/libsupc++/unwind-cxx.h
+++ b/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -28,6 +28,8 @@ 
 #ifndef _UNWIND_CXX_H
 #define _UNWIND_CXX_H 1
 
+#include "../config.h"
+
 // Level 2: C++ ABI
 
 #include <typeinfo>
@@ -37,6 +39,17 @@ 
 #include <bits/atomic_word.h>
 #include <cxxabi.h>
 
+#ifdef HAVE_SYS_SDT_H
+#include <sys/sdt.h>
+/* We only want to use stap probes starting with v3.  Earlier versions
+   added too much startup cost.  */
+#if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
+#define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2)
+#else
+#define PROBE2(name, arg1, arg2)
+#endif
+#endif
+
 #pragma GCC visibility push(default)
 
 namespace __cxxabiv1