Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Hui Zhu <teawater@gmail.com>
To: Tom Tromey <tromey@redhat.com>
Cc: Yao Qi <yao@codesourcery.com>, Hui Zhu <hui_zhu@mentor.com>,
		gdb-patches ml <gdb-patches@sourceware.org>
Subject: Re: [PATCH] Add CTF support to GDB [3/4] ctf target
Date: Fri, 21 Dec 2012 08:23:00 -0000	[thread overview]
Message-ID: <CANFwon0k48X5dAo_K=dR2novtD+qo+U3HftgvqsSZ1ZJno1MHQ@mail.gmail.com> (raw)
In-Reply-To: <87zk203zw3.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 6239 bytes --]

On Fri, Nov 30, 2012 at 4:41 AM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Hui" == Hui Zhu <teawater@gmail.com> writes:
>
> Hui> --- a/configure.ac
> Hui> +++ b/configure.ac
> Hui> @@ -2306,6 +2306,134 @@ if test "$enable_gdbserver" = "yes" -a "
> Hui>    AC_MSG_ERROR(Automatic gdbserver build is not supported for this configuration)
> Hui>  fi
>
> Hui> +AC_ARG_ENABLE(ctf-target,
> Hui> +AS_HELP_STRING([--enable-ctf-target],
> Hui> +               [enable ctf target (yes/no/auto, default is auto)]),
> Hui> +[case "${enableval}" in
> Hui> +  yes| no|auto) ;;
> Hui> +  *) AC_MSG_ERROR(bad value ${enableval} for --enable-ctf-target option) ;;
> Hui> +esac],[enable_ctf_target=auto])
> Hui> +
> Hui> +if test "$enable_ctf_target" = "yes" || test "$enable_ctf_target" = "auto"; then
> Hui> +  pkg_config_args=glib-2.0
> Hui> +  for module in . gmodule
> [...]
>
> This seems like an awful lot of code just to check for one library.
> Does libbabeltrace not come with its own pkg-config file?
> Or not link against its dependencies?
>

The developer of babeltrace added a patch to "provides a basic
pkg-config file for libbabeltrace" after I sent request about that.
So its trunk support pkg-config now.
New patch support it now.

> Hui> +static struct bt_context *ctx = NULL;
> Hui> +static struct bt_ctf_iter *iter = NULL;
> Hui> +static int current_tp;
> Hui> +static struct bt_ctf_event *ctf_event;
>
> Comments.
>
> Most of this patch was impenetrable to me due to the general lack of
> comments.

I added comments to each function to this patch.

>
> Hui> +    error (_("Try to use libbabeltrace got error"));
>
> Please phrase differently.

I change it to "Initialize libbabeltrace fail".

>
> Hui> +      error (_("Try to open \"%s\" got error"), dirname);
>
> Likewise.

I change it to:
error (_("Use libbabeltrace open \"%s\" fail"), dirname);

>
> Hui> +      if (strcmp (bt_ctf_field_name(list_d[i]), name) == 0)
>
> Missing a space before a paren.  This happens in a few spots.

Fixed.

>
> Hui> +  /* XXX: some types are not support.  */
>
> How about an error in this case?
> No new FIXME comments anyway.

Removed.
When this type is not support, GDB will output a warning for that.

>
> Hui> +extern void output_command (char *, int);
>
> Time for this to go into a header file.

Fixed.

>
> Hui> --- a/target.h
> Hui> +++ b/target.h
> Hui> @@ -811,6 +811,10 @@ struct target_ops
> Hui>         successful, 0 otherwise.  */
> Hui>      int (*to_set_trace_notes) (char *user, char *notes, char* stopnotes);
>
> Hui> +    const char *(*to_get_current_tracepoint_name) (void);
> Hui> +
> Hui> +    int (*to_trace_dump) (int from_tty);
>
> These sorts of additions particularly need documentation.

I change it to:
    /* Return name of current traceframe's tracepoint.
       Return NULL if the target doesn't support it.  */

    const char *(*to_get_current_tracepoint_name) (void);

    /* Dump all the value of current traceframe.
       Return fail if the target doesn't support it.  Then GDB will
       dump all the value of current traceframe with itself.  */

    int (*to_trace_dump) (int from_tty);

>
> Hui> +#define target_get_current_tracepoint_name() \
> Hui> +(*current_target.to_get_current_tracepoint_name) ()
> Hui> +
> Hui> +#define target_trace_dump(from_tty) \
> Hui> +(*current_target.to_trace_dump) (from_tty)
>
> Formatting.

Fixed.

