[PATCH] Add CTF support to GDB [3/4] ctf target
Hui Zhu
teawater@gmail.com
Wed Jan 23 05:54:00 GMT 2013
On Wed, Jan 16, 2013 at 11:12 PM, Abid, Hafiz <Hafiz_Abid@mentor.com> wrote:
> Hi Hui,
> Some minor issues that I noted.
>
> Many functions in your patch starts with bt_ctf_ like the function from libbabeltrace. So it is difficult to see which function comes from the library and which function is actually in GDB. I am not sure about the convention but it looks to me that it would make the code more readable if you renamed your functions. Bring them into GDB namespace.
I agree with you. And it increase the Increased the possibility of
same name issue with babeltrace in the future.
So I change it to "ctf_".
>
>>+ error (_("Initialize libbabeltrace fail"));
>>+ error (_("Use libbabeltrace open \"%s\" fail"), dirname);
>>+ warning (_("get tracepoint id fail."));
> As Tom already pointed out, these messages can be improved. How about something like "Unable to get the tracepoint id"
Fixed.
>
>>+/* Add each variable of crrent traceframe to GDB as internalvar. */
> current
Fixed.
>
>>+ warning (_("$%s is not support."), name);
> supported
Fixed.
>
>>+ if (bt_ctf_event_to_internalvar ())
>>+ warning (_("add internal var of this frame fail."));
> This warning message does not tell much. Perhaps it can be moved inside bt_ctf_event_to_internalvar where we have more context to provide more information. Also it needs to be re-phrased.
Sorry. I didn't have good words for these 2 fail. So I just change
warning to Unable to xxx...
>
> May be it is just me but indentation looks off at many places.
>
> Regards,
> Abid
Thanks,
Hui
2013-01-23 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.
(ctf_close_dir, ctf_open_dir, ctf_find_field, ctf_event_id,
ctf_def_to_val, ctf_event_to_internalvar, ctf_goto_begin,
ctf_find_num, 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.
>
> ________________________________________
> From: gdb-patches-owner@sourceware.org [gdb-patches-owner@sourceware.org] on behalf of Hui Zhu [teawater@gmail.com]
> Sent: Friday, December 21, 2012 8:22 AM
> To: Tom Tromey
> Cc: Qi, Yao; Zhu, Hui; gdb-patches ml
> Subject: Re: [PATCH] Add CTF support to GDB [3/4] ctf target
>
> 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.
-------------- next part --------------
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -85,6 +85,32 @@ AC_MSG_CHECKING([whether to am_maintaine
]
)
+# 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
+
+
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
--- 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.
@@ -14090,6 +14103,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
@@ -2318,6 +2318,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
@@ -24,6 +24,7 @@
#include "gdbcmd.h"
#include "exceptions.h"
#include "stack.h"
+#include "valprint.h"
#include <ctype.h>
@@ -1338,3 +1339,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
+ctf_close_dir (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
+ctf_open_dir (char *dirname)
+{
+ int ret;
+ struct bt_iter_pos begin_pos;
+
+ ctx = bt_context_create ();
+ if (!ctx)
+ error (_("Unable to initialize libbabeltrace"));
+ ret = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
+ if (ret < 0)
+ {
+ ctf_close_dir ();
+ error (_("Unable to use libbabeltrace open \"%s\""), dirname);
+ }
+
+ begin_pos.type = BT_SEEK_BEGIN;
+ iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
+ if (!iter)
+ {
+ ctf_close_dir ();
+ error (_("Unable to use libbabeltrace open \"%s\""), dirname);
+ }
+
+ current_tp = 0;
+ ctf_event = bt_ctf_iter_read_event (iter);
+ if (!ctf_event)
+ {
+ ctf_close_dir ();
+ error (_("Unable to use libbabeltrace open \"%s\""), dirname);
+ }
+}
+
+/* Find the field that name is NAME from D and return it.
+ Return NULL if fail. */
+
+static const struct definition *
+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
+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 = 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 = ctf_find_field (d_v, "id");
+ if (!d_id)
+ return -1;
+ }
+ goto getval;
+ break;
+
+ default:
+ warning (_("type of tracepoint id is not supported."));
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+/* Convert DEF to a value struct and return it. */
+
+static struct value *
+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 = ctf_def_to_val (bt_ctf_get_enum_int (def));
+ break;
+ }
+
+ return ret;
+}
+
+/* Add each variable of current traceframe to GDB as internalvar. */
+
+static int
+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 = 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 supported."), name);
+ }
+
+ return 0;
+}
+
+/* Set current traceframe to first one.
+ Return -1 if fail. */
+
+static int
+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
+ctf_find_num (int num, int *tpp)
+{
+ if (num < current_tp)
+ {
+ if (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)
+ {
+ ctf_goto_begin ();
+ return -1;
+ }
+ ++current_tp;
+ }
+
+ if (tpp)
+ {
+ if (ctf_event_id (tpp))
+ {
+ warning (_("Unable to get tracepoint id."));
+ *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
+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)
+ {
+ ctf_goto_begin ();
+ return -1;
+ }
+ ++current_tp;
+ if (ctf_event_id (&id))
+ warning (_("Unable to get tracepoint id."));
+ 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."));
+
+ ctf_open_dir (dirname);
+
+ push_target (&ctf_ops);
+}
+
+static void
+ctf_close (int quitting)
+{
+ ctf_close_dir ();
+}
+
+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 = ctf_find_num (num, tpp);
+ break;
+
+ case tfind_tp:
+ ret = ctf_find_tp (num);
+ break;
+ }
+
+ if (ret >= 0)
+ {
+ if (ctf_event_to_internalvar ())
+ warning (_("Unable to add internal var of this frame."));
+ }
+
+ 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
@@ -2257,7 +2257,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,
@@ -2308,7 +2308,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);
@@ -2318,10 +2319,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)
{
@@ -2355,21 +2359,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 ();
}
}
@@ -2899,6 +2912,9 @@ trace_dump_command (char *args, int from
return;
}
+ if (target_trace_dump (from_tty))
+ return;
+
t = get_tracepoint (tracepoint_number);
if (t == NULL)
More information about the Gdb-patches
mailing list