>
> Hui> --- a/tracepoint.c
> Hui> +++ b/tracepoint.c
> Hui> @@ -2243,7 +2243,7 @@ tfind_1 (enum trace_find_type type, int
> Hui>       below (correctly) decide to print out the source location of the
> Hui>       trace frame.  */
> Hui>    if (!(type == tfind_number && num == -1)
> Hui> -      && (has_stack_frames () || traceframe_number >= 0))
> Hui> +      && has_stack_frames ())
>
> I'm curious about the rationale and impact of this change.

I agree with this change looks odd.  But it is indispensable for this patch.
According to my prev mail in this thread, maybe you had gotten that
CTF format is not base on memory mode like tfild.  So it don't have
frame or something like it.

All this part of code is:
  if (!(type == tfind_number && num == -1)
      && (has_stack_frames () || traceframe_number >= 0))
    old_frame_id = get_frame_id (get_current_frame ());

target ctf cannot support "old_frame_id = get_frame_id
(get_current_frame ());".  But traceframe_number >= 0 will let GDB
call the line that target ctf don't support.
And I don't think traceframe_number >= 0 is very import for "target
remote" or "target tfile" that support tfind because both of them
"has_stack_frames ()".
So I remove "traceframe_number >= 0".

>
> Tom

Thanks for your help.

According to your comments.  I post a new patch.

Merry Christmas!

Best,
Hui

2012-12-20  Hui Zhu  <hui_zhu@mentor.com>

	* aclocal.m4: Add PKG_PROG_PKG_CONFIG.
	* c-exp.y (lookup_enum): Rename to lookup_enum_gdb.
	* config.in (HAVE_LIBBABELTRACE): new macro.
	* configure: New option "--enable-ctf-target".
	* configure.ac: New option "--enable-ctf-target".
	* ctf.c (babeltrace/babeltrace.h, babeltrace/types.h,
	babeltrace/ctf/events.h, babeltrace/ctf/iterator.h): New includes.
	(ctx, iter, current_tp, ctf_event, ctf_ops): New variables.
	(bt_ctf_close, bt_ctf_open, bt_ctf_find_field, bt_ctf_event_id,
	bt_ctf_def_to_val, bt_ctf_event_to_internalvar, bt_ctf_goto_begin,
	bt_ctf_find_num, bt_ctf_find_tp, ctf_open, ctf_close,
	ctf_trace_find, ctf_get_current_tracepoint_name, ctf_trace_dump,
	ctf_has_all_memory, ctf_has_memory, ctf_has_stack,
	ctf_has_registers, ctf_thread_alive, init_ctf_ops,
	_initialize_ctf): New functions.
	* gdbtypes.c (lookup_enum): Rename to lookup_enum_gdb.
	* python/py-type.c (typy_lookup_typename): Rename lookup_enum
	to lookup_enum_gdb.
	* symtab.h (lookup_enum): Rename to lookup_enum_gdb.
	* target.c (update_current_target): Add
	to_get_current_tracepoint_name and to_trace_dump.
	(update_current_target): Ditto.
	* target.h (target_ops): Add to_get_current_tracepoint_name and
	to_trace_dump.
	(target_get_current_tracepoint_name, target_trace_dump): New
	macro.
	* tracepoint.c (tfind_1): Add checks for has_stack_frames ().
	Call target_get_current_tracepoint_name to show the name of
	tracepoint.
	(trace_dump_command): Call target_trace_dump.

[-- Attachment #2: ctf-target.txt --]
[-- Type: text/plain, Size: 27913 bytes --]

--- a/aclocal.m4
+++ b/aclocal.m4
@@ -106,6 +106,31 @@ AC_DEFUN([_AM_SUBST_NOTMAKE])
 # Public sister of _AM_SUBST_NOTMAKE.
 AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
 m4_include([../config/largefile.m4])
 m4_include([../config/lead-dot.m4])
 m4_include([../config/plugins.m4])
--- a/config.in
+++ b/config.in
@@ -216,6 +216,10 @@
 /* Define to 1 if you have the `w' library (-lw). */
 #undef HAVE_LIBW
 
+/* Define to 1 if you have the `babeltrace' library
+   (-lbabeltrace -lbabeltrace-ctf).  */
+#undef HAVE_LIBBABELTRACE
+
 /* Define to 1 if you have the <link.h> header file. */
 #undef HAVE_LINK_H
 
--- a/configure
+++ b/configure
@@ -592,6 +592,9 @@ enable_option_checking=no
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 GDB_NM_FILE
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
 frags
 target_subdir
 CONFIG_UNINSTALL
@@ -819,6 +822,7 @@ with_x
 enable_sim
 enable_multi_ice
 enable_gdbserver
+enable_ctf_target
 '
       ac_precious_vars='build_alias
 host_alias
@@ -833,7 +837,10 @@ MAKEINFO
 MAKEINFOFLAGS
 YACC
 YFLAGS
-XMKMF'
+XMKMF
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR'
 ac_subdirs_all='testsuite
 gdbtk
 multi-ice
@@ -1482,6 +1489,7 @@ Optional Features:
   --enable-multi-ice      build the multi-ice-gdb-server
   --enable-gdbserver      automatically build gdbserver (yes/no/auto, default
                           is auto)
+  --enable-ctf-target     enable ctf target (yes/no/auto, default is auto)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1551,6 +1559,11 @@ Some influential environment variables:
               This script will default YFLAGS to the empty string to avoid a
               default value of `-d' given by some make applications.
   XMKMF       Path to xmkmf, Makefile generator for X Window System
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -13985,6 +13998,222 @@ if test "$enable_gdbserver" = "yes" -a "
   as_fn_error "Automatic gdbserver build is not supported for this configuration" "$LINENO" 5
 fi
 
+# Check whether --enable-ctf-target was given.
+if test "${enable_ctf_target+set}" = set; then :
+  enableval=$enable_ctf_target; case "${enableval}" in
+  yes| no|auto) ;;
+  *) as_fn_error "bad value ${enableval} for --enable-ctf-target option" "$LINENO" 5 ;;
+esac
+else
+  enable_ctf_target=auto
+fi
+
+
+if test "$enable_ctf_target" = "yes" || test "$enable_ctf_target" = "auto"; then
+  pkg_config_args=babeltrace
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.16
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
+
+  if test "x$PKG_CONFIG" = x ; then
+    no_babeltrace=yes
+    PKG_CONFIG=no
+  fi
+
+  if test x"$no_babeltrace" = x ; then
+    BABELTRACE_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_args`
+    BABELTRACE_LIBS=`$PKG_CONFIG --libs $pkg_config_args`
+    ac_save_CFLAGS="$CFLAGS"
+    ac_save_LIBS="$LIBS"
+    CFLAGS="$CFLAGS $BABELTRACE_CFLAGS"
+    LIBS="$LIBS $BABELTRACE_LIBS"
+      rm -f conf.glibtest
+      if test "$cross_compiling" = yes; then :
+  $as_echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <babeltrace/babeltrace.h>
+#include <babeltrace/ctf/events.h>
+#include <babeltrace/ctf/iterator.h>
+
+int
+main ()
+{
+  if (!bt_context_create())
+    return 1;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  no_babeltrace=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+     CFLAGS="$ac_save_CFLAGS"
+     LIBS="$ac_save_LIBS"
+  fi
+  if test "x$no_babeltrace" = x ; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LIBBABELTRACE 1" >>confdefs.h
+
+     LIBS="$LIBS $BABELTRACE_LIBS"
+     CPPFLAGS="$CPPFLAGS $BABELTRACE_LIBS"
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    if test "$PKG_CONFIG" = "no" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** A new enough version of pkg-config was not found." >&5
+$as_echo "$as_me: WARNING: *** A new enough version of pkg-config was not found." >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** See http://www.freedesktop.org/software/pkgconfig/" >&5
+$as_echo "$as_me: WARNING: *** See http://www.freedesktop.org/software/pkgconfig/" >&2;}
+    else
+      if test -f conf.glibtest ; then
+        :
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Could not run libbabeltrace test program." >&5
+$as_echo "$as_me: WARNING: *** Could not run libbabeltrace test program." >&2;}
+      fi
+    fi
+    if test "$enable_ctf_target" = "yes"; then
+      as_fn_error "libbabeltrace are required in order to enable CTF target" "$LINENO" 5
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libbabeltrace is missing or unusable; CTF target is unavailable." >&5
+$as_echo "$as_me: WARNING: libbabeltrace is missing or unusable; CTF target is unavailable." >&2;}
+      enable_ctf_target = no
+    fi
+  fi
+  rm -f conf.glibtest
+fi
+if test "$enable_ctf_target" = "no"; then
+  :
+fi
+
 # If nativefile (NAT_FILE) is not set in config/*/*.m[ht] files, we link
 # to an empty version.
 
--- a/configure.ac
+++ b/configure.ac
@@ -2327,6 +2327,77 @@ if test "$enable_gdbserver" = "yes" -a "
   AC_MSG_ERROR(Automatic gdbserver build is not supported for this configuration)
 fi
 
+AC_ARG_ENABLE(ctf-target,
+AS_HELP_STRING([--enable-ctf-target],
+               [enable ctf target (yes/no/auto, default is auto)]),
+[case "${enableval}" in
+  yes| no|auto) ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-ctf-target option) ;;
+esac],[enable_ctf_target=auto])
+
+if test "$enable_ctf_target" = "yes" || test "$enable_ctf_target" = "auto"; then
+  pkg_config_args=babeltrace
+  PKG_PROG_PKG_CONFIG(0.16)
+
+  if test "x$PKG_CONFIG" = x ; then
+    no_babeltrace=yes
+    PKG_CONFIG=no
+  fi
+
+  if test x"$no_babeltrace" = x ; then
+    BABELTRACE_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_args`
+    BABELTRACE_LIBS=`$PKG_CONFIG --libs $pkg_config_args`
+    ac_save_CFLAGS="$CFLAGS"
+    ac_save_LIBS="$LIBS"
+    CFLAGS="$CFLAGS $BABELTRACE_CFLAGS"
+    LIBS="$LIBS $BABELTRACE_LIBS"
+      rm -f conf.glibtest
+      AC_TRY_RUN([
+#include <babeltrace/babeltrace.h>
+#include <babeltrace/ctf/events.h>
+#include <babeltrace/ctf/iterator.h>
+
+int
+main ()
+{
+  if (!bt_context_create())
+    return 1;
+  return 0;
+}
+],, no_babeltrace=yes,[$as_echo $ac_n "cross compiling; assumed OK... $ac_c"])
+     CFLAGS="$ac_save_CFLAGS"
+     LIBS="$ac_save_LIBS"
+  fi
+  if test "x$no_babeltrace" = x ; then
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_LIBBABELTRACE, 1, [Define if you have the $1 library.])
+     LIBS="$LIBS $BABELTRACE_LIBS"
+     CPPFLAGS="$CPPFLAGS $BABELTRACE_LIBS"
+  else
+    AC_MSG_RESULT(no)
+    if test "$PKG_CONFIG" = "no" ; then
+      AC_MSG_WARN([*** A new enough version of pkg-config was not found.])
+      AC_MSG_WARN([*** See http://www.freedesktop.org/software/pkgconfig/])
+    else
+      if test -f conf.glibtest ; then
+        :
+      else
+        AC_MSG_WARN([*** Could not run libbabeltrace test program.])
+      fi
+    fi
+    if test "$enable_ctf_target" = "yes"; then
+      AC_MSG_ERROR([libbabeltrace are required in order to enable CTF target])
+    else
+      AC_MSG_WARN([libbabeltrace is missing or unusable; CTF target is unavailable.])
+      enable_ctf_target = no
+    fi
+  fi
+  rm -f conf.glibtest
+fi
+if test "$enable_ctf_target" = "no"; then
+  :
+fi
+
 # If nativefile (NAT_FILE) is not set in config/*/*.m[ht] files, we link
 # to an empty version.
 
--- a/ctf.c
+++ b/ctf.c
@@ -1235,3 +1235,479 @@ traceframe %d is dropped because type of
 
   do_cleanups (old_chain);
 }
+
+#ifdef HAVE_LIBBABELTRACE
+#include <babeltrace/babeltrace.h>
+#include <babeltrace/ctf/events.h>
+#include <babeltrace/ctf/iterator.h>
+
+/* The struct pointer for current CTF directory.  */
+static struct bt_context *ctx = NULL;
+static struct bt_ctf_iter *iter = NULL;
+/* The event struct of current traceframe.  */
+static struct bt_ctf_event *ctf_event;
+/* The number of current traceframe.  */
+static int current_tp;
+
+static struct target_ops ctf_ops;
+
+static void
+bt_ctf_close (void)
+{
+  if (iter)
+    {
+      bt_ctf_iter_destroy (iter);
+      iter = NULL;
+    }
+  if (ctx)
+    {
+      bt_context_put (ctx);
+      ctx = NULL;
+    }
+}
+
+/* Use libbabeltrace open DIRNAME.  Setup CTX, ITER, CTF_EVENT
+   and CURRENT_TP.  */
+
+static void
+bt_ctf_open (char *dirname)
+{
+  int ret;
+  struct bt_iter_pos begin_pos;
+
+  ctx = bt_context_create ();
+  if (!ctx)
+    error (_("Initialize libbabeltrace fail"));
+  ret = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
+  if (ret < 0)
+    {
+      bt_ctf_close ();
+      error (_("Use libbabeltrace open \"%s\" fail"), dirname);
+    }
+
+  begin_pos.type = BT_SEEK_BEGIN;
+  iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
+  if (!iter)
+    {
+      bt_ctf_close ();
+      error (_("Use libbabeltrace open \"%s\" fail"), dirname);
+    }
+
+  current_tp = 0;
+  ctf_event = bt_ctf_iter_read_event (iter);
+  if (!ctf_event)
+    {
+      bt_ctf_close ();
+      error (_("Use libbabeltrace open \"%s\" fail"), dirname);
+    }
+}
+
+/* Find the field that name is NAME from D and return it.
+   Return NULL if fail.  */
+
+static const struct definition *
+bt_ctf_find_field (const struct definition *d, const char *name)
+{
+  struct definition const * const *list_d;
+  unsigned int list_d_count, i;
+
+  if (bt_ctf_get_field_list (ctf_event, d, &list_d, &list_d_count))
+    return NULL;
+  for (i = 0; i < list_d_count; i++)
+    {
+      if (strcmp (bt_ctf_field_name (list_d[i]), name) == 0)
+	return list_d[i];
+    }
+
+  return NULL;
+}
+
+/* Get the id of current traceframe and set it to TPP.
+   Return -1 if fail.  */
+
+static int
+bt_ctf_event_id (int *tpp)
+{
+  const struct definition *top_d;
+  struct definition const * const *list_d;
+  unsigned int list_d_count, i;
+  const struct definition *d_id = NULL;
+  const struct definition *d_v = NULL;
+
+  top_d = bt_ctf_get_top_level_scope (ctf_event, BT_STREAM_EVENT_HEADER);
+  if (!top_d)
+    return -1;
+  if (bt_ctf_get_field_list (ctf_event, top_d, &list_d, &list_d_count))
+    return -1;
+
+  for (i = 0; i < list_d_count; i++)
+    {
+      if (strcmp (bt_ctf_field_name (list_d[i]), "id") == 0)
+	d_id = list_d[i];
+      else if (strcmp (bt_ctf_field_name (list_d[i]), "v") == 0)
+	d_v = list_d[i];
+      if (d_id && d_v)
+	break;
+    }
+  if (!d_id)
+    return -1;
+
+getval:
+  switch (bt_ctf_field_type (bt_ctf_get_decl_from_def (d_id)))
+    {
+    case CTF_TYPE_INTEGER:
+      {
+	int64_t val;
+
+	if (bt_ctf_get_int_signedness (bt_ctf_get_decl_from_def (d_id)))
+	  val = bt_ctf_get_int64 (d_id);
+	else
+	  val = bt_ctf_get_uint64 (d_id);
+	if (val < INT_MIN || val > INT_MAX)
+	  {
+	    warning (_("tracepoint id is too big or too small."));
+	    return -1;
+	  }
+	*tpp = (int) val;
+      }
+      break;
+
+    case CTF_TYPE_ENUM:
+      if (strcmp (bt_ctf_get_enum_str (d_id), "compact") == 0)
+	d_id = bt_ctf_get_enum_int (d_id);
+      else
+	{
+	  if (!d_v)
+	    return -1;
+	  if (bt_ctf_field_type (bt_ctf_get_decl_from_def (d_v))
+	      != CTF_TYPE_VARIANT)
+	    return -1;
+
+	  d_v = bt_ctf_find_field (d_v, "extended");
+	  if (!d_v)
+	    return -1;
+	  if (bt_ctf_field_type (bt_ctf_get_decl_from_def (d_v))
+	      != CTF_TYPE_STRUCT)
+	    return -1;
+	  d_id = bt_ctf_find_field (d_v, "id");
+	  if (!d_id)
+	    return -1;
+	}
+	goto getval;
+      break;
+
+    default:
+      warning (_("type of tracepoint id is not support."));
+      return -1;
+      break;
+    }
+
+  return 0;
+}
+
+/* Convert DEF to a value struct and return it.  */
+
+static struct value *
+bt_ctf_def_to_val (const struct definition *def)
+{
+  struct value *ret = NULL;
+
+  if (!def)
+    return ret;
+
+  switch (bt_ctf_field_type (bt_ctf_get_decl_from_def (def)))
+    {
+    case CTF_TYPE_INTEGER:
+      if (bt_ctf_get_int_signedness (bt_ctf_get_decl_from_def (def)))
+	{
+	  int64_t val;
+	  val = bt_ctf_get_int64 (def);
+	  ret = value_from_longest
+		    (builtin_type (target_gdbarch ())->builtin_int64, val);
+	}
+      else
+	{
+	  uint64_t val;
+	  val = bt_ctf_get_uint64 (def);
+	  ret = value_from_longest
+		    (builtin_type (target_gdbarch ())->builtin_uint64, val);
+	}
+      break;
+
+    case CTF_TYPE_ENUM:
+      ret = bt_ctf_def_to_val (bt_ctf_get_enum_int (def));
+      break;
+    }
+
+  return ret;
+}
+
+/* Add each variable of crrent traceframe to GDB as internalvar.  */
+
+static int
+bt_ctf_event_to_internalvar (void)
+{
+  const struct definition *top_d;
+  struct definition const * const *list_d;
+  unsigned int list_d_count, i;
+
+  top_d = bt_ctf_get_top_level_scope (ctf_event, BT_EVENT_FIELDS);
+  if (!top_d)
+    return -1;
+  if (bt_ctf_get_field_list (ctf_event, top_d, &list_d, &list_d_count))
+    return -1;
+
+  for (i = 0; i < list_d_count; i++)
+    {
+      struct value *val;
+      const char *name;
+
+      val = bt_ctf_def_to_val (list_d[i]);
+      name = bt_ctf_field_name (list_d[i]);
+      if (val)
+        set_internalvar (lookup_internalvar (name), val);
+      else
+	warning (_("$%s is not support."), name);
+    }
+
+  return 0;
+}
+
+/* Set current traceframe to first one.
+   Return -1 if fail.  */
+
+static int
+bt_ctf_goto_begin (void)
+{
+  struct bt_iter_pos pos;
+
+  pos.type = BT_SEEK_BEGIN;
+  if (bt_iter_set_pos (bt_ctf_get_iter (iter), &pos))
+    return -1;
+  current_tp = 0;
+  ctf_event = bt_ctf_iter_read_event (iter);
+  if (!ctf_event)
+    return -1;
+
+  return 0;
+}
+
+/* Find the NUM traceframe and select it.
+   If success, return the num of traceframe and set tracepoint id to
+   TPP.
+   If fail, return -1.  */
+
+static int
+bt_ctf_find_num (int num, int *tpp)
+{
+  if (num < current_tp)
+    {
+      if (bt_ctf_goto_begin ())
+	return -1;
+    }
+
+  while (1)
+    {
+      if (current_tp == num)
+        break;
+      if (bt_iter_next (bt_ctf_get_iter (iter)) < 0)
+	return -1;
+      ctf_event = bt_ctf_iter_read_event (iter);
+      if (!ctf_event)
+        {
+	  bt_ctf_goto_begin ();
+	  return -1;
+	}
+      ++current_tp;
+    }
+
+  if (tpp)
+    {
+      if (bt_ctf_event_id (tpp))
+        {
+	  warning (_("get tracepoint id fail."));
+          *tpp = INT_MIN;
+	}
+    }
+
+  return current_tp;
+}
+
+/* Find traceframe that id is TP that follow current traceframe.
+   If success, return the num of traceframe.
+   If fail, return -1.  */
+
+static int
+bt_ctf_find_tp (int tp)
+{
+  while (1)
+    {
+      int id;
+
+      if (bt_iter_next (bt_ctf_get_iter (iter)) < 0)
+	return -1;
+      ctf_event = bt_ctf_iter_read_event (iter);
+      if (!ctf_event)
+        {
+	  bt_ctf_goto_begin ();
+	  return -1;
+	}
+      ++current_tp;
+      if (bt_ctf_event_id (&id))
+        warning (_("get tracepoint id fail."));
+      else if (id == tp)
+	break;
+    }
+
+  return current_tp;
+}
+
+static void
+ctf_open (char *dirname, int from_tty)
+{
+  target_preopen (from_tty);
+  if (!dirname)
+    error (_("No CTF directory specified."));
+
+  bt_ctf_open (dirname);
+
+  push_target (&ctf_ops);
+}
+
+static void
+ctf_close (int quitting)
+{
+  bt_ctf_close ();
+}
+
+static int
+ctf_trace_find (enum trace_find_type type, int num,
+		ULONGEST addr1, ULONGEST addr2, int *tpp)
+{
+  int ret = -1;
+
+  switch (type)
+    {
+    case tfind_number:
+      if (num < 0)
+        {
+	  if (tpp)
+	    *tpp = -1;
+	}
+      else
+        ret = bt_ctf_find_num (num, tpp);
+      break;
+
+    case tfind_tp:
+      ret = bt_ctf_find_tp (num);
+      break;
+    }
+
+  if (ret >= 0)
+    {
+      if (bt_ctf_event_to_internalvar ())
+	warning (_("add internal var of this frame fail."));
+    }
+
+  return ret;
+}
+
+static const char *
+ctf_get_current_tracepoint_name (void)
+{
+  if (ctf_event)
+    return bt_ctf_event_name (ctf_event);
+
+  return NULL;
+}
+
+static int
+ctf_trace_dump (int from_tty)
+{
+  const struct definition *top_d;
+  struct definition const * const *list_d;
+  unsigned int list_d_count, i;
+
+  if (!ctf_event)
+    return 1;
+
+  top_d = bt_ctf_get_top_level_scope (ctf_event, BT_EVENT_FIELDS);
+  if (!top_d)
+    return 1;
+  if (bt_ctf_get_field_list (ctf_event, top_d, &list_d, &list_d_count))
+    return 1;
+
+  for (i = 0; i < list_d_count; i++)
+    {
+      char name[256];
+      snprintf (name, 256, "$%s", bt_ctf_field_name (list_d[i]));
+      printf_filtered ("%s = ", name);
+      output_command (name, from_tty);
+      printf_filtered ("\n");
+    }
+
+  return 1;
+}
+
+static int
+ctf_has_all_memory (struct target_ops *ops)
+{
+  return 0;
+}
+
+static int
+ctf_has_memory (struct target_ops *ops)
+{
+  return 0;
+}
+
+static int
+ctf_has_stack (struct target_ops *ops)
+{
+  return 0;
+}
+
+static int
+ctf_has_registers (struct target_ops *ops)
+{
+  return 0;
+}
+
+static int
+ctf_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+  return 1;
+}
+
+static void
+init_ctf_ops (void)
+{
+  ctf_ops.to_shortname = "ctf";
+  ctf_ops.to_longname = "CTF file";
+  ctf_ops.to_doc = "Use a CTF directory as a target.\n\
+Specify the filename of the CTF directory.";
+  ctf_ops.to_open = ctf_open;
+  ctf_ops.to_close = ctf_close;
+  ctf_ops.to_trace_find = ctf_trace_find;
+  ctf_ops.to_get_current_tracepoint_name = ctf_get_current_tracepoint_name;
+  ctf_ops.to_trace_dump = ctf_trace_dump;
+  ctf_ops.to_stratum = process_stratum;
+  ctf_ops.to_has_all_memory = ctf_has_all_memory;
+  ctf_ops.to_has_memory = ctf_has_memory;
+  ctf_ops.to_has_stack = ctf_has_stack;
+  ctf_ops.to_has_registers = ctf_has_registers;
+  ctf_ops.to_thread_alive = ctf_thread_alive;
+  ctf_ops.to_magic = OPS_MAGIC;
+}
+
+extern void _initialize_ctf (void);
+
+/* module initialization */
+void
+_initialize_ctf (void)
+{
+  init_ctf_ops ();
+
+  add_target (&ctf_ops);
+}
+#endif
--- a/target.c
+++ b/target.c
@@ -694,6 +694,8 @@ update_current_target (void)
       INHERIT (to_set_disconnected_tracing, t);
       INHERIT (to_set_circular_trace_buffer, t);
       INHERIT (to_set_trace_notes, t);
+      INHERIT (to_get_current_tracepoint_name, t);
+      INHERIT (to_trace_dump, t);
       INHERIT (to_get_tib_address, t);
       INHERIT (to_set_permissions, t);
       INHERIT (to_static_tracepoint_marker_at, t);
@@ -915,6 +917,12 @@ update_current_target (void)
   de_fault (to_set_trace_notes,
 	    (int (*) (char *, char *, char *))
 	    return_zero);
+  de_fault (to_get_current_tracepoint_name,
+	    (const char *(*) (void))
+	    return_zero);
+  de_fault (to_trace_dump,
+	    (int (*) (int))
+	    return_zero);
   de_fault (to_get_tib_address,
 	    (int (*) (ptid_t, CORE_ADDR *))
 	    tcomplain);
--- a/target.h
+++ b/target.h
@@ -811,6 +811,17 @@ struct target_ops
        successful, 0 otherwise.  */
     int (*to_set_trace_notes) (char *user, char *notes, char* stopnotes);
 
+    /* Return name of current traceframe's tracepoint.
+       Return NULL if the target doesn't support it.  */
+
+    const char *(*to_get_current_tracepoint_name) (void);
+
+    /* Dump all the value of current traceframe.
+       Return fail if the target doesn't support it.  Then GDB will
+       dump all the value of current traceframe with itself.  */
+
+    int (*to_trace_dump) (int from_tty);
+
     /* Return the processor core that thread PTID was last seen on.
        This information is updated only when:
        - update_thread_list is called
@@ -1703,6 +1714,12 @@ extern char *target_fileio_read_stralloc
 #define	target_set_trace_notes(user,notes,stopnotes)		\
   (*current_target.to_set_trace_notes) ((user), (notes), (stopnotes))
 
+#define target_get_current_tracepoint_name() \
+  (*current_target.to_get_current_tracepoint_name) ()
+
+#define target_trace_dump(from_tty) \
+  (*current_target.to_trace_dump) (from_tty)
+
 #define target_get_tib_address(ptid, addr) \
   (*current_target.to_get_tib_address) ((ptid), (addr))
 
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -2243,7 +2243,7 @@ tfind_1 (enum trace_find_type type, int
      below (correctly) decide to print out the source location of the
      trace frame.  */
   if (!(type == tfind_number && num == -1)
-      && (has_stack_frames () || traceframe_number >= 0))
+      && has_stack_frames ())
     old_frame_id = get_frame_id (get_current_frame ());
 
   target_frameno = target_trace_find (type, num, addr1, addr2,
@@ -2294,7 +2294,8 @@ tfind_1 (enum trace_find_type type, int
   
   tp = get_tracepoint_by_number_on_target (target_tracept);
 
-  reinit_frame_cache ();
+  if (has_stack_frames ())
+    reinit_frame_cache ();
   target_dcache_invalidate ();
 
   set_tracepoint_num (tp ? tp->base.number : target_tracept);
@@ -2304,10 +2305,13 @@ tfind_1 (enum trace_find_type type, int
 
   set_current_traceframe (target_frameno);
 
-  if (target_frameno == -1)
-    set_traceframe_context (NULL);
-  else
-    set_traceframe_context (get_current_frame ());
+  if (has_stack_frames ())
+    {
+      if (target_frameno == -1)
+	set_traceframe_context (NULL);
+      else
+        set_traceframe_context (get_current_frame ());
+    }
 
   if (traceframe_number >= 0)
     {
@@ -2341,21 +2345,30 @@ tfind_1 (enum trace_find_type type, int
   if (from_tty
       && (has_stack_frames () || traceframe_number >= 0))
     {
-      enum print_what print_what;
+      const char *tp_name;
 
-      /* NOTE: in imitation of the step command, try to determine
-         whether we have made a transition from one function to
-         another.  If so, we'll print the "stack frame" (ie. the new
-         function and it's arguments) -- otherwise we'll just show the
-         new source line.  */
+      tp_name = target_get_current_tracepoint_name ();
+      if (tp_name)
+        printf_filtered ("%s\n", tp_name);
 
-      if (frame_id_eq (old_frame_id,
-		       get_frame_id (get_current_frame ())))
-	print_what = SRC_LINE;
-      else
-	print_what = SRC_AND_LOC;
+      if (has_stack_frames ())
+        {
+	  enum print_what print_what;
 
-      print_stack_frame (get_selected_frame (NULL), 1, print_what);
+	  /* NOTE: in imitation of the step command, try to determine
+           whether we have made a transition from one function to
+           another.  If so, we'll print the "stack frame" (ie. the new
+           function and it's arguments) -- otherwise we'll just show the
+           new source line.  */
+
+	  if (frame_id_eq (old_frame_id,
+			   get_frame_id (get_current_frame ())))
+	    print_what = SRC_LINE;
+	  else
+	    print_what = SRC_AND_LOC;
+
+	  print_stack_frame (get_selected_frame (NULL), 1, print_what);
+	}
       do_displays ();
     }
 }
@@ -2885,6 +2898,9 @@ trace_dump_command (char *args, int from
       return;
     }
 
+  if (target_trace_dump (from_tty))
+    return;
+
   t = get_tracepoint (tracepoint_number);
 
   if (t == NULL)

  reply	other threads:[~2012-12-21  8:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-21  1:45 Hui Zhu
2012-11-21  2:36 ` Yao Qi
2012-11-21  3:32   ` Hui Zhu
2012-11-27 10:55     ` Hui Zhu
2012-11-29 20:42       ` Tom Tromey
2012-12-21  8:23         ` Hui Zhu [this message]
2013-01-16 15:12           ` Abid, Hafiz
2013-01-23  5:54             ` Hui Zhu
2013-02-11 12:55               ` Hui Zhu
2012-11-21  4:29 ` Yao Qi
2012-11-29 20:24 ` Tom Tromey
2012-12-05  6:59   ` Hui Zhu
2012-11-29 20:47 ` Tom Tromey
2012-12-06 13:37   ` Hui Zhu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANFwon0k48X5dAo_K=dR2novtD+qo+U3HftgvqsSZ1ZJno1MHQ@mail.gmail.com' \
    --to=teawater@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=hui_zhu@mentor.com \
    --cc=tromey@redhat.com \
    --cc=yao@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox