* [PATCH 10/16] btrace, config: enable btrace for 32bit and 64bit linux native
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
@ 2012-05-23 11:24 ` markus.t.metzger
2012-05-23 11:24 ` [PATCH 06/16] configure: add check for perf_event header markus.t.metzger
` (17 subsequent siblings)
18 siblings, 0 replies; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:24 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Install the btrace target ops for i386-linux-nat and amd64-linux-nat.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* amd64-linux-nat.c: Add include
(_initialize_amd64_linux_nat): Initialize btrace ops
* i386-linux.nat.c: Add include
(_initialize_i386_linux_nat): Initialize btrace ops
gdb/config/i386/
* linux.mh: Add linux-btrace.o
* linux64.mh: Add linux-btrace.o
---
gdb/amd64-linux-nat.c | 2 ++
gdb/config/i386/linux.mh | 3 ++-
gdb/config/i386/linux64.mh | 2 +-
gdb/i386-linux-nat.c | 2 ++
4 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 5ebba3a..caea66a 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -25,6 +25,7 @@
#include "regset.h"
#include "linux-nat.h"
#include "amd64-linux-tdep.h"
+#include "linux-nat-btrace.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -841,6 +842,7 @@ _initialize_amd64_linux_nat (void)
t = linux_target ();
i386_use_watchpoints (t);
+ linux_nat_add_btrace_ops (t);
i386_dr_low.set_control = amd64_linux_dr_set_control;
i386_dr_low.set_addr = amd64_linux_dr_set_addr;
diff --git a/gdb/config/i386/linux.mh b/gdb/config/i386/linux.mh
index 8316d87..cc45f83 100644
--- a/gdb/config/i386/linux.mh
+++ b/gdb/config/i386/linux.mh
@@ -4,7 +4,8 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o i386-linux-nat.o \
proc-service.o linux-thread-db.o \
- linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
+ linux-btrace.o linux-nat-btrace.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The dynamically loaded libthread_db needs access to symbols in the
diff --git a/gdb/config/i386/linux64.mh b/gdb/config/i386/linux64.mh
index d2b95fd..4fead06 100644
--- a/gdb/config/i386/linux64.mh
+++ b/gdb/config/i386/linux64.mh
@@ -3,7 +3,7 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o amd64-nat.o amd64-linux-nat.o \
linux-nat.o linux-osdata.o \
proc-service.o linux-thread-db.o linux-fork.o \
- linux-procfs.o linux-ptrace.o
+ linux-procfs.o linux-ptrace.o linux-btrace.o linux-nat-btrace.o
NAT_FILE= config/nm-linux.h
NAT_CDEPS = $(srcdir)/proc-service.list
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index ac1629a..00bddb6 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -25,6 +25,7 @@
#include "regset.h"
#include "target.h"
#include "linux-nat.h"
+#include "linux-nat-btrace.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -1020,6 +1021,7 @@ _initialize_i386_linux_nat (void)
t = linux_target ();
i386_use_watchpoints (t);
+ linux_nat_add_btrace_ops (t);
i386_dr_low.set_control = i386_linux_dr_set_control;
i386_dr_low.set_addr = i386_linux_dr_set_addr;
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 06/16] configure: add check for perf_event header
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
2012-05-23 11:24 ` [PATCH 10/16] btrace, config: enable btrace for 32bit and 64bit linux native markus.t.metzger
@ 2012-05-23 11:24 ` markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-23 11:24 ` [PATCH 02/16] source: add flags to print_source_lines () markus.t.metzger
` (16 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:24 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* configure.ac: check for linux/perf_event.h
gdb/gdbserver/
* configure.ac: check for linux/perf_event.h
---
gdb/configure.ac | 2 ++
gdb/gdbserver/configure.ac | 2 +-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/gdb/configure.ac b/gdb/configure.ac
index d7409d0..6bc19e2 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1057,6 +1057,8 @@ AC_CHECK_HEADERS(term.h, [], [],
#endif
])
+AC_CHECK_HEADERS(linux/perf_event.h)
+
# ------------------------- #
# Checks for declarations. #
# ------------------------- #
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 7013a21..f6748af 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -55,7 +55,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
stdlib.h unistd.h dnl
errno.h fcntl.h signal.h sys/file.h malloc.h dnl
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
- netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h)
+ netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h linux/perf_event.h)
AC_CHECK_FUNCS(pread pwrite pread64 readlink)
AC_REPLACE_FUNCS(vasprintf vsnprintf)
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 06/16] configure: add check for perf_event header
2012-05-23 11:24 ` [PATCH 06/16] configure: add check for perf_event header markus.t.metzger
@ 2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:43 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:21 +0200, markus.t.metzger@intel.com wrote:
> --- a/gdb/configure.ac
> +++ b/gdb/configure.ac
> @@ -1057,6 +1057,8 @@ AC_CHECK_HEADERS(term.h, [], [],
> #endif
> ])
>
> +AC_CHECK_HEADERS(linux/perf_event.h)
> +
There is already existing big AC_CHECK_HEADERS block at line 1014.
> # ------------------------- #
> # Checks for declarations. #
> # ------------------------- #
> diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
> index 7013a21..f6748af 100644
> --- a/gdb/gdbserver/configure.ac
> +++ b/gdb/gdbserver/configure.ac
> @@ -55,7 +55,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
> stdlib.h unistd.h dnl
> errno.h fcntl.h signal.h sys/file.h malloc.h dnl
> sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
> - netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h)
> + netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h linux/perf_event.h)
> AC_CHECK_FUNCS(pread pwrite pread64 readlink)
> AC_REPLACE_FUNCS(vasprintf vsnprintf)
>
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 06/16] configure: add check for perf_event header
2012-05-30 20:43 ` Jan Kratochvil
@ 2012-05-31 15:34 ` Metzger, Markus T
2012-06-22 20:40 ` Tom Tromey
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:34 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 420 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:43 PM
> To: Metzger, Markus T
Thanks for your review!
> > +AC_CHECK_HEADERS(linux/perf_event.h)
> > +
>
> There is already existing big AC_CHECK_HEADERS block at line 1014.
This new check is right at the end of that block. They got expanded by
conditional include statements.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 06/16] configure: add check for perf_event header
2012-05-31 15:34 ` Metzger, Markus T
@ 2012-06-22 20:40 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Tom Tromey @ 2012-06-22 20:40 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: Jan Kratochvil, kettenis, gdb-patches, markus.t.metzger
>>>>> "Markus" == Metzger, Markus T <markus.t.metzger@intel.com> writes:
Markus> Thanks for your review!
>> > +AC_CHECK_HEADERS(linux/perf_event.h)
Jan> There is already existing big AC_CHECK_HEADERS block at line 1014.
Markus> This new check is right at the end of that block. They got expanded by
Markus> conditional include statements.
It is better to just put the new file into the big AC_CHECK_HEADERS
invocation, if possible, since that results in a smaller configure file.
Right now you have added a separate AC_CHECK_HEADERS invocation, but it
doesn't need to be separate.
Tom
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 06/16] configure: add check for perf_event header
2012-06-22 20:40 ` Tom Tromey
@ 2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-25 8:50 UTC (permalink / raw)
To: Tom Tromey; +Cc: Jan Kratochvil, kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 747 bytes --]
> -----Original Message-----
> From: Tom Tromey [mailto:tromey@redhat.com]
> Sent: Friday, June 22, 2012 10:40 PM
> To: Metzger, Markus T
[...]
> >> > +AC_CHECK_HEADERS(linux/perf_event.h)
>
> Jan> There is already existing big AC_CHECK_HEADERS block at line 1014.
>
> Markus> This new check is right at the end of that block. They got expanded by
> Markus> conditional include statements.
>
> It is better to just put the new file into the big AC_CHECK_HEADERS
> invocation, if possible, since that results in a smaller configure file.
> Right now you have added a separate AC_CHECK_HEADERS invocation, but it
> doesn't need to be separate.
I found one big block ending with sys/un.h and added the new file to this list.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 02/16] source: add flags to print_source_lines ()
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
2012-05-23 11:24 ` [PATCH 10/16] btrace, config: enable btrace for 32bit and 64bit linux native markus.t.metzger
2012-05-23 11:24 ` [PATCH 06/16] configure: add check for perf_event header markus.t.metzger
@ 2012-05-23 11:24 ` markus.t.metzger
2012-05-30 20:41 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 15/16] gdbserver, btrace: add generic btrace support markus.t.metzger
` (15 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:24 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
The 4th parameter of print_source_lines is a boolean flag noerror. Generalize
this to be a bit vector of flags and make noerror one of the flag bits.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* symtab.h (print_source_lines_flags): New enum
* source.c (print_source_lines_base): Change noerror to flags
(print_source_lines): Change noerror to flags
---
gdb/source.c | 14 ++++++--------
gdb/symtab.h | 5 +++++
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/gdb/source.c b/gdb/source.c
index 27c5b0e..4dd7ed2 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1225,10 +1225,8 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
/* Print source lines from the file of symtab S,
starting with line number LINE and stopping before line number STOPLINE. */
-static void print_source_lines_base (struct symtab *s, int line, int stopline,
- int noerror);
static void
-print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines_base (struct symtab *s, int line, int stopline, int flags)
{
int c;
int desc;
@@ -1256,13 +1254,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
else
{
desc = last_source_error;
- noerror = 1;
+ flags |= PRINT_SOURCE_LINES_NOERROR;
}
}
else
{
desc = last_source_error;
- noerror = 1;
+ flags |= PRINT_SOURCE_LINES_NOERROR;
noprint = 1;
}
@@ -1270,7 +1268,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
{
last_source_error = desc;
- if (!noerror)
+ if (!(flags & PRINT_SOURCE_LINES_NOERROR))
{
char *name = alloca (strlen (s->filename) + 100);
sprintf (name, "%d\t%s", line, s->filename);
@@ -1356,9 +1354,9 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
window otherwise it is simply printed. */
void
-print_source_lines (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines (struct symtab *s, int line, int stopline, int flags)
{
- print_source_lines_base (s, line, stopline, noerror);
+ print_source_lines_base (s, line, stopline, flags);
}
\f
/* Print info on range of pc's in a specified line. */
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 526fe5a..a8c57cf 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1143,6 +1143,11 @@ extern void clear_solib (void);
extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
+/* Flags passed as 4th argument to print_source_lines. */
+enum print_source_lines_flags {
+ PRINT_SOURCE_LINES_NOERROR = (0x1 << 0)
+};
+
extern void print_source_lines (struct symtab *, int, int, int);
extern void forget_cached_source_info_for_objfile (struct objfile *);
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 02/16] source: add flags to print_source_lines ()
2012-05-23 11:24 ` [PATCH 02/16] source: add flags to print_source_lines () markus.t.metzger
@ 2012-05-30 20:41 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:41 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:17 +0200, markus.t.metzger@intel.com wrote:
> From: Markus Metzger <markus.t.metzger@intel.com>
>
> The 4th parameter of print_source_lines is a boolean flag noerror. Generalize
> this to be a bit vector of flags and make noerror one of the flag bits.
>
> 2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
>
> gdb/
> * symtab.h (print_source_lines_flags): New enum
> * source.c (print_source_lines_base): Change noerror to flags
> (print_source_lines): Change noerror to flags
The indentation should not be there, just:
gdb/
* symtab.h (print_source_lines_flags): New enum.
* source.c (print_source_lines_base): Change noerror to flags.
(print_source_lines): Change noerror to flags.
And every sentence should be terminated by a dot.
>
>
> ---
> gdb/source.c | 14 ++++++--------
> gdb/symtab.h | 5 +++++
> 2 files changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/gdb/source.c b/gdb/source.c
> index 27c5b0e..4dd7ed2 100644
> --- a/gdb/source.c
> +++ b/gdb/source.c
> @@ -1225,10 +1225,8 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
> /* Print source lines from the file of symtab S,
> starting with line number LINE and stopping before line number STOPLINE. */
>
> -static void print_source_lines_base (struct symtab *s, int line, int stopline,
> - int noerror);
> static void
> -print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
> +print_source_lines_base (struct symtab *s, int line, int stopline, int flags)
Make it then 'enum print_source_lines_flags flags'.
> {
> int c;
> int desc;
> @@ -1256,13 +1254,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
> else
> {
> desc = last_source_error;
> - noerror = 1;
> + flags |= PRINT_SOURCE_LINES_NOERROR;
> }
> }
> else
> {
> desc = last_source_error;
> - noerror = 1;
> + flags |= PRINT_SOURCE_LINES_NOERROR;
> noprint = 1;
> }
>
> @@ -1270,7 +1268,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
> {
> last_source_error = desc;
>
> - if (!noerror)
> + if (!(flags & PRINT_SOURCE_LINES_NOERROR))
> {
> char *name = alloca (strlen (s->filename) + 100);
> sprintf (name, "%d\t%s", line, s->filename);
> @@ -1356,9 +1354,9 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
> window otherwise it is simply printed. */
>
> void
> -print_source_lines (struct symtab *s, int line, int stopline, int noerror)
> +print_source_lines (struct symtab *s, int line, int stopline, int flags)
Here again.
> {
> - print_source_lines_base (s, line, stopline, noerror);
> + print_source_lines_base (s, line, stopline, flags);
> }
> \f
> /* Print info on range of pc's in a specified line. */
> diff --git a/gdb/symtab.h b/gdb/symtab.h
> index 526fe5a..a8c57cf 100644
> --- a/gdb/symtab.h
> +++ b/gdb/symtab.h
> @@ -1143,6 +1143,11 @@ extern void clear_solib (void);
>
> extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
>
> +/* Flags passed as 4th argument to print_source_lines. */
> +enum print_source_lines_flags {
> + PRINT_SOURCE_LINES_NOERROR = (0x1 << 0)
> +};
GNU Coding Style formatting is (+I changed 0x1, it is just a bit):
enum print_source_lines_flags
{
PRINT_SOURCE_LINES_NOERROR = (1 << 0)
};
> +
> extern void print_source_lines (struct symtab *, int, int, int);
>
> extern void forget_cached_source_info_for_objfile (struct objfile *);
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 02/16] source: add flags to print_source_lines ()
2012-05-30 20:41 ` Jan Kratochvil
@ 2012-05-31 15:34 ` Metzger, Markus T
2012-06-22 20:08 ` Tom Tromey
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:34 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1541 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:41 PM
> To: Metzger, Markus T
Thanks for your review!
[...]
> > gdb/
> > * symtab.h (print_source_lines_flags): New enum
> > * source.c (print_source_lines_base): Change noerror to flags
> > (print_source_lines): Change noerror to flags
>
> The indentation should not be there, just:
>
> gdb/
> * symtab.h (print_source_lines_flags): New enum.
> * source.c (print_source_lines_base): Change noerror to flags.
> (print_source_lines): Change noerror to flags.
>
> And every sentence should be terminated by a dot.
Fixed.
> > static void
> > -print_source_lines_base (struct symtab *s, int line, int stopline,
> > int noerror)
> > +print_source_lines_base (struct symtab *s, int line, int stopline,
> > +int flags)
>
> Make it then 'enum print_source_lines_flags flags'.
Flags is intended as bit vector. The enum just gives names to the individual
bits.
> > void
> > -print_source_lines (struct symtab *s, int line, int stopline, int
> > noerror)
> > +print_source_lines (struct symtab *s, int line, int stopline, int
> > +flags)
>
> Here again.
Same here.
> > +/* Flags passed as 4th argument to print_source_lines. */ enum
> > +print_source_lines_flags {
> > + PRINT_SOURCE_LINES_NOERROR = (0x1 << 0) };
>
> GNU Coding Style formatting is (+I changed 0x1, it is just a bit):
>
> enum print_source_lines_flags
> {
> PRINT_SOURCE_LINES_NOERROR = (1 << 0)
> };
Fixed.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 02/16] source: add flags to print_source_lines ()
2012-05-31 15:34 ` Metzger, Markus T
@ 2012-06-22 20:08 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Tom Tromey @ 2012-06-22 20:08 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: Jan Kratochvil, kettenis, gdb-patches, markus.t.metzger
>>>>> "Markus" == Metzger, Markus T <markus.t.metzger@intel.com> writes:
Jan> Make it then 'enum print_source_lines_flags flags'.
Markus> Flags is intended as bit vector. The enum just gives names to
Markus> the individual bits.
In C it is ok to use the enum type the way that Jan suggests; and it
makes debugging a bit simpler since gdb will print the symbolic value.
gdb doesn't do this consistently (it doesn't do anything consistently
:-); but it is nice to do in new code.
Tom
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 02/16] source: add flags to print_source_lines ()
2012-06-22 20:08 ` Tom Tromey
@ 2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-25 8:50 UTC (permalink / raw)
To: Tom Tromey; +Cc: Jan Kratochvil, kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 701 bytes --]
> -----Original Message-----
> From: Tom Tromey [mailto:tromey@redhat.com]
> Sent: Friday, June 22, 2012 10:08 PM
[...]
> Jan> Make it then 'enum print_source_lines_flags flags'.
>
> Markus> Flags is intended as bit vector. The enum just gives names to
> Markus> the individual bits.
>
> In C it is ok to use the enum type the way that Jan suggests; and it
> makes debugging a bit simpler since gdb will print the symbolic value.
> gdb doesn't do this consistently (it doesn't do anything consistently
> :-); but it is nice to do in new code.
It's consistent in that, at least;-)
I pointed out in a reply to Jan already that this won't compile as C++.
I changed it to an enum.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 15/16] gdbserver, btrace: add generic btrace support
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (2 preceding siblings ...)
2012-05-23 11:24 ` [PATCH 02/16] source: add flags to print_source_lines () markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-23 11:25 ` [PATCH 16/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
` (14 subsequent siblings)
18 siblings, 0 replies; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add support to gdbserver to understand branch trace related packages.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/gdbserver/
* target.h (struct target_ops): Add btrace ops
(target_supports_btrace): New macro
(target_btrace_has_changed): New macro
(target_enable_btrace): New macro
(target_disable_btrace): New macro
(target_read_btrace): New macro
* gdbthread.h (struct thread_info): Add btrace field
* server.c (handle_btrace_general_set): New function
(handle_general_set): Call handle_btrace_general_set
(handle_qxfer_btrace): New function
(struct qxfer qxfer_packets[]): Add btrace entry
(handle_btrace_query): New function
(handle_query): Add btrace to supported query, call handle_btrace_query
* inferiors.c (remove_thread): Disable btrace
---
gdb/gdbserver/gdbthread.h | 5 ++
gdb/gdbserver/inferiors.c | 3 +
gdb/gdbserver/server.c | 171 +++++++++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/target.h | 38 ++++++++++
4 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index d863ec0..b2b6f62 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -22,6 +22,8 @@
#include "server.h"
+struct btrace_target_info;
+
struct thread_info
{
struct inferior_list_entry entry;
@@ -58,6 +60,9 @@ struct thread_info
Each item in the list holds the current step of the while-stepping
action. */
struct wstep_state *while_stepping;
+
+ /* Branch trace target information for this thread. */
+ struct btrace_target_info *btrace;
};
extern struct inferior_list all_threads;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 76abaf5..76f5731 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -161,6 +161,9 @@ free_one_thread (struct inferior_list_entry *inf)
void
remove_thread (struct thread_info *thread)
{
+ if (thread->btrace)
+ target_disable_btrace (thread->btrace);
+
remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
free_one_thread (&thread->entry);
}
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index b3d1b41..87613b9 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -446,6 +446,85 @@ write_qxfer_response (char *buf, const void *data, int len, int is_more)
/* Handle all of the extended 'Q' packets. */
+static int
+handle_btrace_general_set (char *own_buf)
+{
+ char *operation = own_buf + strlen ("Qbtrace:");
+
+ if (strncmp ("Qbtrace:", own_buf, strlen ("Qbtrace:")) != 0)
+ return 0;
+
+ if (strncmp ("on:", operation, strlen ("on:")) == 0)
+ {
+ char* ptid_str = operation + strlen ("on:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (thread->btrace)
+ {
+ fprintf (stderr, "Btrace already enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ {
+ thread->btrace = target_enable_btrace (thread->entry.id);
+ if (!thread->btrace)
+ {
+ fprintf (stderr, "Could not enable btrace for %s: %s\n",
+ ptid_str, strerror (errno));
+ write_enn (own_buf);
+ }
+ else
+ write_ok (own_buf);
+ }
+ }
+ else if (strncmp ("off:", operation, strlen ("off:")) == 0)
+ {
+ char* ptid_str = operation + strlen ("off:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ {
+ int errcode = target_disable_btrace (thread->btrace);
+ if (errcode)
+ {
+ fprintf (stderr, "Could not disable btrace for %s: %s\n",
+ ptid_str, strerror (errcode));
+ write_enn (own_buf);
+ }
+ else
+ {
+ thread->btrace = NULL;
+ write_ok (own_buf);
+ }
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Unknown btrace operation: %s. Use on or off.\n",
+ own_buf);
+ write_enn (own_buf);
+ }
+
+ return 1;
+}
+
static void
handle_general_set (char *own_buf)
{
@@ -600,6 +679,9 @@ handle_general_set (char *own_buf)
return;
}
+ if (handle_btrace_general_set (own_buf))
+ return;
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
@@ -1298,6 +1380,57 @@ handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
return (*the_target->read_loadmap) (annex, offset, readbuf, len);
}
+static int
+handle_qxfer_btrace (const char *annex,
+ gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST offset, LONGEST len)
+{
+ static struct buffer cache;
+ struct thread_info *thread;
+ ptid_t ptid;
+ int error;
+
+ if (!the_target->read_btrace || writebuf)
+ return -2;
+
+ if (!target_running () || !annex)
+ return -1;
+
+ ptid = read_ptid ((char *) annex, NULL);
+ thread = find_thread_ptid (ptid);
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", annex);
+ return -1;
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", annex);
+ return -1;
+ }
+
+ if (!offset)
+ {
+ buffer_free (&cache);
+
+ error = target_read_btrace (thread->btrace, &cache);
+ if (error)
+ return -error;
+ }
+ else if (offset >= cache.used_size)
+ {
+ buffer_free (&cache);
+ return 0;
+ }
+
+ if (len > (cache.used_size - offset))
+ len = cache.used_size - offset;
+
+ memcpy (readbuf, cache.buffer + offset, len);
+
+ return len;
+}
+
static const struct qxfer qxfer_packets[] =
{
{ "auxv", handle_qxfer_auxv },
@@ -1311,6 +1444,7 @@ static const struct qxfer qxfer_packets[] =
{ "statictrace", handle_qxfer_statictrace },
{ "threads", handle_qxfer_threads },
{ "traceframe-info", handle_qxfer_traceframe_info },
+ { "btrace", handle_qxfer_btrace },
};
static int
@@ -1467,6 +1601,33 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
/* Handle all of the extended 'q' packets. */
+static int
+handle_btrace_query (char *own_buf)
+{
+ if (strncmp ("qbtrace:", own_buf, strlen ("qbtrace:")) == 0)
+ {
+ char *ptid_str = own_buf + strlen ("qbtrace:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ strcpy (own_buf,
+ (target_btrace_has_changed (thread->btrace) ? "yes" : "no"));
+ return 1;
+ }
+ return 0;
+}
+
void
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
@@ -1693,6 +1854,13 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_agent ())
strcat (own_buf, ";QAgent+");
+ if (target_supports_btrace ())
+ {
+ strcat (own_buf, ";qbtrace+");
+ strcat (own_buf, ";Qbtrace+");
+ strcat (own_buf, ";qXfer:btrace:read+");
+ }
+
return;
}
@@ -1883,6 +2051,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_tracepoints () && handle_tracepoint_query (own_buf))
return;
+ if (handle_btrace_query (own_buf))
+ return;
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index dcf0230..f89b106 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -22,6 +22,8 @@
#define TARGET_H
struct emit_ops;
+struct btrace_target_info;
+struct buffer;
/* Ways to "resume" a thread. */
@@ -397,6 +399,23 @@ struct target_ops
/* Return true if target supports debugging agent. */
int (*supports_agent) (void);
+
+ /* Check whether the target supports branch tracing. */
+ int (*supports_btrace) (void);
+
+ /* Enable branch tracing for @ptid and allocate a branch trace target
+ information struct for reading and for disabling branch trace. */
+ struct btrace_target_info *(*enable_btrace) (ptid_t ptid);
+
+ /* Disable branch tracing. */
+ int (*disable_btrace) (struct btrace_target_info *tinfo);
+
+ /* Check whether branch trace changed on the target. */
+ int (*btrace_has_changed) (struct btrace_target_info *);
+
+ /* Read branch trace data into buffer.
+ Returns 0 on success, an error code, otherwise. */
+ int (*read_btrace) (struct btrace_target_info *, struct buffer *);
};
extern struct target_ops *the_target;
@@ -521,6 +540,25 @@ void set_target_ops (struct target_ops *);
(the_target->supports_agent ? \
(*the_target->supports_agent) () : 0)
+#define target_supports_btrace() \
+ (the_target->supports_btrace ? (*the_target->supports_btrace) () : 0)
+
+#define target_enable_btrace(ptid) \
+ (the_target->enable_btrace ? \
+ (*the_target->enable_btrace) (ptid) : (errno = ENOSYS, NULL))
+
+#define target_disable_btrace(tinfo) \
+ (the_target->disable_btrace ? \
+ (*the_target->disable_btrace) (tinfo) : (errno = ENOSYS))
+
+#define target_btrace_has_changed(tinfo) \
+ (the_target->btrace_has_changed ? \
+ (*the_target->btrace_has_changed) (tinfo) : (errno = ENOSYS, 0))
+
+#define target_read_btrace(tinfo, buffer) \
+ (the_target->read_btrace ? \
+ (*the_target->read_btrace) (tinfo, buffer) : (errno = ENOSYS))
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 16/16] gdbserver, linux, btrace: add btrace support for linux-low
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (3 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 15/16] gdbserver, btrace: add generic btrace support markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-23 11:25 ` [PATCH 13/16] xml, btrace: define btrace xml document style markus.t.metzger
` (13 subsequent siblings)
18 siblings, 0 replies; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Implement btrace target ops in target linux-low using the common linux-btrace
functions.
Add linux-btrace.o to all targets that link linux-low.o. I'd rather not link it
to targets that do not support branch tracing, but this would require changing
the way target ops are defined for gdbserver.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/gdbserver/
* linux-low: Include linux-btrace.h
(linux_low_enable_btrace): New function
(linux_low_print_btrace_record): New function
(linux_low_read_btrace): New function
(linux_target_ops): Add btrace ops
* configure.srv: Add linux-btrace.o
---
gdb/gdbserver/configure.srv | 34 +++++++++++++++++-----------------
gdb/gdbserver/linux-low.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 17 deletions(-)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index e6ae157..7f33dd1 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -47,7 +47,7 @@ case "${target}" in
srv_regobj="${srv_regobj} arm-with-vfpv3.o"
srv_regobj="${srv_regobj} arm-with-neon.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-arm-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_xmlfiles="arm-with-iwmmxt.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
@@ -70,19 +70,19 @@ case "${target}" in
;;
bfin-*-*linux*) srv_regobj=reg-bfin.o
srv_tgtobj="linux-low.o linux-osdata.o linux-bfin-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
crisv32-*-linux*) srv_regobj=reg-crisv32.o
srv_tgtobj="linux-low.o linux-osdata.o linux-crisv32-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
cris-*-linux*) srv_regobj=reg-cris.o
srv_tgtobj="linux-low.o linux-osdata.o linux-cris-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
@@ -97,7 +97,7 @@ case "${target}" in
srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
fi
srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
@@ -129,12 +129,12 @@ case "${target}" in
;;
ia64-*-linux*) srv_regobj=reg-ia64.o
srv_tgtobj="linux-low.o linux-osdata.o linux-ia64-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
;;
m32r*-*-linux*) srv_regobj=reg-m32r.o
srv_tgtobj="linux-low.o linux-osdata.o linux-m32r-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
@@ -144,7 +144,7 @@ case "${target}" in
srv_regobj=reg-m68k.o
fi
srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
@@ -155,7 +155,7 @@ case "${target}" in
srv_regobj=reg-m68k.o
fi
srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
@@ -165,7 +165,7 @@ case "${target}" in
srv_regobj="${srv_regobj} mips64-linux.o"
srv_regobj="${srv_regobj} mips64-dsp-linux.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-mips-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_xmlfiles="mips-linux.xml"
srv_xmlfiles="${srv_xmlfiles} mips-dsp-linux.xml"
srv_xmlfiles="${srv_xmlfiles} mips-cpu.xml"
@@ -198,7 +198,7 @@ case "${target}" in
srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o"
srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-ppc-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_xmlfiles="rs6000/powerpc-32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-altivec32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-cell32l.xml"
@@ -241,7 +241,7 @@ case "${target}" in
srv_regobj="${srv_regobj} s390x-linux64v1.o"
srv_regobj="${srv_regobj} s390x-linux64v2.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_xmlfiles="s390-linux32.xml"
srv_xmlfiles="${srv_xmlfiles} s390-linux32v1.xml"
srv_xmlfiles="${srv_xmlfiles} s390-linux32v2.xml"
@@ -262,14 +262,14 @@ case "${target}" in
;;
sh*-*-linux*) srv_regobj=reg-sh.o
srv_tgtobj="linux-low.o linux-osdata.o linux-sh-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
sparc*-*-linux*) srv_regobj=reg-sparc64.o
srv_tgtobj="linux-low.o linux-osdata.o linux-sparc-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
@@ -286,14 +286,14 @@ case "${target}" in
srv_xmlfiles="${srv_xmlfiles} tic6x-gp.xml"
srv_xmlfiles="${srv_xmlfiles} tic6x-c6xp.xml"
srv_tgtobj="linux-low.o linux-osdata.o linux-tic6x-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_regsets=yes
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
x86_64-*-linux*) srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
srv_linux_usrregs=yes # This is for i386 progs.
srv_linux_regsets=yes
@@ -308,7 +308,7 @@ case "${target}" in
xtensa*-*-linux*) srv_regobj=reg-xtensa.o
srv_tgtobj="linux-low.o linux-osdata.o linux-xtensa-low.o linux-procfs.o"
- srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
srv_linux_regsets=yes
;;
*) echo "Error: target not supported by gdbserver."
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 5fe19fd..f041a56 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,7 @@
#include "linux-low.h"
#include "linux-osdata.h"
#include "agent.h"
+#include "linux-btrace.h"
#include <sys/wait.h>
#include <stdio.h>
@@ -5777,6 +5778,42 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
return len;
}
+static int
+linux_low_print_btrace_record (struct linux_btrace_block *raw, void *arg)
+{
+ struct buffer *buffer = arg;
+
+ if (!raw)
+ return EINVAL;
+
+ if (!buffer)
+ return EINVAL;
+
+ buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+ paddress (raw->begin), paddress (raw->end));
+
+ return 0;
+}
+
+static int
+linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer)
+{
+ int errcode;
+
+ if (!tinfo || !buffer)
+ return EINVAL;
+
+ if (!tinfo->ptr_bits)
+ tinfo->ptr_bits = register_size (0) * 8;
+
+ buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
+ buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+ errcode = linux_read_btrace (tinfo, linux_low_print_btrace_record, buffer);
+ buffer_grow_str (buffer, "</btrace>\n");
+
+ return errcode;
+}
+
static struct target_ops linux_target_ops = {
linux_create_inferior,
linux_attach,
@@ -5841,6 +5878,11 @@ static struct target_ops linux_target_ops = {
linux_get_min_fast_tracepoint_insn_len,
linux_qxfer_libraries_svr4,
linux_supports_agent,
+ linux_supports_btrace,
+ linux_enable_btrace,
+ linux_disable_btrace,
+ linux_btrace_has_changed,
+ linux_low_read_btrace,
};
static void
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 13/16] xml, btrace: define btrace xml document style
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (4 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 16/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 01/16] disas: add precise instructions flag markus.t.metzger
` (12 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Define the xml document style for transferring branch trace data.
Add a function to parse a btrace xml document into a vector of branch trace
blocks.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/features/
* btrace.dtd: New file
gdb/
* Makefile.in (XMLFILES): Add btrace.dtd
* btrace.h (parse_xml_btrace): New declaration
* btrace.c (parse_xml_btrace): New function
(parse_xml_btrace_block): New function
(block_attributes): New struct
(btrace_attributes): New struct
(btrace_children): New struct
(btrace_elements): New struct
---
gdb/Makefile.in | 3 +-
gdb/btrace.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
gdb/btrace.h | 3 ++
gdb/features/btrace.dtd | 12 +++++++
4 files changed, 98 insertions(+), 1 deletions(-)
create mode 100644 gdb/features/btrace.dtd
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index b3fdd4f..5c31ecd 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -489,7 +489,8 @@ RUNTESTFLAGS=
XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
$(srcdir)/features/library-list.dtd \
$(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
- $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd
+ $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
+ $(srcdir)/features/btrace.dtd
# This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
# interface to the serial port. Hopefully if get ported to OS/2, VMS,
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 2b57ca7..c2aef67 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -29,6 +29,7 @@
#include "cli/cli-utils.h"
#include "arch-utils.h"
#include "disasm.h"
+#include "xml-support.h"
#include <errno.h>
#include <ctype.h>
@@ -798,6 +799,86 @@ cmd_btrace (char *args, int from_tty)
do_btrace (trace, flags);
}
+#if defined(HAVE_LIBEXPAT)
+
+static void
+check_xml_btrace_version (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data, VEC (gdb_xml_value_s) *attributes)
+{
+ const char *version = xml_find_attribute (attributes, "version")->value;
+ if (strcmp (version, "1.0") != 0)
+ gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version);
+}
+
+static void
+parse_xml_btrace_block (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data, VEC (gdb_xml_value_s) *attributes)
+{
+ VEC (btrace_block_s) **btrace = user_data;
+ struct btrace_block *block = VEC_safe_push (btrace_block_s, *btrace, NULL);
+ ULONGEST *begin, *end;
+
+ begin = xml_find_attribute (attributes, "begin")->value;
+ end = xml_find_attribute (attributes, "end")->value;
+
+ block->begin = *begin;
+ block->end = *end;
+}
+
+const struct gdb_xml_attribute block_attributes[] = {
+ { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+const struct gdb_xml_attribute btrace_attributes[] = {
+ { "version", GDB_XML_AF_NONE, NULL, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+const struct gdb_xml_element btrace_children[] = {
+ { "block", block_attributes, NULL,
+ GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+const struct gdb_xml_element btrace_elements[] = {
+ { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE,
+ check_xml_btrace_version, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+#endif /* defined(HAVE_LIBEXPAT) */
+
+VEC (btrace_block_s) *
+parse_xml_btrace (const char *buffer)
+{
+ VEC (btrace_block_s) *btrace = NULL;
+ struct cleanup *cleanup;
+ int errcode;
+
+#if defined(HAVE_LIBEXPAT)
+ cleanup = make_cleanup (xfree, btrace);
+ errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
+ buffer, &btrace);
+ if (errcode)
+ {
+ do_cleanups (cleanup);
+ errno = errcode;
+ return NULL;
+ }
+
+ /* Keep parse results. */
+ discard_cleanups (cleanup);
+#else /* defined(HAVE_LIBEXPAT) */
+ errno = ENOSYS;
+#endif /* defined(HAVE_LIBEXPAT) */
+
+ return btrace;
+}
+
void _initialize_btrace (void);
void
diff --git a/gdb/btrace.h b/gdb/btrace.h
index 97f0f52..12e70b9 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -86,4 +86,7 @@ extern struct btrace_block *read_btrace (struct thread_info *, int);
extern struct btrace_block *prev_btrace (struct thread_info *);
extern struct btrace_block *next_btrace (struct thread_info *);
+/* Parse a branch trace xml document into a block vector. */
+extern VEC (btrace_block_s) *parse_xml_btrace (const char*);
+
#endif /* BTRACE_H */
diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd
new file mode 100644
index 0000000..7e6bfd0
--- /dev/null
+++ b/gdb/features/btrace.dtd
@@ -0,0 +1,12 @@
+<!-- Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!ELEMENT btrace (block)* >
+<!ATTLIST btrace version CDATA #REQUIRED>
+
+<!ELEMENT block EMPTY>
+<!ATTLIST block begin CDATA #REQUIRED
+ end CDATA #REQUIRED>
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 13/16] xml, btrace: define btrace xml document style
2012-05-23 11:25 ` [PATCH 13/16] xml, btrace: define btrace xml document style markus.t.metzger
@ 2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 8:39 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:44 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:28 +0200, markus.t.metzger@intel.com wrote:
> diff --git a/gdb/Makefile.in b/gdb/Makefile.in
> index b3fdd4f..5c31ecd 100644
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -489,7 +489,8 @@ RUNTESTFLAGS=
> XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
> $(srcdir)/features/library-list.dtd \
> $(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
> - $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd
> + $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
> + $(srcdir)/features/btrace.dtd
>
> # This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
> # interface to the serial port. Hopefully if get ported to OS/2, VMS,
> diff --git a/gdb/btrace.c b/gdb/btrace.c
> index 2b57ca7..c2aef67 100644
> --- a/gdb/btrace.c
> +++ b/gdb/btrace.c
> @@ -29,6 +29,7 @@
> #include "cli/cli-utils.h"
> #include "arch-utils.h"
> #include "disasm.h"
> +#include "xml-support.h"
>
> #include <errno.h>
> #include <ctype.h>
> @@ -798,6 +799,86 @@ cmd_btrace (char *args, int from_tty)
> do_btrace (trace, flags);
> }
>
> +#if defined(HAVE_LIBEXPAT)
> +
> +static void
> +check_xml_btrace_version (struct gdb_xml_parser *parser,
> + const struct gdb_xml_element *element,
> + void *user_data, VEC (gdb_xml_value_s) *attributes)
> +{
> + const char *version = xml_find_attribute (attributes, "version")->value;
Empty line.
> + if (strcmp (version, "1.0") != 0)
> + gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version);
> +}
> +
> +static void
> +parse_xml_btrace_block (struct gdb_xml_parser *parser,
> + const struct gdb_xml_element *element,
> + void *user_data, VEC (gdb_xml_value_s) *attributes)
> +{
> + VEC (btrace_block_s) **btrace = user_data;
> + struct btrace_block *block = VEC_safe_push (btrace_block_s, *btrace, NULL);
> + ULONGEST *begin, *end;
> +
> + begin = xml_find_attribute (attributes, "begin")->value;
> + end = xml_find_attribute (attributes, "end")->value;
> +
> + block->begin = *begin;
> + block->end = *end;
> +}
> +
> +const struct gdb_xml_attribute block_attributes[] = {
It can be static. The same in other cases.
> + { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
> + { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
> + { NULL, GDB_XML_AF_NONE, NULL, NULL }
> +};
> +
> +const struct gdb_xml_attribute btrace_attributes[] = {
> + { "version", GDB_XML_AF_NONE, NULL, NULL },
> + { NULL, GDB_XML_AF_NONE, NULL, NULL }
> +};
> +
> +const struct gdb_xml_element btrace_children[] = {
> + { "block", block_attributes, NULL,
> + GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL },
> + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
> +};
> +
> +const struct gdb_xml_element btrace_elements[] = {
> + { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE,
> + check_xml_btrace_version, NULL },
> + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
> +};
> +
> +#endif /* defined(HAVE_LIBEXPAT) */
> +
> +VEC (btrace_block_s) *
> +parse_xml_btrace (const char *buffer)
> +{
> + VEC (btrace_block_s) *btrace = NULL;
> + struct cleanup *cleanup;
> + int errcode;
> +
> +#if defined(HAVE_LIBEXPAT)
> + cleanup = make_cleanup (xfree, btrace);
Use VEC_cleanup, not xfree.
> + errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
> + buffer, &btrace);
> + if (errcode)
> + {
> + do_cleanups (cleanup);
> + errno = errcode;
> + return NULL;
> + }
> +
> + /* Keep parse results. */
> + discard_cleanups (cleanup);
> +#else /* defined(HAVE_LIBEXPAT) */
> + errno = ENOSYS;
Again, use some error, not errno.
> +#endif /* defined(HAVE_LIBEXPAT) */
> +
> + return btrace;
> +}
> +
> void _initialize_btrace (void);
>
> void
> diff --git a/gdb/btrace.h b/gdb/btrace.h
> index 97f0f52..12e70b9 100644
> --- a/gdb/btrace.h
> +++ b/gdb/btrace.h
> @@ -86,4 +86,7 @@ extern struct btrace_block *read_btrace (struct thread_info *, int);
> extern struct btrace_block *prev_btrace (struct thread_info *);
> extern struct btrace_block *next_btrace (struct thread_info *);
>
> +/* Parse a branch trace xml document into a block vector. */
> +extern VEC (btrace_block_s) *parse_xml_btrace (const char*);
> +
> #endif /* BTRACE_H */
> diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd
> new file mode 100644
> index 0000000..7e6bfd0
> --- /dev/null
> +++ b/gdb/features/btrace.dtd
> @@ -0,0 +1,12 @@
> +<!-- Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Copying and distribution of this file, with or without modification,
> + are permitted in any medium without royalty provided the copyright
> + notice and this notice are preserved. -->
> +
> +<!ELEMENT btrace (block)* >
> +<!ATTLIST btrace version CDATA #REQUIRED>
> +
> +<!ELEMENT block EMPTY>
> +<!ATTLIST block begin CDATA #REQUIRED
> + end CDATA #REQUIRED>
> --
> 1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 13/16] xml, btrace: define btrace xml document style
2012-05-30 20:44 ` Jan Kratochvil
@ 2012-06-01 8:39 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-01 8:39 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1062 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:44 PM
Thanks for your review!
[...]
> > +*attributes) {
> > + const char *version = xml_find_attribute (attributes,
> > +"version")->value;
>
> Empty line.
Fixed.
[...]
> > +const struct gdb_xml_attribute block_attributes[] = {
>
> It can be static. The same in other cases.
Fixed.
[...]
> > +#if defined(HAVE_LIBEXPAT)
> > + cleanup = make_cleanup (xfree, btrace);
>
> Use VEC_cleanup, not xfree.
Fixed.
> > + errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd",
> btrace_elements,
> > + buffer, &btrace); if (errcode)
> > + {
> > + do_cleanups (cleanup);
> > + errno = errcode;
> > + return NULL;
> > + }
> > +
> > + /* Keep parse results. */
> > + discard_cleanups (cleanup);
> > +#else /* defined(HAVE_LIBEXPAT) */
> > + errno = ENOSYS;
>
> Again, use some error, not errno.
I guess I need to rework the entire error handling.
[...]
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 01/16] disas: add precise instructions flag
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (5 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 13/16] xml, btrace: define btrace xml document style markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-23 11:25 ` [PATCH 03/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
` (11 subsequent siblings)
18 siblings, 0 replies; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
When disassembling an address range with interleaved sources, the addresses that
are being disassembled may not exactly match the specified range.
Addresses may be:
- added after the specified range
- omitted at the beginning of the specified range
Add a new disassembly flag that fixes the above two cases.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* disasm.h: Add new flag DISASSEMBLY_PRECISE_INSN
* disasm.c (do_mixed_source_and_assembly): Adjust mle boundaries
---
gdb/disasm.c | 28 ++++++++++++++++++++++++----
gdb/disasm.h | 7 ++++---
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/gdb/disasm.c b/gdb/disasm.c
index e3d3349..4902d95 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -217,13 +217,22 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
/* First, skip all the preceding functions. */
- for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+ /* If we want precise instructions, we only skip the line entries for which
+ the pc range between this and the next entry precedes the requested
+ instruction range. */
+ if (flags & DISASSEMBLY_PRECISE_INSN)
+ for (i = 0; i < nlines - 2 && le[i + 1].pc <= low; i++);
+ else
+ for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
/* Now, copy all entries before the end of this function. */
for (; i < nlines - 1 && le[i].pc < high; i++)
{
- if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+ CORE_ADDR start = le[i].pc;
+ CORE_ADDR end = le[i + 1].pc;
+
+ if (le[i].line == le[i + 1].line && start == end)
continue; /* Ignore duplicates. */
/* Skip any end-of-function markers. */
@@ -233,8 +242,19 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
mle[newlines].line = le[i].line;
if (le[i].line > le[i + 1].line)
out_of_order = 1;
- mle[newlines].start_pc = le[i].pc;
- mle[newlines].end_pc = le[i + 1].pc;
+
+ /* If we want precise instructions, adjust the line ranges to only contain
+ instructions in the requested range. */
+ if (flags & DISASSEMBLY_PRECISE_INSN)
+ {
+ if (high < end)
+ end = high;
+ if (start < low)
+ start = low;
+ }
+
+ mle[newlines].start_pc = start;
+ mle[newlines].end_pc = end;
newlines++;
}
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 646ee8e..5b459f4 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -19,9 +19,10 @@
#ifndef DISASM_H
#define DISASM_H
-#define DISASSEMBLY_SOURCE (0x1 << 0)
-#define DISASSEMBLY_RAW_INSN (0x1 << 1)
-#define DISASSEMBLY_OMIT_FNAME (0x1 << 2)
+#define DISASSEMBLY_SOURCE (0x1 << 0)
+#define DISASSEMBLY_RAW_INSN (0x1 << 1)
+#define DISASSEMBLY_OMIT_FNAME (0x1 << 2)
+#define DISASSEMBLY_PRECISE_INSN (0x1 << 3)
struct ui_out;
struct ui_file;
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 03/16] source, disasm: optionally prefix source lines with filename
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (6 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 01/16] disas: add precise instructions flag markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:41 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 14/16] remote, btrace: add branch trace remote ops markus.t.metzger
` (10 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add respective flags to print_source_lines () and gdb_disassembly () to prefix
the source line with its file name.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* disasm.h (DISASSEMBLY_FILENAME): New macro
* disasm.c (do_mixed_source_and_assembly): Pass filename flag on to
print_source_lines ().
* symtab.h (PRINT_SOURCE_LINES_FILENAME): New print source lines flag
* source.c (print_source_lines_base): Prefix source line with filename if
PRINT_SOURCE_LINES_FILENAME flag is set.
---
gdb/disasm.c | 12 ++++++++----
gdb/disasm.h | 1 +
gdb/source.c | 5 +++++
gdb/symtab.h | 3 ++-
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 4902d95..d0a0be4 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -204,10 +204,14 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
int out_of_order = 0;
int next_line = 0;
int num_displayed = 0;
+ int psl_flags = 0;
struct cleanup *ui_out_chain;
struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
+ if (flags & DISASSEMBLY_FILENAME)
+ psl_flags |= PRINT_SOURCE_LINES_FILENAME;
+
mle = (struct dis_line_entry *) alloca (nlines
* sizeof (struct dis_line_entry));
@@ -295,7 +299,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
ui_out_tuple_chain
= make_cleanup_ui_out_tuple_begin_end (uiout,
"src_and_asm_line");
- print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
}
else
{
@@ -309,7 +313,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
= make_cleanup_ui_out_tuple_begin_end (uiout,
"src_and_asm_line");
print_source_lines (symtab, next_line, next_line + 1,
- 0);
+ psl_flags);
ui_out_list_chain_line
= make_cleanup_ui_out_list_begin_end (uiout,
"line_asm_insn");
@@ -321,7 +325,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
ui_out_tuple_chain
= make_cleanup_ui_out_tuple_begin_end (uiout,
"src_and_asm_line");
- print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
}
}
else
@@ -329,7 +333,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
ui_out_tuple_chain
= make_cleanup_ui_out_tuple_begin_end (uiout,
"src_and_asm_line");
- print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+ print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
}
next_line = mle[i].line + 1;
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 5b459f4..5ae71c9 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -23,6 +23,7 @@
#define DISASSEMBLY_RAW_INSN (0x1 << 1)
#define DISASSEMBLY_OMIT_FNAME (0x1 << 2)
#define DISASSEMBLY_PRECISE_INSN (0x1 << 3)
+#define DISASSEMBLY_FILENAME (0x1 << 4)
struct ui_out;
struct ui_file;
diff --git a/gdb/source.c b/gdb/source.c
index 4dd7ed2..a1ca6d3 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1315,6 +1315,11 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int flags)
if (c == EOF)
break;
last_line_listed = current_source_line;
+ if (flags & PRINT_SOURCE_LINES_FILENAME)
+ {
+ ui_out_text (uiout, s->filename);
+ ui_out_text (uiout, ":");
+ }
sprintf (buf, "%d\t", current_source_line++);
ui_out_text (uiout, buf);
do
diff --git a/gdb/symtab.h b/gdb/symtab.h
index a8c57cf..9287814 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1145,7 +1145,8 @@ extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
/* Flags passed as 4th argument to print_source_lines. */
enum print_source_lines_flags {
- PRINT_SOURCE_LINES_NOERROR = (0x1 << 0)
+ PRINT_SOURCE_LINES_NOERROR = (0x1 << 0),
+ PRINT_SOURCE_LINES_FILENAME = (0x1 << 1)
};
extern void print_source_lines (struct symtab *, int, int, int);
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 03/16] source, disasm: optionally prefix source lines with filename
2012-05-23 11:25 ` [PATCH 03/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
@ 2012-05-30 20:41 ` Jan Kratochvil
0 siblings, 0 replies; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:41 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:18 +0200, markus.t.metzger@intel.com wrote:
> --- a/gdb/disasm.c
> +++ b/gdb/disasm.c
> @@ -204,10 +204,14 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
> int out_of_order = 0;
> int next_line = 0;
> int num_displayed = 0;
> + int psl_flags = 0;
enum here again.
> struct cleanup *ui_out_chain;
> struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
> struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
[...]
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 14/16] remote, btrace: add branch trace remote ops
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (7 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 03/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
` (9 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add the gdb remote target operations for branch tracing. We define the following
packets:
qbtrace:<ptid> query if new trace data is available for a thread
returns "yes" or "no" or "Enn"
Qbtrace:on:<ptid> enable branch tracing for one thread
returns "OK" or "Enn"
Qbtrace:off:<ptid> disable branch tracing for one thread
returns "OK" or "Enn"
qXfer:btrace:read:<ptid> read the full branch trace data for one thread
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* target.h (enum target_object): Add TARGET_OBJECT_BTRACE
* remote.c (struct btrace_target_info): New struct
(remote_supports_btrace): New function
(remote_enable_btrace): New function
(remote_disable_btrace): New function
(remote_btrace_has_changed): New function
(remote_read_btrace): New function
(init_remote_ops): Add btrace ops
(enum <unnamed>): Add btrace packets
(struct protocol_feature remote_protocol_features[]): Add btrace packets
(_initialize_remote): Add btrace packets
---
gdb/remote.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/target.h | 4 +-
2 files changed, 211 insertions(+), 1 deletions(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index 3717a26..df6a878 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -66,6 +66,7 @@
#include "ax.h"
#include "ax-gdb.h"
#include "agent.h"
+#include "btrace.h"
/* Temp hacks for tracepoint encoding migration. */
static char *target_buf;
@@ -1284,6 +1285,9 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qbtrace,
+ PACKET_Qbtrace,
+ PACKET_qXfer_btrace,
PACKET_MAX
};
@@ -3925,6 +3929,10 @@ static struct protocol_feature remote_protocol_features[] = {
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_qbtrace },
+ { "Qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace },
+ { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_btrace }
};
static char *remote_support_xml;
@@ -8588,6 +8596,10 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_BTRACE:
+ return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_btrace]);
+
default:
return -1;
}
@@ -10901,6 +10913,188 @@ remote_can_use_agent (void)
return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
}
+struct btrace_target_info
+{
+ /* The ptid of the traced thread. */
+ ptid_t ptid;
+};
+
+static int
+remote_supports_btrace (void)
+{
+ if (remote_protocol_packets[PACKET_qbtrace].support != PACKET_ENABLE)
+ return 0;
+ if (remote_protocol_packets[PACKET_Qbtrace].support != PACKET_ENABLE)
+ return 0;
+ if (remote_protocol_packets[PACKET_qXfer_btrace].support != PACKET_ENABLE)
+ return 0;
+
+ return 1;
+}
+
+static struct btrace_target_info *
+remote_enable_btrace (ptid_t ptid)
+{
+ struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
+ struct remote_state *rs = get_remote_state ();
+ struct btrace_target_info *tinfo = NULL;
+ char *buf = rs->buf;
+ char *endbuf = rs->buf + get_remote_packet_size ();
+
+ if (packet->support != PACKET_ENABLE)
+ {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+ buf += xsnprintf (buf, endbuf - buf, ":on:");
+ buf = write_ptid (buf, endbuf, ptid);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ switch (packet_ok (rs->buf, packet))
+ {
+ case PACKET_OK:
+ tinfo = xzalloc (sizeof (*tinfo));
+ if (tinfo)
+ tinfo->ptid = ptid;
+ else
+ errno = ENOMEM;
+ break;
+ case PACKET_ERROR:
+ {
+ int pid = ptid_get_lwp (ptid);
+ if (!pid)
+ pid = ptid_get_pid (ptid);
+
+ error (_("Couldn't enable btrace for %d: %s"),
+ pid, rs->buf);
+ }
+ default:
+ errno = ENOSYS;
+ break;
+ }
+
+ return tinfo;
+}
+
+static int
+remote_disable_btrace (struct btrace_target_info *tinfo)
+{
+ struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
+ struct remote_state *rs = get_remote_state ();
+ char *buf = rs->buf;
+ char *endbuf = rs->buf + get_remote_packet_size ();
+
+ if (!tinfo)
+ return EINVAL;
+
+ if (packet->support != PACKET_ENABLE)
+ return ENOSYS;
+
+ buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+ buf += xsnprintf (buf, endbuf - buf, ":off:");
+ buf = write_ptid (buf, endbuf, tinfo->ptid);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ switch (packet_ok (rs->buf, packet))
+ {
+ case PACKET_OK:
+ xfree (tinfo);
+ return 0;
+
+ case PACKET_ERROR:
+ {
+ int pid = ptid_get_lwp (tinfo->ptid);
+ if (!pid)
+ pid = ptid_get_pid (tinfo->ptid);
+
+ error (_("Couldn't disable btrace for %d: %s"),
+ pid, rs->buf);
+ }
+ default:
+ return ENOSYS;
+ }
+}
+
+static int
+remote_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+ struct packet_config *packet = &remote_protocol_packets[PACKET_qbtrace];
+ struct remote_state *rs = get_remote_state ();
+ char *buf = rs->buf;
+ char *endbuf = rs->buf + get_remote_packet_size ();
+
+ if (!tinfo)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+ if (packet->support != PACKET_ENABLE)
+ {
+ errno = ENOSYS;
+ return 0;
+ }
+
+ buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+ buf += xsnprintf (buf, endbuf - buf, ":");
+ buf = write_ptid (buf, endbuf, tinfo->ptid);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ switch (packet_ok (rs->buf, packet))
+ {
+ case PACKET_OK:
+ return (strcmp (rs->buf, "yes") == 0);
+ case PACKET_ERROR:
+ error (_("%s"), rs->buf);
+ default:
+ errno = ENOSYS;
+ return 0;
+ }
+}
+
+static VEC (btrace_block_s) *
+remote_read_btrace (struct btrace_target_info *tinfo)
+{
+ struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
+ struct remote_state *rs = get_remote_state ();
+ char *xml, annex[64], *pend;
+ VEC (btrace_block_s) *btrace = NULL;
+
+ if (!tinfo)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (packet->support != PACKET_ENABLE)
+ {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+#if !defined(HAVE_LIBEXPAT)
+ errno = ENOSYS;
+ return NULL;
+#endif
+
+ memset (annex, 0, sizeof (annex));
+ pend = write_ptid (annex, annex + sizeof (annex), tinfo->ptid);
+
+ xml = target_read_stralloc (¤t_target,
+ TARGET_OBJECT_BTRACE, annex);
+ if (xml)
+ {
+ struct cleanup *cleanup = make_cleanup (xfree, xml);
+ btrace = parse_xml_btrace (xml);
+ do_cleanups (cleanup);
+ }
+
+ return btrace;
+}
+
static void
init_remote_ops (void)
{
@@ -11016,6 +11210,11 @@ Specify the serial device it is connected to\n\
remote_ops.to_traceframe_info = remote_traceframe_info;
remote_ops.to_use_agent = remote_use_agent;
remote_ops.to_can_use_agent = remote_can_use_agent;
+ remote_ops.to_supports_btrace = remote_supports_btrace;
+ remote_ops.to_enable_btrace = remote_enable_btrace;
+ remote_ops.to_disable_btrace = remote_disable_btrace;
+ remote_ops.to_btrace_has_changed = remote_btrace_has_changed;
+ remote_ops.to_read_btrace = remote_read_btrace;
}
/* Set up the extended remote vector by making a copy of the standard
@@ -11538,6 +11737,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qbtrace],
+ "qbtrace", "query-btrace", 0);
+
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace],
+ "Qbtrace", "enable-btrace", 0);
+
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
+ "qXfer:btrace", "read-btrace", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
diff --git a/gdb/target.h b/gdb/target.h
index 86513f7..3730863 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -283,7 +283,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Branch trace data, in XML format. */
+ TARGET_OBJECT_BTRACE
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 14/16] remote, btrace: add branch trace remote ops
2012-05-23 11:25 ` [PATCH 14/16] remote, btrace: add branch trace remote ops markus.t.metzger
@ 2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 8:49 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:44 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:29 +0200, markus.t.metzger@intel.com wrote:
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -66,6 +66,7 @@
> #include "ax.h"
> #include "ax-gdb.h"
> #include "agent.h"
> +#include "btrace.h"
>
> /* Temp hacks for tracepoint encoding migration. */
> static char *target_buf;
> @@ -1284,6 +1285,9 @@ enum {
> PACKET_qXfer_fdpic,
> PACKET_QDisableRandomization,
> PACKET_QAgent,
> + PACKET_qbtrace,
> + PACKET_Qbtrace,
> + PACKET_qXfer_btrace,
> PACKET_MAX
> };
>
> @@ -3925,6 +3929,10 @@ static struct protocol_feature remote_protocol_features[] = {
> { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
> { "tracenz", PACKET_DISABLE,
> remote_string_tracing_feature, -1 },
> + { "qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_qbtrace },
> + { "Qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace },
> + { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet,
> + PACKET_qXfer_btrace }
> };
>
> static char *remote_support_xml;
> @@ -8588,6 +8596,10 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
> return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
> &remote_protocol_packets[PACKET_qXfer_uib]);
>
> + case TARGET_OBJECT_BTRACE:
> + return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len,
> + &remote_protocol_packets[PACKET_qXfer_btrace]);
> +
> default:
> return -1;
> }
> @@ -10901,6 +10913,188 @@ remote_can_use_agent (void)
> return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
> }
>
> +struct btrace_target_info
> +{
> + /* The ptid of the traced thread. */
> + ptid_t ptid;
> +};
> +
> +static int
> +remote_supports_btrace (void)
> +{
> + if (remote_protocol_packets[PACKET_qbtrace].support != PACKET_ENABLE)
> + return 0;
> + if (remote_protocol_packets[PACKET_Qbtrace].support != PACKET_ENABLE)
> + return 0;
> + if (remote_protocol_packets[PACKET_qXfer_btrace].support != PACKET_ENABLE)
> + return 0;
> +
> + return 1;
> +}
> +
> +static struct btrace_target_info *
> +remote_enable_btrace (ptid_t ptid)
> +{
> + struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
> + struct remote_state *rs = get_remote_state ();
> + struct btrace_target_info *tinfo = NULL;
> + char *buf = rs->buf;
> + char *endbuf = rs->buf + get_remote_packet_size ();
> +
> + if (packet->support != PACKET_ENABLE)
> + {
> + errno = ENOSYS;
errno is not used for intra-GDB/gdbserver communication. Everywhere.
> + return NULL;
> + }
> +
> + buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
> + buf += xsnprintf (buf, endbuf - buf, ":on:");
> + buf = write_ptid (buf, endbuf, ptid);
> + putpkt (rs->buf);
> + getpkt (&rs->buf, &rs->buf_size, 0);
> +
> + switch (packet_ok (rs->buf, packet))
> + {
> + case PACKET_OK:
> + tinfo = xzalloc (sizeof (*tinfo));
> + if (tinfo)
Remove, xzalloc can never fail.
> + tinfo->ptid = ptid;
> + else
> + errno = ENOMEM;
> + break;
> + case PACKET_ERROR:
> + {
> + int pid = ptid_get_lwp (ptid);
> + if (!pid)
> + pid = ptid_get_pid (ptid);
> +
> + error (_("Couldn't enable btrace for %d: %s"),
> + pid, rs->buf);
Use target_pid_to_str. Everywhere.
> + }
> + default:
> + errno = ENOSYS;
> + break;
> + }
> +
> + return tinfo;
> +}
> +
> +static int
> +remote_disable_btrace (struct btrace_target_info *tinfo)
> +{
> + struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
> + struct remote_state *rs = get_remote_state ();
> + char *buf = rs->buf;
> + char *endbuf = rs->buf + get_remote_packet_size ();
> +
> + if (!tinfo)
> + return EINVAL;
> +
> + if (packet->support != PACKET_ENABLE)
> + return ENOSYS;
> +
> + buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
> + buf += xsnprintf (buf, endbuf - buf, ":off:");
> + buf = write_ptid (buf, endbuf, tinfo->ptid);
> + putpkt (rs->buf);
> + getpkt (&rs->buf, &rs->buf_size, 0);
> +
> + switch (packet_ok (rs->buf, packet))
> + {
> + case PACKET_OK:
> + xfree (tinfo);
> + return 0;
> +
> + case PACKET_ERROR:
> + {
> + int pid = ptid_get_lwp (tinfo->ptid);
> + if (!pid)
> + pid = ptid_get_pid (tinfo->ptid);
> +
> + error (_("Couldn't disable btrace for %d: %s"),
> + pid, rs->buf);
> + }
> + default:
> + return ENOSYS;
> + }
> +}
> +
> +static int
> +remote_btrace_has_changed (struct btrace_target_info *tinfo)
> +{
> + struct packet_config *packet = &remote_protocol_packets[PACKET_qbtrace];
> + struct remote_state *rs = get_remote_state ();
> + char *buf = rs->buf;
> + char *endbuf = rs->buf + get_remote_packet_size ();
> +
> + if (!tinfo)
> + {
> + errno = EINVAL;
> + return 0;
> + }
> + if (packet->support != PACKET_ENABLE)
> + {
> + errno = ENOSYS;
> + return 0;
> + }
> +
> + buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
> + buf += xsnprintf (buf, endbuf - buf, ":");
> + buf = write_ptid (buf, endbuf, tinfo->ptid);
> + putpkt (rs->buf);
> + getpkt (&rs->buf, &rs->buf_size, 0);
> +
> + switch (packet_ok (rs->buf, packet))
> + {
> + case PACKET_OK:
> + return (strcmp (rs->buf, "yes") == 0);
> + case PACKET_ERROR:
> + error (_("%s"), rs->buf);
> + default:
> + errno = ENOSYS;
> + return 0;
> + }
> +}
> +
> +static VEC (btrace_block_s) *
> +remote_read_btrace (struct btrace_target_info *tinfo)
> +{
> + struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
> + struct remote_state *rs = get_remote_state ();
> + char *xml, annex[64], *pend;
> + VEC (btrace_block_s) *btrace = NULL;
> +
> + if (!tinfo)
> + {
> + errno = EINVAL;
> + return NULL;
> + }
> + if (packet->support != PACKET_ENABLE)
> + {
> + errno = ENOSYS;
> + return NULL;
> + }
> +
> +#if !defined(HAVE_LIBEXPAT)
> + errno = ENOSYS;
> + return NULL;
> +#endif
> +
> + memset (annex, 0, sizeof (annex));
> + pend = write_ptid (annex, annex + sizeof (annex), tinfo->ptid);
> +
> + xml = target_read_stralloc (¤t_target,
> + TARGET_OBJECT_BTRACE, annex);
> + if (xml)
> + {
> + struct cleanup *cleanup = make_cleanup (xfree, xml);
Empty line after declarations.
> + btrace = parse_xml_btrace (xml);
> + do_cleanups (cleanup);
> + }
> +
> + return btrace;
> +}
> +
> static void
> init_remote_ops (void)
> {
> @@ -11016,6 +11210,11 @@ Specify the serial device it is connected to\n\
> remote_ops.to_traceframe_info = remote_traceframe_info;
> remote_ops.to_use_agent = remote_use_agent;
> remote_ops.to_can_use_agent = remote_can_use_agent;
> + remote_ops.to_supports_btrace = remote_supports_btrace;
> + remote_ops.to_enable_btrace = remote_enable_btrace;
> + remote_ops.to_disable_btrace = remote_disable_btrace;
> + remote_ops.to_btrace_has_changed = remote_btrace_has_changed;
> + remote_ops.to_read_btrace = remote_read_btrace;
> }
>
> /* Set up the extended remote vector by making a copy of the standard
> @@ -11538,6 +11737,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
> add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
> "QAgent", "agent", 0);
>
> + add_packet_config_cmd (&remote_protocol_packets[PACKET_qbtrace],
> + "qbtrace", "query-btrace", 0);
> +
> + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace],
> + "Qbtrace", "enable-btrace", 0);
> +
> + add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
> + "qXfer:btrace", "read-btrace", 0);
> +
> /* Keep the old ``set remote Z-packet ...'' working. Each individual
> Z sub-packet has its own set and show commands, but users may
> have sets to this variable in their .gdbinit files (or in their
> diff --git a/gdb/target.h b/gdb/target.h
> index 86513f7..3730863 100644
> --- a/gdb/target.h
> +++ b/gdb/target.h
> @@ -283,7 +283,9 @@ enum target_object
> /* Darwin dynamic linker info data. */
> TARGET_OBJECT_DARWIN_DYLD_INFO,
> /* OpenVMS Unwind Information Block. */
> - TARGET_OBJECT_OPENVMS_UIB
> + TARGET_OBJECT_OPENVMS_UIB,
> + /* Branch trace data, in XML format. */
> + TARGET_OBJECT_BTRACE
> /* Possible future objects: TARGET_OBJECT_FILE, ... */
> };
>
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 14/16] remote, btrace: add branch trace remote ops
2012-05-30 20:44 ` Jan Kratochvil
@ 2012-06-01 8:49 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-01 8:49 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1415 bytes --]
> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> owner@sourceware.org] On Behalf Of Jan Kratochvil
> Sent: Wednesday, May 30, 2012 10:44 PM
Thanks for your review!
[...]
> > + if (packet->support != PACKET_ENABLE)
> > + {
> > + errno = ENOSYS;
>
> errno is not used for intra-GDB/gdbserver communication. Everywhere.
I'll look into error handling.
> > + return NULL;
> > + }
> > +
> > + buf += xsnprintf (buf, endbuf - buf, "%s", packet->name); buf +=
> > + xsnprintf (buf, endbuf - buf, ":on:"); buf = write_ptid (buf,
> > + endbuf, ptid); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size,
> > + 0);
> > +
> > + switch (packet_ok (rs->buf, packet))
> > + {
> > + case PACKET_OK:
> > + tinfo = xzalloc (sizeof (*tinfo));
> > + if (tinfo)
>
> Remove, xzalloc can never fail.
Fixed.
> > + tinfo->ptid = ptid;
> > + else
> > + errno = ENOMEM;
> > + break;
> > + case PACKET_ERROR:
> > + {
> > + int pid = ptid_get_lwp (ptid);
> > + if (!pid)
> > + pid = ptid_get_pid (ptid);
> > +
> > + error (_("Couldn't enable btrace for %d: %s"),
> > + pid, rs->buf);
>
> Use target_pid_to_str. Everywhere.
Fixed.
[...]
> > + struct cleanup *cleanup = make_cleanup (xfree, xml);
>
> Empty line after declarations.
Fixed.
[...]
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 08/16] linux, btrace: perf_event based branch tracing
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (8 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 14/16] remote, btrace: add branch trace remote ops markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 04/16] thread, btrace: add generic branch trace support markus.t.metzger
` (8 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Implement branch tracing on Linux based on perf_event such taht it can be shared
between gdb and gdbserver.
The actual btrace target ops will be implemented on top.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/common/
* linux_btrace.h: New file
* linux_btrace.c: New file
gdb/
* Makefile.in: Add linux-btrace rules
gdb/gdbserver/
* Makefile.in: Add linux-btrace rules
---
gdb/Makefile.in | 7 +-
gdb/common/linux-btrace.c | 368 +++++++++++++++++++++++++++++++++++++++++++++
gdb/common/linux-btrace.h | 76 +++++++++
gdb/gdbserver/Makefile.in | 6 +-
4 files changed, 455 insertions(+), 2 deletions(-)
create mode 100644 gdb/common/linux-btrace.c
create mode 100644 gdb/common/linux-btrace.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 5fa7c12..b3fdd4f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -826,7 +826,8 @@ gnulib/import/extra/snippet/arg-nonnull.h gnulib/import/extra/snippet/c++defs.h
gnulib/import/extra/snippet/warn-on-use.h \
gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h
+common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
+common/linux-btrace.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -1930,6 +1931,10 @@ vec.o: ${srcdir}/common/vec.c
$(COMPILE) $(srcdir)/common/vec.c
$(POSTCOMPILE)
+linux-btrace.o: ${srcdir}/common/linux-btrace.c
+ $(COMPILE) $(srcdir)/common/linux-btrace.c
+ $(POSTCOMPILE)
+
#
# gdb/tui/ dependencies
#
diff --git a/gdb/common/linux-btrace.c b/gdb/common/linux-btrace.c
new file mode 100644
index 0000000..76bca75
--- /dev/null
+++ b/gdb/common/linux-btrace.c
@@ -0,0 +1,368 @@
+/* Linux-dependent part of branch trace support for GDB, and GDBserver.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#include "linux-btrace.h"
+#include "common-utils.h"
+#include <errno.h>
+
+#if HAVE_LINUX_PERF_EVENT_H
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+
+typedef unsigned char byte;
+
+/* A branch trace record in perf_event. */
+struct perf_event_bts
+{
+ unsigned long long from;
+ unsigned long long to;
+};
+
+/* A perf_event branch trace sample. */
+struct perf_event_sample
+{
+ struct perf_event_header header;
+ struct perf_event_bts bts;
+};
+
+static inline volatile struct perf_event_mmap_page *
+perf_event_header (struct btrace_target_info* tinfo)
+{
+ return tinfo->buffer;
+}
+
+static inline size_t
+perf_event_mmap_size (const struct btrace_target_info *tinfo)
+{
+ /* The branch trace buffer is preceded by a configuration page. */
+ return ((tinfo->size + 1) * PAGE_SIZE);
+}
+
+static inline size_t
+perf_event_buffer_size (struct btrace_target_info* tinfo)
+{
+ return (tinfo->size * PAGE_SIZE);
+}
+
+static inline const byte *
+perf_event_buffer_begin (struct btrace_target_info* tinfo)
+{
+ return ((const byte *) tinfo->buffer) + PAGE_SIZE;
+}
+
+static inline const byte *
+perf_event_buffer_end (struct btrace_target_info* tinfo)
+{
+ return perf_event_buffer_begin (tinfo) + perf_event_buffer_size (tinfo);
+}
+
+static inline int
+perf_event_skip_record (struct btrace_target_info* tinfo,
+ const struct perf_event_bts *bts)
+{
+ if (tinfo->ptr_bits)
+ {
+ int shift = tinfo->ptr_bits - 1;
+
+ /* Branch trace records branches from kernel space to user space. */
+ if (bts->from & (1ull << shift))
+ return 1;
+
+ /* Branch trace records branches from user space to kernel space. */
+ if (bts->to & (1ull << shift))
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int
+perf_event_check_sample (const struct perf_event_sample *sample)
+{
+ if (sample->header.type != PERF_RECORD_SAMPLE)
+ return EINVAL;
+
+ if (sample->header.size != sizeof (*sample))
+ return EINVAL;
+
+ return 0;
+}
+
+/* Branch trace is collected in a circular buffer [begin; end) as pairs of from
+ and to addresses (plus some header).
+
+ Start points into that buffer at the next sample position.
+ We read the collected samples backwards from start.
+
+ While reading the samples, we convert the information into a list of blocks.
+ For two adjacent samples s1 and s2, we form a block b such that b.begin =
+ s1.to and b.end = s2.from.
+
+ In case the buffer overflows during sampling, samples may be split. */
+static int
+perf_event_read_bts (struct btrace_target_info* tinfo,
+ const byte *begin, const byte *end, const byte *start,
+ int (*fun) (struct linux_btrace_block *, void *),
+ void *arg)
+{
+ struct perf_event_sample sample;
+ int read = 0, size = (end - begin), errcode = 0;
+ struct linux_btrace_block block = { 0, 0 };
+
+ if (start < begin)
+ return EINVAL;
+
+ if (end < start)
+ return EINVAL;
+
+ /* The buffer may contain a partial record as its last entry (i.e. when the
+ buffer size is not a mulitple of the sample size). */
+ read = sizeof (sample) - 1;
+
+ for (; read < size; read += sizeof (sample))
+ {
+ const struct perf_event_sample *psample;
+
+ /* Find the next perf_event sample. */
+ start -= sizeof (sample);
+ if (begin <= start)
+ psample = (const struct perf_event_sample *) start;
+ else
+ {
+ int missing = (begin - start);
+ start = (end - missing);
+
+ if (missing == sizeof (sample))
+ psample = (const struct perf_event_sample *) start;
+ else
+ {
+ byte *stack = (byte *) &sample;
+
+ memcpy (stack, start, missing);
+ memcpy (stack + missing, begin, sizeof (sample) - missing);
+
+ psample = &sample;
+ }
+ }
+
+ errcode = perf_event_check_sample (psample);
+ if (errcode)
+ break;
+
+ if (perf_event_skip_record (tinfo, &(psample->bts)))
+ continue;
+
+ /* We found a valid sample, so we can complete the current block. */
+ block.begin = psample->bts.to;
+
+ errcode = (*fun) (&block, arg);
+ if (errcode)
+ break;
+
+ /* Start the next block. */
+ block.end = psample->bts.from;
+ }
+
+ return errcode;
+}
+
+int
+linux_supports_btrace (void)
+{
+ return 1;
+}
+
+int
+linux_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+ volatile struct perf_event_mmap_page *header = perf_event_header (tinfo);
+ if (!header)
+ return 0;
+
+ return (header->data_head != tinfo->data_head);
+}
+
+struct btrace_target_info *
+linux_enable_btrace (ptid_t ptid)
+{
+ struct btrace_target_info *tinfo;
+ int pid;
+
+ tinfo = xzalloc (sizeof (*tinfo));
+ if (!tinfo)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ tinfo->attr.size = sizeof (tinfo->attr);
+
+ tinfo->attr.type = PERF_TYPE_HARDWARE;
+ tinfo->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
+ tinfo->attr.sample_period = 1;
+
+ /* We sample from and to address. */
+ tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
+
+ tinfo->attr.exclude_kernel = 1;
+ tinfo->attr.exclude_hv = 1;
+ tinfo->attr.exclude_idle = 1;
+
+ tinfo->ptr_bits = 0;
+
+ pid = ptid_get_lwp (ptid);
+ if (!pid)
+ pid = ptid_get_pid (ptid);
+
+ tinfo->file = syscall (SYS_perf_event_open, &(tinfo->attr), pid, -1, -1, 0);
+ if (tinfo->file < 0)
+ goto err;
+
+ /* We hard-code the trace buffer size.
+ At some later time, we should make this configurable. */
+ tinfo->size = 1;
+ tinfo->buffer = mmap (NULL, perf_event_mmap_size (tinfo),
+ PROT_READ, MAP_SHARED, tinfo->file, 0);
+ if (tinfo->buffer == MAP_FAILED)
+ goto err_file;
+
+ return tinfo;
+
+err_file:
+ close (tinfo->file);
+
+err:
+ xfree (tinfo);
+ return NULL;
+}
+
+int
+linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+ int errcode;
+
+ if (!tinfo)
+ return -EINVAL;
+
+ errcode = munmap (tinfo->buffer, perf_event_mmap_size (tinfo));
+ if (errcode)
+ return errno;
+
+ close (tinfo->file);
+ xfree (tinfo);
+
+ return 0;
+}
+
+int
+linux_read_btrace (struct btrace_target_info *tinfo,
+ int (*fun) (struct linux_btrace_block *, void *),
+ void *arg)
+{
+ volatile struct perf_event_mmap_page *header;
+ const byte *begin, *end, *start;
+ unsigned long data_head, retries = 5;
+ size_t buffer_size;
+ int errcode = 0;
+
+ if (!tinfo)
+ return EINVAL;
+
+ header = perf_event_header (tinfo);
+ if (!header)
+ return ENOSYS;
+
+ buffer_size = perf_event_buffer_size (tinfo);
+
+ /* We may need to retry reading the trace. See below. */
+ while (retries--)
+ {
+ data_head = header->data_head;
+
+ /* If there new trace, let's read it. */
+ if (data_head != tinfo->data_head)
+ {
+ /* Data_head keeps growing; the buffer itself is circular. */
+ begin = perf_event_buffer_begin (tinfo);
+ start = begin + (data_head % buffer_size);
+
+ if (data_head <= buffer_size)
+ end = start;
+ else
+ end = perf_event_buffer_end (tinfo);
+
+ errcode = perf_event_read_bts (tinfo, begin, end, start, fun, arg);
+ }
+
+ /* The stopping thread notifies its ptracer before it is scheduled out.
+ On multi-core systems, the debugger might therefore run while the
+ kernel might be writing the last branch trace records.
+
+ Let's check whether the data head moved while we read the trace. */
+ if (data_head == header->data_head)
+ break;
+ }
+
+ tinfo->data_head = data_head;
+
+ return errcode;
+}
+
+#else /* HAVE_LINUX_PERF_EVENT_H */
+
+int
+linux_supports_btrace (void)
+{
+ return 0;
+}
+
+int
+linux_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+ return 0;
+}
+
+struct btrace_target_info *
+linux_enable_btrace (ptid_t ptid)
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+int
+linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+ return ENOSYS;
+}
+
+int
+linux_read_btrace (struct btrace_target_info *tinfo,
+ int (*fun) (struct linux_btrace_block *, void *),
+ void *arg)
+{
+ return ENOSYS;
+}
+
+#endif /* HAVE_LINUX_PERF_EVENT_H */
diff --git a/gdb/common/linux-btrace.h b/gdb/common/linux-btrace.h
new file mode 100644
index 0000000..22f435a
--- /dev/null
+++ b/gdb/common/linux-btrace.h
@@ -0,0 +1,76 @@
+/* Linux-dependent part of branch trace support for GDB, and GDBserver.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LINUX_BTRACE_H
+#define LINUX_BTRACE_H
+
+#include "config.h"
+#include "ptid.h"
+#include <stddef.h>
+
+#if HAVE_LINUX_PERF_EVENT_H
+# include <linux/perf_event.h>
+#endif
+
+/* A branch trace block on linux.
+ GDB and GDBserver don't agree on the definition of CORE_ADDR. In order to
+ allow sharing the perf_event access code, we stick to unsigned long long;
+ that's also what perf_event delivers. */
+struct linux_btrace_block
+{
+ unsigned long long begin;
+ unsigned long long end;
+};
+
+/* Branch trace target information per thread. */
+struct btrace_target_info
+{
+#if HAVE_LINUX_PERF_EVENT_H
+ /* The Linux perf_event configuration for collecting the branch trace. */
+ struct perf_event_attr attr;
+
+ /* The mmap configuration mapping the branch trace perf_event buffer.
+
+ file .. the file descriptor
+ buffer .. the mmapped memory buffer
+ size .. the buffer's size in pages without the configuration page
+ data_head .. the data head from the last read */
+ int file;
+ void *buffer;
+ size_t size;
+ unsigned long data_head;
+#endif /* HAVE_LINUX_PERF_EVENT_H */
+
+ /* The size of a pointer in bits for this thread.
+ The information is used to identify kernel addresses in order to skip
+ records from/to kernel space. */
+ int ptr_bits;
+};
+
+extern int linux_supports_btrace (void);
+extern struct btrace_target_info *linux_enable_btrace (ptid_t);
+extern int linux_disable_btrace (struct btrace_target_info *);
+extern int linux_btrace_has_changed (struct btrace_target_info *);
+extern int linux_read_btrace (struct btrace_target_info *,
+ int (*) (struct linux_btrace_block *, void *),
+ void *);
+
+#endif /* LINUX_BTRACE_H */
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 50786d5..1f256de 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -139,7 +139,7 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
$(srcdir)/common/vec.c \
$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
- $(srcdir)/common/buffer.c
+ $(srcdir)/common/buffer.c $(srcdir)/common/linux-btrace.c
DEPFILES = @GDBSERVER_DEPFILES@
@@ -408,6 +408,7 @@ signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
ptid_h = $(srcdir)/../common/ptid.h
ax_h = $(srcdir)/ax.h
agent_h = $(srcdir)/../common/agent.h
+linux_btrace_h = $(srcdir)/../common/linux-btrace.h
linux_osdata_h = $(srcdir)/../common/linux-osdata.h
vec_h = $(srcdir)/../common/vec.h
# Since everything must include server.h, we make that depend on
@@ -514,6 +515,9 @@ buffer.o: ../common/buffer.c $(server_h)
agent.o: ../common/agent.c $(server_h) $(agent_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+linux-btrace.o: ../common/linux-btrace.c $(linux_btrace_h) $(server_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
# We build vasprintf with -DHAVE_CONFIG_H because we want that unit to
# include our config.h file. Otherwise, some system headers do not get
# included, and the compiler emits a warning about implicitly defined
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 08/16] linux, btrace: perf_event based branch tracing
2012-05-23 11:25 ` [PATCH 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
@ 2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:43 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:23 +0200, markus.t.metzger@intel.com wrote:
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -826,7 +826,8 @@ gnulib/import/extra/snippet/arg-nonnull.h gnulib/import/extra/snippet/c++defs.h
> gnulib/import/extra/snippet/warn-on-use.h \
> gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
> common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
> -common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h
> +common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
> +common/linux-btrace.h
>
> # Header files that already have srcdir in them, or which are in objdir.
>
> @@ -1930,6 +1931,10 @@ vec.o: ${srcdir}/common/vec.c
> $(COMPILE) $(srcdir)/common/vec.c
> $(POSTCOMPILE)
>
> +linux-btrace.o: ${srcdir}/common/linux-btrace.c
> + $(COMPILE) $(srcdir)/common/linux-btrace.c
> + $(POSTCOMPILE)
> +
> #
> # gdb/tui/ dependencies
> #
> diff --git a/gdb/common/linux-btrace.c b/gdb/common/linux-btrace.c
> new file mode 100644
> index 0000000..76bca75
> --- /dev/null
> +++ b/gdb/common/linux-btrace.c
> @@ -0,0 +1,368 @@
> +/* Linux-dependent part of branch trace support for GDB, and GDBserver.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#include "linux-btrace.h"
> +#include "common-utils.h"
> +#include <errno.h>
> +
> +#if HAVE_LINUX_PERF_EVENT_H
> +
> +#include <string.h>
> +#include <unistd.h>
> +#include <sys/syscall.h>
> +#include <sys/mman.h>
> +#include <sys/user.h>
> +
> +typedef unsigned char byte;
Two spaces. There already exists gdb_byte.
> +
> +/* A branch trace record in perf_event. */
> +struct perf_event_bts
> +{
> + unsigned long long from;
> + unsigned long long to;
'long long' is forbidden in GDB, it will produce ARI script warnings.
uint64_t is OK.
> +};
> +
> +/* A perf_event branch trace sample. */
> +struct perf_event_sample
> +{
> + struct perf_event_header header;
> + struct perf_event_bts bts;
GNU Coding Style forbids such alignment, just use:
struct perf_event_header header;
struct perf_event_bts bts;
> +};
> +
> +static inline volatile struct perf_event_mmap_page *
> +perf_event_header (struct btrace_target_info* tinfo)
> +{
> + return tinfo->buffer;
> +}
> +
> +static inline size_t
> +perf_event_mmap_size (const struct btrace_target_info *tinfo)
> +{
> + /* The branch trace buffer is preceded by a configuration page. */
> + return ((tinfo->size + 1) * PAGE_SIZE);
Excessive out parentheses. Multiple times.
> +}
> +
> +static inline size_t
> +perf_event_buffer_size (struct btrace_target_info* tinfo)
> +{
> + return (tinfo->size * PAGE_SIZE);
> +}
> +
> +static inline const byte *
> +perf_event_buffer_begin (struct btrace_target_info* tinfo)
> +{
> + return ((const byte *) tinfo->buffer) + PAGE_SIZE;
> +}
> +
> +static inline const byte *
> +perf_event_buffer_end (struct btrace_target_info* tinfo)
> +{
> + return perf_event_buffer_begin (tinfo) + perf_event_buffer_size (tinfo);
> +}
> +
> +static inline int
> +perf_event_skip_record (struct btrace_target_info* tinfo,
Formatting:
struct btrace_target_info *tinfo,
> + const struct perf_event_bts *bts)
> +{
> + if (tinfo->ptr_bits)
> + {
> + int shift = tinfo->ptr_bits - 1;
> +
> + /* Branch trace records branches from kernel space to user space. */
> + if (bts->from & (1ull << shift))
long long again.
> + return 1;
> +
> + /* Branch trace records branches from user space to kernel space. */
> + if (bts->to & (1ull << shift))
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static inline int
> +perf_event_check_sample (const struct perf_event_sample *sample)
> +{
> + if (sample->header.type != PERF_RECORD_SAMPLE)
> + return EINVAL;
Here everywhere some error with description would be easier than the error
codes passing in the callers.
> +
> + if (sample->header.size != sizeof (*sample))
> + return EINVAL;
> +
> + return 0;
> +}
> +
> +/* Branch trace is collected in a circular buffer [begin; end) as pairs of from
> + and to addresses (plus some header).
> +
> + Start points into that buffer at the next sample position.
> + We read the collected samples backwards from start.
> +
> + While reading the samples, we convert the information into a list of blocks.
> + For two adjacent samples s1 and s2, we form a block b such that b.begin =
> + s1.to and b.end = s2.from.
> +
> + In case the buffer overflows during sampling, samples may be split. */
Empty line.
> +static int
> +perf_event_read_bts (struct btrace_target_info* tinfo,
> + const byte *begin, const byte *end, const byte *start,
> + int (*fun) (struct linux_btrace_block *, void *),
> + void *arg)
> +{
> + struct perf_event_sample sample;
> + int read = 0, size = (end - begin), errcode = 0;
> + struct linux_btrace_block block = { 0, 0 };
> +
> + if (start < begin)
> + return EINVAL;
> +
> + if (end < start)
> + return EINVAL;
> +
> + /* The buffer may contain a partial record as its last entry (i.e. when the
> + buffer size is not a mulitple of the sample size). */
> + read = sizeof (sample) - 1;
> +
> + for (; read < size; read += sizeof (sample))
> + {
> + const struct perf_event_sample *psample;
> +
> + /* Find the next perf_event sample. */
> + start -= sizeof (sample);
> + if (begin <= start)
> + psample = (const struct perf_event_sample *) start;
> + else
> + {
> + int missing = (begin - start);
Empty line.
> + start = (end - missing);
> +
> + if (missing == sizeof (sample))
> + psample = (const struct perf_event_sample *) start;
> + else
> + {
> + byte *stack = (byte *) &sample;
> +
> + memcpy (stack, start, missing);
> + memcpy (stack + missing, begin, sizeof (sample) - missing);
> +
> + psample = &sample;
> + }
> + }
> +
> + errcode = perf_event_check_sample (psample);
> + if (errcode)
> + break;
> +
> + if (perf_event_skip_record (tinfo, &(psample->bts)))
> + continue;
> +
> + /* We found a valid sample, so we can complete the current block. */
> + block.begin = psample->bts.to;
> +
> + errcode = (*fun) (&block, arg);
> + if (errcode)
> + break;
> +
> + /* Start the next block. */
> + block.end = psample->bts.from;
> + }
> +
> + return errcode;
> +}
> +
> +int
> +linux_supports_btrace (void)
> +{
> + return 1;
> +}
> +
> +int
> +linux_btrace_has_changed (struct btrace_target_info *tinfo)
> +{
> + volatile struct perf_event_mmap_page *header = perf_event_header (tinfo);
Empty line.
> + if (!header)
> + return 0;
> +
> + return (header->data_head != tinfo->data_head);
> +}
> +
> +struct btrace_target_info *
> +linux_enable_btrace (ptid_t ptid)
> +{
> + struct btrace_target_info *tinfo;
> + int pid;
> +
> + tinfo = xzalloc (sizeof (*tinfo));
> + if (!tinfo)
Remove, xzalloc can never return NULL.
> + {
> + errno = ENOMEM;
> + return NULL;
> + }
> +
> + tinfo->attr.size = sizeof (tinfo->attr);
> +
> + tinfo->attr.type = PERF_TYPE_HARDWARE;
> + tinfo->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
> + tinfo->attr.sample_period = 1;
> +
> + /* We sample from and to address. */
> + tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
> +
> + tinfo->attr.exclude_kernel = 1;
> + tinfo->attr.exclude_hv = 1;
> + tinfo->attr.exclude_idle = 1;
> +
> + tinfo->ptr_bits = 0;
> +
> + pid = ptid_get_lwp (ptid);
> + if (!pid)
> + pid = ptid_get_pid (ptid);
> +
> + tinfo->file = syscall (SYS_perf_event_open, &(tinfo->attr), pid, -1, -1, 0);
> + if (tinfo->file < 0)
> + goto err;
> +
> + /* We hard-code the trace buffer size.
> + At some later time, we should make this configurable. */
> + tinfo->size = 1;
> + tinfo->buffer = mmap (NULL, perf_event_mmap_size (tinfo),
> + PROT_READ, MAP_SHARED, tinfo->file, 0);
> + if (tinfo->buffer == MAP_FAILED)
> + goto err_file;
> +
> + return tinfo;
> +
> +err_file:
> + close (tinfo->file);
> +
> +err:
> + xfree (tinfo);
> + return NULL;
> +}
> +
> +int
> +linux_disable_btrace (struct btrace_target_info *tinfo)
> +{
> + int errcode;
> +
> + if (!tinfo)
> + return -EINVAL;
> +
> + errcode = munmap (tinfo->buffer, perf_event_mmap_size (tinfo));
> + if (errcode)
> + return errno;
> +
> + close (tinfo->file);
> + xfree (tinfo);
> +
> + return 0;
> +}
> +
> +int
> +linux_read_btrace (struct btrace_target_info *tinfo,
> + int (*fun) (struct linux_btrace_block *, void *),
> + void *arg)
> +{
> + volatile struct perf_event_mmap_page *header;
> + const byte *begin, *end, *start;
> + unsigned long data_head, retries = 5;
> + size_t buffer_size;
> + int errcode = 0;
> +
> + if (!tinfo)
> + return EINVAL;
> +
> + header = perf_event_header (tinfo);
> + if (!header)
> + return ENOSYS;
> +
> + buffer_size = perf_event_buffer_size (tinfo);
> +
> + /* We may need to retry reading the trace. See below. */
> + while (retries--)
> + {
> + data_head = header->data_head;
> +
> + /* If there new trace, let's read it. */
> + if (data_head != tinfo->data_head)
> + {
> + /* Data_head keeps growing; the buffer itself is circular. */
> + begin = perf_event_buffer_begin (tinfo);
> + start = begin + (data_head % buffer_size);
> +
> + if (data_head <= buffer_size)
> + end = start;
> + else
> + end = perf_event_buffer_end (tinfo);
> +
> + errcode = perf_event_read_bts (tinfo, begin, end, start, fun, arg);
> + }
> +
> + /* The stopping thread notifies its ptracer before it is scheduled out.
> + On multi-core systems, the debugger might therefore run while the
> + kernel might be writing the last branch trace records.
> +
> + Let's check whether the data head moved while we read the trace. */
> + if (data_head == header->data_head)
> + break;
> + }
> +
> + tinfo->data_head = data_head;
> +
> + return errcode;
> +}
> +
> +#else /* HAVE_LINUX_PERF_EVENT_H */
GNU Coding Standards say here should be:
#else /* !HAVE_LINUX_PERF_EVENT_H */
(they say "not" but GDB uses !)
> +
> +int
> +linux_supports_btrace (void)
> +{
> + return 0;
> +}
> +
> +int
> +linux_btrace_has_changed (struct btrace_target_info *tinfo)
> +{
> + return 0;
> +}
> +
> +struct btrace_target_info *
> +linux_enable_btrace (ptid_t ptid)
> +{
> + errno = ENOSYS;
> + return NULL;
> +}
> +
> +int
> +linux_disable_btrace (struct btrace_target_info *tinfo)
> +{
> + return ENOSYS;
> +}
> +
> +int
> +linux_read_btrace (struct btrace_target_info *tinfo,
> + int (*fun) (struct linux_btrace_block *, void *),
> + void *arg)
> +{
> + return ENOSYS;
> +}
> +
> +#endif /* HAVE_LINUX_PERF_EVENT_H */
And !HAVE_LINUX_PERF_EVENT_H again.
> diff --git a/gdb/common/linux-btrace.h b/gdb/common/linux-btrace.h
> new file mode 100644
> index 0000000..22f435a
> --- /dev/null
> +++ b/gdb/common/linux-btrace.h
> @@ -0,0 +1,76 @@
> +/* Linux-dependent part of branch trace support for GDB, and GDBserver.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#ifndef LINUX_BTRACE_H
> +#define LINUX_BTRACE_H
> +
> +#include "config.h"
> +#include "ptid.h"
> +#include <stddef.h>
> +
> +#if HAVE_LINUX_PERF_EVENT_H
> +# include <linux/perf_event.h>
> +#endif
> +
> +/* A branch trace block on linux.
> + GDB and GDBserver don't agree on the definition of CORE_ADDR. In order to
> + allow sharing the perf_event access code, we stick to unsigned long long;
> + that's also what perf_event delivers. */
> +struct linux_btrace_block
> +{
> + unsigned long long begin;
> + unsigned long long end;
> +};
> +
> +/* Branch trace target information per thread. */
> +struct btrace_target_info
> +{
> +#if HAVE_LINUX_PERF_EVENT_H
> + /* The Linux perf_event configuration for collecting the branch trace. */
> + struct perf_event_attr attr;
> +
> + /* The mmap configuration mapping the branch trace perf_event buffer.
> +
> + file .. the file descriptor
> + buffer .. the mmapped memory buffer
> + size .. the buffer's size in pages without the configuration page
> + data_head .. the data head from the last read */
> + int file;
> + void *buffer;
> + size_t size;
GNU Coding Style - no indentation of the names.
> + unsigned long data_head;
> +#endif /* HAVE_LINUX_PERF_EVENT_H */
> +
> + /* The size of a pointer in bits for this thread.
> + The information is used to identify kernel addresses in order to skip
> + records from/to kernel space. */
> + int ptr_bits;
> +};
> +
> +extern int linux_supports_btrace (void);
> +extern struct btrace_target_info *linux_enable_btrace (ptid_t);
> +extern int linux_disable_btrace (struct btrace_target_info *);
> +extern int linux_btrace_has_changed (struct btrace_target_info *);
> +extern int linux_read_btrace (struct btrace_target_info *,
> + int (*) (struct linux_btrace_block *, void *),
> + void *);
Tabs, not spaces, everywhere.
> +
> +#endif /* LINUX_BTRACE_H */
> diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
> index 50786d5..1f256de 100644
> --- a/gdb/gdbserver/Makefile.in
> +++ b/gdb/gdbserver/Makefile.in
> @@ -139,7 +139,7 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
> $(srcdir)/common/vec.c \
> $(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
> $(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
> - $(srcdir)/common/buffer.c
> + $(srcdir)/common/buffer.c $(srcdir)/common/linux-btrace.c
>
> DEPFILES = @GDBSERVER_DEPFILES@
>
> @@ -408,6 +408,7 @@ signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
> ptid_h = $(srcdir)/../common/ptid.h
> ax_h = $(srcdir)/ax.h
> agent_h = $(srcdir)/../common/agent.h
> +linux_btrace_h = $(srcdir)/../common/linux-btrace.h
> linux_osdata_h = $(srcdir)/../common/linux-osdata.h
> vec_h = $(srcdir)/../common/vec.h
> # Since everything must include server.h, we make that depend on
> @@ -514,6 +515,9 @@ buffer.o: ../common/buffer.c $(server_h)
> agent.o: ../common/agent.c $(server_h) $(agent_h)
> $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
>
> +linux-btrace.o: ../common/linux-btrace.c $(linux_btrace_h) $(server_h)
> + $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
> +
> # We build vasprintf with -DHAVE_CONFIG_H because we want that unit to
> # include our config.h file. Otherwise, some system headers do not get
> # included, and the compiler emits a warning about implicitly defined
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 08/16] linux, btrace: perf_event based branch tracing
2012-05-30 20:43 ` Jan Kratochvil
@ 2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:34 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 7054 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:43 PM
> To: Metzger, Markus T
Thanks for your review!
[...]
> > +typedef unsigned char byte;
>
> Two spaces. There already exists gdb_byte.
Gdb_byte is not available in gdb/common/.
Is it OK to put the typedef into gdb/common/common-utils.h?
> > +
> > +/* A branch trace record in perf_event. */ struct perf_event_bts {
> > + unsigned long long from;
> > + unsigned long long to;
>
> 'long long' is forbidden in GDB, it will produce ARI script warnings.
> uint64_t is OK.
Fixed.
Could we put this ARI script and maybe some style checker scripts into the
gdb source tree?
> > +};
> > +
> > +/* A perf_event branch trace sample. */ struct perf_event_sample {
> > + struct perf_event_header header;
> > + struct perf_event_bts bts;
>
> GNU Coding Style forbids such alignment, just use:
> struct perf_event_header header;
> struct perf_event_bts bts;
Fixed.
> > +};
> > +
> > +static inline volatile struct perf_event_mmap_page *
> > +perf_event_header (struct btrace_target_info* tinfo) {
> > + return tinfo->buffer;
> > +}
> > +
> > +static inline size_t
> > +perf_event_mmap_size (const struct btrace_target_info *tinfo) {
> > + /* The branch trace buffer is preceded by a configuration page. */
> > + return ((tinfo->size + 1) * PAGE_SIZE);
>
> Excessive out parentheses. Multiple times.
Fixed.
> > +}
> > +
> > +static inline size_t
> > +perf_event_buffer_size (struct btrace_target_info* tinfo) {
> > + return (tinfo->size * PAGE_SIZE);
> > +}
> > +
> > +static inline const byte *
> > +perf_event_buffer_begin (struct btrace_target_info* tinfo) {
> > + return ((const byte *) tinfo->buffer) + PAGE_SIZE; }
> > +
> > +static inline const byte *
> > +perf_event_buffer_end (struct btrace_target_info* tinfo) {
> > + return perf_event_buffer_begin (tinfo) + perf_event_buffer_size
> > +(tinfo); }
> > +
> > +static inline int
> > +perf_event_skip_record (struct btrace_target_info* tinfo,
>
> Formatting:
> struct btrace_target_info *tinfo,
Fixed.
> > + const struct perf_event_bts *bts) {
> > + if (tinfo->ptr_bits)
> > + {
> > + int shift = tinfo->ptr_bits - 1;
> > +
> > + /* Branch trace records branches from kernel space to user space.
> > */
> > + if (bts->from & (1ull << shift))
>
> long long again.
Replaced with explicit type cast.
> > + return 1;
> > +
> > + /* Branch trace records branches from user space to kernel space.
> > */
> > + if (bts->to & (1ull << shift))
> > + return 1;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static inline int
> > +perf_event_check_sample (const struct perf_event_sample *sample) {
> > + if (sample->header.type != PERF_RECORD_SAMPLE)
> > + return EINVAL;
>
> Here everywhere some error with description would be easier than the error
> codes passing in the callers.
I'll fix this once it is clear whether this will also work with gdbserver.
> > +
> > + if (sample->header.size != sizeof (*sample))
> > + return EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +/* Branch trace is collected in a circular buffer [begin; end) as pairs
> > of from
> > + and to addresses (plus some header).
> > +
> > + Start points into that buffer at the next sample position.
> > + We read the collected samples backwards from start.
> > +
> > + While reading the samples, we convert the information into a list of
> blocks.
> > + For two adjacent samples s1 and s2, we form a block b such that
> > b.begin
> =
> > + s1.to and b.end = s2.from.
> > +
> > + In case the buffer overflows during sampling, samples may be
> > + split. */
>
> Empty line.
Fixed.
> > +static int
> > +perf_event_read_bts (struct btrace_target_info* tinfo,
> > + const byte *begin, const byte *end, const byte
> > *start,
> > + int (*fun) (struct linux_btrace_block *, void *),
> > + void *arg)
> > +{
> > + struct perf_event_sample sample;
> > + int read = 0, size = (end - begin), errcode = 0;
> > + struct linux_btrace_block block = { 0, 0 };
> > +
> > + if (start < begin)
> > + return EINVAL;
> > +
> > + if (end < start)
> > + return EINVAL;
> > +
> > + /* The buffer may contain a partial record as its last entry (i.e. when
> > the
> > + buffer size is not a mulitple of the sample size). */ read =
> > + sizeof (sample) - 1;
> > +
> > + for (; read < size; read += sizeof (sample))
> > + {
> > + const struct perf_event_sample *psample;
> > +
> > + /* Find the next perf_event sample. */
> > + start -= sizeof (sample);
> > + if (begin <= start)
> > + psample = (const struct perf_event_sample *) start;
> > + else
> > + {
> > + int missing = (begin - start);
> Empty line.
Fixed.
[...]
> > +int
> > +linux_btrace_has_changed (struct btrace_target_info *tinfo) {
> > + volatile struct perf_event_mmap_page *header = perf_event_header
> > +(tinfo);
> Empty line.
Fixed.
> > + if (!header)
> > + return 0;
> > +
> > + return (header->data_head != tinfo->data_head); }
> > +
> > +struct btrace_target_info *
> > +linux_enable_btrace (ptid_t ptid)
> > +{
> > + struct btrace_target_info *tinfo;
> > + int pid;
> > +
> > + tinfo = xzalloc (sizeof (*tinfo));
> > + if (!tinfo)
>
> Remove, xzalloc can never return NULL.
Fixed.
[...]
> > +#else /* HAVE_LINUX_PERF_EVENT_H */
>
> GNU Coding Standards say here should be:
> #else /* !HAVE_LINUX_PERF_EVENT_H */
> (they say "not" but GDB uses !)
Fixed.
[...]
> > +#endif /* HAVE_LINUX_PERF_EVENT_H */
>
> And !HAVE_LINUX_PERF_EVENT_H again.
Fixed.
[...]
> > + /* The mmap configuration mapping the branch trace perf_event buffer.
> > +
> > + file .. the file descriptor
> > + buffer .. the mmapped memory buffer
> > + size .. the buffer's size in pages without the configuration
> > page
> > + data_head .. the data head from the last read */
> > + int file;
> > + void *buffer;
> > + size_t size;
>
> GNU Coding Style - no indentation of the names.
Fixed.
> > + unsigned long data_head;
> > +#endif /* HAVE_LINUX_PERF_EVENT_H */
> > +
> > + /* The size of a pointer in bits for this thread.
> > + The information is used to identify kernel addresses in order to
> > skip
> > + records from/to kernel space. */
> > + int ptr_bits;
> > +};
> > +
> > +extern int linux_supports_btrace (void); extern struct
> > +btrace_target_info *linux_enable_btrace (ptid_t); extern int
> > +linux_disable_btrace (struct btrace_target_info *); extern int
> > +linux_btrace_has_changed (struct btrace_target_info *); extern int
> > +linux_read_btrace (struct btrace_target_info *,
> > + int (*) (struct linux_btrace_block *, void
> > *),
> > + void *);
>
> Tabs, not spaces, everywhere.
Fixed.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 04/16] thread, btrace: add generic branch trace support
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (9 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:42 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 05/16] cli, btrace: add btrace cli markus.t.metzger
` (7 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add branch trace information to struct thread_info to hold the branch trace
information for that thread.
Add functions to enable/disable, and get a thread's branch trace, as well as
for iterating over it.
Iteration uses a per-thread iterator stored in the thread_info's branch trace
information.
Iterators are reset implicitly when a thread's branch trace changes.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* target.h: Add include
(struct target_ops): Add btrace ops
(target_supports_btrace): New macro
(target_enable_btrace): New macro
(target_disable_btrace): New macro
(target_read_btrace): New macro
(target_btrace_has_changed): New macro
* target.c (update_current_target): Initialize btrace ops
* btrace.h: New file
* btrace.c: New file
* Makefile.in: Add btrace.c
* gdbthread.h: Add include
(struct thread_info): Add btrace field
* thread.c: Add include
(free_thread): Call disable_btrace
* infcmd.c: Add include
(detach_command): Call disconnect_btrace
---
gdb/Makefile.in | 4 +-
gdb/btrace.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/btrace.h | 89 +++++++++++++++++++
gdb/gdbthread.h | 4 +
gdb/infcmd.c | 2 +
gdb/target.c | 20 +++++
gdb/target.h | 32 +++++++
gdb/thread.c | 3 +
8 files changed, 406 insertions(+), 2 deletions(-)
create mode 100644 gdb/btrace.c
create mode 100644 gdb/btrace.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 4368f07..5fa7c12 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -744,7 +744,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
annotate.c common/signals.c copying.c dfp.c gdb.c inf-child.c \
regset.c sol-thread.c windows-termcap.c \
common/common-utils.c common/xml-utils.c \
- common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c
+ common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c btrace.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@@ -915,7 +915,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
jit.o progspace.o skip.o probe.o \
- common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o
+ common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o btrace.o
TSOBS = inflow.o
diff --git a/gdb/btrace.c b/gdb/btrace.c
new file mode 100644
index 0000000..e66a986
--- /dev/null
+++ b/gdb/btrace.c
@@ -0,0 +1,254 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#include "btrace.h"
+#include "gdbthread.h"
+#include "frame.h"
+#include "exceptions.h"
+
+#include <errno.h>
+
+#if !defined(EALREADY)
+/* Remap EALREADY for systems that do not define it, e.g. mingw. */
+# define EALREADY EBUSY
+#endif
+
+int
+enable_btrace (struct thread_info *tinfo)
+{
+ if (!tinfo)
+ return EINVAL;
+
+ if (tinfo->btrace.target)
+ return EALREADY;
+
+ tinfo->btrace.target = target_enable_btrace (tinfo->ptid);
+ if (!tinfo->btrace.target)
+ return (errno ? errno : ENOSYS);
+
+ return 0;
+}
+
+int
+disable_btrace (struct thread_info *tinfo)
+{
+ struct btrace_thread_info *btinfo;
+ int errcode = 0;
+
+ if (!tinfo)
+ return EINVAL;
+
+ btinfo = &tinfo->btrace;
+
+ if (!btinfo->target)
+ return EALREADY;
+
+ /* When killing the inferior, we may have lost our target before we disable
+ branch tracing. */
+ if (target_supports_btrace ())
+ errcode = target_disable_btrace (btinfo->target);
+
+ if (!errcode)
+ {
+ VEC_free (btrace_block_s, btinfo->btrace);
+ btinfo->btrace = NULL;
+ btinfo->target = NULL;
+ }
+
+ return errcode;
+}
+
+static int
+do_disconnect_btrace (struct thread_info *tinfo, void *ignored)
+{
+ if (tinfo->btrace.target)
+ {
+ volatile struct gdb_exception error;
+
+ TRY_CATCH (error, RETURN_MASK_ERROR)
+ {
+ /* Switching threads makes it easier for targets like kgdb, where we
+ need to switch cpus, as well. */
+ switch_to_thread (tinfo->ptid);
+
+ disable_btrace (tinfo);
+ }
+ }
+
+ return 0;
+}
+
+void
+disconnect_btrace (void)
+{
+ ptid_t ptid = inferior_ptid;
+
+ iterate_over_threads (do_disconnect_btrace, NULL);
+
+ switch_to_thread (ptid);
+}
+
+static struct btrace_thread_info *
+get_btinfo (struct thread_info *tinfo)
+{
+ if (!tinfo)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ return &tinfo->btrace;
+}
+
+static int
+update_btrace (struct btrace_thread_info *btinfo)
+{
+ if (!btinfo)
+ return EINVAL;
+
+ if (btinfo->target && target_btrace_has_changed (btinfo->target))
+ {
+ btinfo->btrace = target_read_btrace (btinfo->target);
+ btinfo->iterator = -1;
+
+ if (!btinfo->btrace)
+ return (errno ? errno : ENOSYS);
+
+ /* The first block ends at the current pc. */
+ if (!VEC_empty (btrace_block_s, btinfo->btrace))
+ {
+ struct frame_info *frame = get_current_frame ();
+ if (frame)
+ {
+ struct btrace_block *head =
+ VEC_index (btrace_block_s, btinfo->btrace, 0);
+ if (head && !head->end)
+ head->end = get_frame_pc (frame);
+ }
+ }
+ }
+
+ return 0;
+}
+
+VEC (btrace_block_s) *
+get_btrace (struct thread_info *tinfo)
+{
+ struct btrace_thread_info *btinfo = get_btinfo (tinfo);
+ int errcode;
+
+ if (!btinfo)
+ return NULL;
+
+ errcode = update_btrace (btinfo);
+ if (errcode)
+ {
+ errno = errcode;
+ return NULL;
+ }
+ return btinfo->btrace;
+}
+
+struct btrace_block *
+read_btrace (struct thread_info *tinfo, int index)
+{
+ struct btrace_thread_info *btinfo = get_btinfo (tinfo);
+ int errcode;
+
+ if (!btinfo)
+ return NULL;
+
+ if (index < 0)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ errcode = update_btrace (btinfo);
+ if (errcode)
+ {
+ errno = errcode;
+ return NULL;
+ }
+
+ btinfo->iterator = index;
+
+ if (btinfo->iterator >= VEC_length (btrace_block_s, btinfo->btrace))
+ {
+ btinfo->iterator = VEC_length (btrace_block_s, btinfo->btrace);
+ return NULL;
+ }
+
+ return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
+}
+
+struct btrace_block *
+prev_btrace (struct thread_info *tinfo)
+{
+ struct btrace_thread_info *btinfo = get_btinfo (tinfo);
+ int errcode;
+
+ if (!btinfo)
+ return NULL;
+
+ errcode = update_btrace (btinfo);
+ if (errcode)
+ {
+ errno = errcode;
+ return NULL;
+ }
+
+ btinfo->iterator += 1;
+
+ if (btinfo->iterator >= VEC_length (btrace_block_s, btinfo->btrace))
+ {
+ btinfo->iterator = VEC_length (btrace_block_s, btinfo->btrace);
+ return NULL;
+ }
+
+ return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
+}
+
+struct btrace_block *
+next_btrace (struct thread_info *tinfo)
+{
+ struct btrace_thread_info *btinfo = get_btinfo (tinfo);
+ int errcode;
+
+ if (!btinfo)
+ return NULL;
+
+ errcode = update_btrace (btinfo);
+ if (errcode)
+ {
+ errno = errcode;
+ return NULL;
+ }
+
+ btinfo->iterator -= 1;
+
+ if (btinfo->iterator < 0)
+ {
+ btinfo->iterator = -1;
+ return NULL;
+ }
+
+ return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
+}
diff --git a/gdb/btrace.h b/gdb/btrace.h
new file mode 100644
index 0000000..97f0f52
--- /dev/null
+++ b/gdb/btrace.h
@@ -0,0 +1,89 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef BTRACE_H
+#define BTRACE_H
+
+#include "vec.h"
+#include "defs.h"
+
+struct thread_info;
+
+/* A branch trace block.
+
+ Beware that a block is not a branch. Rather, blocks are connected through
+ branches. */
+struct btrace_block
+{
+ CORE_ADDR begin;
+ CORE_ADDR end;
+};
+
+/* Branch trace is represented as a vector of branch trace blocks starting with
+ the most recent block. */
+typedef struct btrace_block btrace_block_s;
+DEF_VEC_O (btrace_block_s);
+
+/* Target specific branch trace information. */
+struct btrace_target_info;
+
+/* Branch trace information per thread. */
+struct btrace_thread_info
+{
+ /* The target branch trace information for this thread. */
+ struct btrace_target_info *target;
+
+ /* The current branch trace for this thread. */
+ VEC (btrace_block_s) *btrace;
+
+ /* The current iterator position in the above trace vector. */
+ int iterator;
+};
+
+/* Enable branch tracing for a thread.
+ Allocates the branch trace target information.
+ Returns 0 on success and an error value, otherwise. */
+extern int enable_btrace (struct thread_info *);
+
+/* Disable branch tracing for a thread.
+ Deallocates the branch trace target information as well as the current branch
+ trace data.
+ Returns 0 on success and an error value, otherwise. */
+extern int disable_btrace (struct thread_info *);
+
+/* Disconnect branch tracing on detach. */
+extern void disconnect_btrace (void);
+
+/* Return the current branch trace vector for a thread, or NULL if ther is no
+ trace. */
+extern VEC (btrace_block_s) *get_btrace (struct thread_info *);
+
+/* Functions to iterate over a thread's branch trace.
+ There is one global iterator per thread. The iterator is reset implicitly
+ when branch trace for this thread changes.
+ On success, read_btrace sets the iterator to the returned trace entry.
+ Returns the selected block or NULL if there is no trace or the iteratoris
+ out of bounds. */
+extern struct btrace_block *read_btrace (struct thread_info *, int);
+extern struct btrace_block *prev_btrace (struct thread_info *);
+extern struct btrace_block *next_btrace (struct thread_info *);
+
+#endif /* BTRACE_H */
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index fb8de16..055bac0 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -28,6 +28,7 @@ struct symtab;
#include "frame.h"
#include "ui-out.h"
#include "inferior.h"
+#include "btrace.h"
/* Frontend view of the thread state. Possible extensions: stepping,
finishing, until(ling),... */
@@ -225,6 +226,9 @@ struct thread_info
/* Function that is called to free PRIVATE. If this is NULL, then
xfree will be called on PRIVATE. */
void (*private_dtor) (struct private_thread_info *);
+
+ /* Branch trace information for this thread. */
+ struct btrace_thread_info btrace;
};
/* Create an empty thread list, or empty the existing one. */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 1f7564a..f9299e9 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -56,6 +56,7 @@
#include "inf-loop.h"
#include "continuations.h"
#include "linespec.h"
+#include "btrace.h"
/* Functions exported for general use, in inferior.h: */
@@ -2680,6 +2681,7 @@ detach_command (char *args, int from_tty)
error (_("The program is not being run."));
disconnect_tracing (from_tty);
+ disconnect_btrace ();
target_detach (args, from_tty);
diff --git a/gdb/target.c b/gdb/target.c
index 6dba936..4d2ea9e 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -701,6 +701,11 @@ update_current_target (void)
INHERIT (to_traceframe_info, t);
INHERIT (to_use_agent, t);
INHERIT (to_can_use_agent, t);
+ INHERIT (to_supports_btrace, t);
+ INHERIT (to_enable_btrace, t);
+ INHERIT (to_disable_btrace, t);
+ INHERIT (to_btrace_has_changed, t);
+ INHERIT (to_read_btrace, t);
INHERIT (to_magic, t);
INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
/* Do not inherit to_memory_map. */
@@ -939,6 +944,21 @@ update_current_target (void)
(int (*) (void))
return_zero);
de_fault (to_execution_direction, default_execution_direction);
+ de_fault (to_supports_btrace,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_enable_btrace,
+ (struct btrace_target_info * (*) (ptid_t))
+ tcomplain);
+ de_fault (to_disable_btrace,
+ (int (*) (struct btrace_target_info *))
+ tcomplain);
+ de_fault (to_btrace_has_changed,
+ (int (*) (struct btrace_target_info *))
+ tcomplain);
+ de_fault (to_read_btrace,
+ (VEC (btrace_block_s) * (*) (struct btrace_target_info *))
+ tcomplain);
#undef de_fault
diff --git a/gdb/target.h b/gdb/target.h
index 84b462a..86513f7 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -62,6 +62,7 @@ struct expression;
#include "memattr.h"
#include "vec.h"
#include "gdb_signals.h"
+#include "btrace.h"
enum strata
{
@@ -849,6 +850,22 @@ struct target_ops
/* Is the target able to use agent in current state? */
int (*to_can_use_agent) (void);
+ /* Check whether the target supports branch tracing. */
+ int (*to_supports_btrace) (void);
+
+ /* Enable branch tracing for @ptid and allocate a branch trace target
+ information struct for reading and for disabling branch trace. */
+ struct btrace_target_info *(*to_enable_btrace) (ptid_t ptid);
+
+ /* Disable branch tracing. Deallocated @tinfo on success. */
+ int (*to_disable_btrace) (struct btrace_target_info *tinfo);
+
+ /* Check whether branch trace changed on the target. */
+ int (*to_btrace_has_changed) (struct btrace_target_info *);
+
+ /* Read branch trace data. */
+ VEC (btrace_block_s) *(*to_read_btrace) (struct btrace_target_info *);
+
int to_magic;
/* Need sub-structure for target machine related rather than comm related?
*/
@@ -1710,6 +1727,21 @@ extern char *target_fileio_read_stralloc (const char *filename);
#define target_can_use_agent() \
(*current_target.to_can_use_agent) ()
+#define target_supports_btrace() \
+ (*current_target.to_supports_btrace) ()
+
+#define target_enable_btrace(ptid) \
+ (*current_target.to_enable_btrace) (ptid)
+
+#define target_disable_btrace(tinfo) \
+ (*current_target.to_disable_btrace) (tinfo)
+
+#define target_btrace_has_changed(tinfo) \
+ (*current_target.to_btrace_has_changed) (tinfo)
+
+#define target_read_btrace(tinfo) \
+ (*current_target.to_read_btrace) (tinfo)
+
/* Command logging facility. */
#define target_log_command(p) \
diff --git a/gdb/thread.c b/gdb/thread.c
index d361dd8..e234fff 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -34,6 +34,7 @@
#include "regcache.h"
#include "gdb.h"
#include "gdb_string.h"
+#include "btrace.h"
#include <ctype.h>
#include <sys/types.h>
@@ -132,6 +133,8 @@ free_thread (struct thread_info *tp)
xfree (tp->private);
}
+ disable_btrace (tp);
+
xfree (tp->name);
xfree (tp);
}
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 04/16] thread, btrace: add generic branch trace support
2012-05-23 11:25 ` [PATCH 04/16] thread, btrace: add generic branch trace support markus.t.metzger
@ 2012-05-30 20:42 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:42 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:19 +0200, markus.t.metzger@intel.com wrote:
> --- /dev/null
> +++ b/gdb/btrace.c
> @@ -0,0 +1,254 @@
> +/* Branch trace support for GDB, the GNU debugger.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#include "btrace.h"
> +#include "gdbthread.h"
> +#include "frame.h"
> +#include "exceptions.h"
> +
> +#include <errno.h>
> +
> +#if !defined(EALREADY)
GNU Coding Style formatting would be:
#if !defined (EALREADY)
but maybe it is easier:
#ifndef EALREADY
> +/* Remap EALREADY for systems that do not define it, e.g. mingw. */
> +# define EALREADY EBUSY
> +#endif
> +
> +int
> +enable_btrace (struct thread_info *tinfo)
Very every new function must have a comment before.
It is very common across the whole patchset.
This function is documented in btrace.h so it is enough to write here:
/* See definition in btrace.h. */
int
enable_btrace (struct thread_info *tinfo)
I did not list them specifically but I see at least some of the new functions
without comment are really not documented in their corresponding .h file (at
least the 'static' ones).
Also use some common prefix for the global functions in btrace.c, most
probably just rename this function to btrace_enable and other functions too.
> +{
> + if (!tinfo)
> + return EINVAL;
This cannot happen (similarly in other functions) in current code. It could
be rather 'gdb_assert (tinfo != NULL);' but I think it can be even omitted.
Also 'struct thread_info *' is commonly called 'tp' in GDB. But it is not
required to change it.
> +
> + if (tinfo->btrace.target)
> + return EALREADY;
Isn't more suitable here to say some user message instead?
error (_("Branch tracing is already enable for %s."),
target_pid_to_str (tinfo->ptid));
The generic message is not too user friendly, in KVM (assuming not supporting
btrace that way):
(gdb) btrace enable all
warning: Couldn't enable branch tracing for 26535: No such file or directory
"No such file or directory" may not be understood well by a user.
> +
> + tinfo->btrace.target = target_enable_btrace (tinfo->ptid);
> + if (!tinfo->btrace.target)
> + return (errno ? errno : ENOSYS);
I do not see the whole picture now but I do not find these error codes too
right, it is like in C code. GDB uses more the
error()/throw_error()/TRY_CATCH exceptions. Wouldn't it simplify the code
a lot?
> +
> + return 0;
> +}
> +
> +int
> +disable_btrace (struct thread_info *tinfo)
> +{
> + struct btrace_thread_info *btinfo;
> + int errcode = 0;
> +
> + if (!tinfo)
> + return EINVAL;
> +
> + btinfo = &tinfo->btrace;
> +
> + if (!btinfo->target)
> + return EALREADY;
> +
> + /* When killing the inferior, we may have lost our target before we disable
> + branch tracing. */
> + if (target_supports_btrace ())
> + errcode = target_disable_btrace (btinfo->target);
> +
> + if (!errcode)
> + {
> + VEC_free (btrace_block_s, btinfo->btrace);
> + btinfo->btrace = NULL;
VEC_free already does 'btinfo->btrace = NULL;' (I agree it is confusing).
> + btinfo->target = NULL;
> + }
> +
> + return errcode;
> +}
> +
> +static int
> +do_disconnect_btrace (struct thread_info *tinfo, void *ignored)
> +{
> + if (tinfo->btrace.target)
> + {
> + volatile struct gdb_exception error;
> +
> + TRY_CATCH (error, RETURN_MASK_ERROR)
> + {
> + /* Switching threads makes it easier for targets like kgdb, where we
> + need to switch cpus, as well. */
> + switch_to_thread (tinfo->ptid);
> +
> + disable_btrace (tinfo);
> + }
> + }
> +
> + return 0;
> +}
> +
> +void
> +disconnect_btrace (void)
> +{
> + ptid_t ptid = inferior_ptid;
Minor style issue - instead:
struct cleanup *old_chain = save_inferior_ptid ();
> +
> + iterate_over_threads (do_disconnect_btrace, NULL);
> +
> + switch_to_thread (ptid);
Minor style issue - instead:
do_cleanups (old_chain);
This makes it safe against possible future throws of errors.
> +}
> +
> +static struct btrace_thread_info *
> +get_btinfo (struct thread_info *tinfo)
> +{
> + if (!tinfo)
> + {
> + errno = EINVAL;
> + return NULL;
> + }
> + return &tinfo->btrace;
> +}
> +
> +static int
> +update_btrace (struct btrace_thread_info *btinfo)
> +{
> + if (!btinfo)
> + return EINVAL;
> +
> + if (btinfo->target && target_btrace_has_changed (btinfo->target))
> + {
> + btinfo->btrace = target_read_btrace (btinfo->target);
> + btinfo->iterator = -1;
> +
> + if (!btinfo->btrace)
> + return (errno ? errno : ENOSYS);
> +
> + /* The first block ends at the current pc. */
> + if (!VEC_empty (btrace_block_s, btinfo->btrace))
> + {
> + struct frame_info *frame = get_current_frame ();
Empty line after declarations.
> + if (frame)
> + {
> + struct btrace_block *head =
> + VEC_index (btrace_block_s, btinfo->btrace, 0);
Empty line after declarations.
> + if (head && !head->end)
> + head->end = get_frame_pc (frame);
> + }
> + }
> + }
> +
> + return 0;
> +}
> +
> +VEC (btrace_block_s) *
> +get_btrace (struct thread_info *tinfo)
> +{
> + struct btrace_thread_info *btinfo = get_btinfo (tinfo);
> + int errcode;
> +
> + if (!btinfo)
> + return NULL;
> +
> + errcode = update_btrace (btinfo);
> + if (errcode)
> + {
> + errno = errcode;
> + return NULL;
> + }
> + return btinfo->btrace;
> +}
> +
> +struct btrace_block *
> +read_btrace (struct thread_info *tinfo, int index)
> +{
> + struct btrace_thread_info *btinfo = get_btinfo (tinfo);
> + int errcode;
> +
> + if (!btinfo)
> + return NULL;
> +
> + if (index < 0)
> + {
> + errno = EINVAL;
> + return NULL;
> + }
> +
> + errcode = update_btrace (btinfo);
> + if (errcode)
> + {
> + errno = errcode;
> + return NULL;
> + }
> +
> + btinfo->iterator = index;
> +
> + if (btinfo->iterator >= VEC_length (btrace_block_s, btinfo->btrace))
> + {
> + btinfo->iterator = VEC_length (btrace_block_s, btinfo->btrace);
> + return NULL;
So == VEC_length is not permitted and you still set it to VEC_length?
Shouldn't it be set to VEC_length -1 in such case? See more by comment for
the btrace_thread_info.iterator field.
> + }
> +
> + return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
> +}
> +
> +struct btrace_block *
> +prev_btrace (struct thread_info *tinfo)
> +{
> + struct btrace_thread_info *btinfo = get_btinfo (tinfo);
> + int errcode;
> +
> + if (!btinfo)
> + return NULL;
> +
> + errcode = update_btrace (btinfo);
> + if (errcode)
> + {
> + errno = errcode;
> + return NULL;
> + }
> +
> + btinfo->iterator += 1;
> +
> + if (btinfo->iterator >= VEC_length (btrace_block_s, btinfo->btrace))
> + {
> + btinfo->iterator = VEC_length (btrace_block_s, btinfo->btrace);
> + return NULL;
> + }
> +
> + return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
> +}
> +
> +struct btrace_block *
> +next_btrace (struct thread_info *tinfo)
> +{
> + struct btrace_thread_info *btinfo = get_btinfo (tinfo);
> + int errcode;
> +
> + if (!btinfo)
> + return NULL;
> +
> + errcode = update_btrace (btinfo);
> + if (errcode)
> + {
> + errno = errcode;
> + return NULL;
> + }
> +
> + btinfo->iterator -= 1;
> +
> + if (btinfo->iterator < 0)
> + {
> + btinfo->iterator = -1;
> + return NULL;
> + }
> +
> + return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
> +}
> diff --git a/gdb/btrace.h b/gdb/btrace.h
> new file mode 100644
> index 0000000..97f0f52
> --- /dev/null
> +++ b/gdb/btrace.h
> @@ -0,0 +1,89 @@
> +/* Branch trace support for GDB, the GNU debugger.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#ifndef BTRACE_H
> +#define BTRACE_H
> +
> +#include "vec.h"
> +#include "defs.h"
> +
> +struct thread_info;
> +
> +/* A branch trace block.
> +
> + Beware that a block is not a branch. Rather, blocks are connected through
> + branches. */
> +struct btrace_block
> +{
> + CORE_ADDR begin;
> + CORE_ADDR end;
Describe END is the last byte (and not one-after-the-last-one). BTW I would
find easier to make it rather one-after-the-last-byte.
> +};
> +
> +/* Branch trace is represented as a vector of branch trace blocks starting with
> + the most recent block. */
> +typedef struct btrace_block btrace_block_s;
> +DEF_VEC_O (btrace_block_s);
> +
> +/* Target specific branch trace information. */
> +struct btrace_target_info;
> +
> +/* Branch trace information per thread. */
> +struct btrace_thread_info
> +{
> + /* The target branch trace information for this thread. */
> + struct btrace_target_info *target;
> +
> + /* The current branch trace for this thread. */
> + VEC (btrace_block_s) *btrace;
> +
> + /* The current iterator position in the above trace vector. */
> + int iterator;
Could you describe here what does mean if it is -1 and what does mean if it is
VEC_length (btrace)? The code is doing some magic with it.
> +};
> +
> +/* Enable branch tracing for a thread.
> + Allocates the branch trace target information.
> + Returns 0 on success and an error value, otherwise. */
> +extern int enable_btrace (struct thread_info *);
> +
> +/* Disable branch tracing for a thread.
> + Deallocates the branch trace target information as well as the current branch
> + trace data.
> + Returns 0 on success and an error value, otherwise. */
> +extern int disable_btrace (struct thread_info *);
> +
> +/* Disconnect branch tracing on detach. */
> +extern void disconnect_btrace (void);
> +
> +/* Return the current branch trace vector for a thread, or NULL if ther is no
> + trace. */
> +extern VEC (btrace_block_s) *get_btrace (struct thread_info *);
> +
> +/* Functions to iterate over a thread's branch trace.
> + There is one global iterator per thread. The iterator is reset implicitly
> + when branch trace for this thread changes.
> + On success, read_btrace sets the iterator to the returned trace entry.
> + Returns the selected block or NULL if there is no trace or the iteratoris
> + out of bounds. */
> +extern struct btrace_block *read_btrace (struct thread_info *, int);
> +extern struct btrace_block *prev_btrace (struct thread_info *);
> +extern struct btrace_block *next_btrace (struct thread_info *);
> +
> +#endif /* BTRACE_H */
> diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
> index fb8de16..055bac0 100644
> --- a/gdb/gdbthread.h
> +++ b/gdb/gdbthread.h
> @@ -28,6 +28,7 @@ struct symtab;
> #include "frame.h"
> #include "ui-out.h"
> #include "inferior.h"
> +#include "btrace.h"
>
> /* Frontend view of the thread state. Possible extensions: stepping,
> finishing, until(ling),... */
> @@ -225,6 +226,9 @@ struct thread_info
> /* Function that is called to free PRIVATE. If this is NULL, then
> xfree will be called on PRIVATE. */
> void (*private_dtor) (struct private_thread_info *);
> +
> + /* Branch trace information for this thread. */
> + struct btrace_thread_info btrace;
> };
>
> /* Create an empty thread list, or empty the existing one. */
> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> index 1f7564a..f9299e9 100644
> --- a/gdb/infcmd.c
> +++ b/gdb/infcmd.c
> @@ -56,6 +56,7 @@
> #include "inf-loop.h"
> #include "continuations.h"
> #include "linespec.h"
> +#include "btrace.h"
>
> /* Functions exported for general use, in inferior.h: */
>
> @@ -2680,6 +2681,7 @@ detach_command (char *args, int from_tty)
> error (_("The program is not being run."));
>
> disconnect_tracing (from_tty);
> + disconnect_btrace ();
>
> target_detach (args, from_tty);
>
> diff --git a/gdb/target.c b/gdb/target.c
> index 6dba936..4d2ea9e 100644
> --- a/gdb/target.c
> +++ b/gdb/target.c
> @@ -701,6 +701,11 @@ update_current_target (void)
> INHERIT (to_traceframe_info, t);
> INHERIT (to_use_agent, t);
> INHERIT (to_can_use_agent, t);
> + INHERIT (to_supports_btrace, t);
This whole INHERIT / de_fault / '#define target_.*' way is the deprecated one.
The currently recommended way is to use stub functions like
target_verify_memory (and many others). I am sorry it is probably not
documented anywhere.
> + INHERIT (to_enable_btrace, t);
> + INHERIT (to_disable_btrace, t);
> + INHERIT (to_btrace_has_changed, t);
> + INHERIT (to_read_btrace, t);
> INHERIT (to_magic, t);
> INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
> /* Do not inherit to_memory_map. */
> @@ -939,6 +944,21 @@ update_current_target (void)
> (int (*) (void))
> return_zero);
> de_fault (to_execution_direction, default_execution_direction);
> + de_fault (to_supports_btrace,
> + (int (*) (void))
> + return_zero);
> + de_fault (to_enable_btrace,
> + (struct btrace_target_info * (*) (ptid_t))
> + tcomplain);
> + de_fault (to_disable_btrace,
> + (int (*) (struct btrace_target_info *))
> + tcomplain);
> + de_fault (to_btrace_has_changed,
> + (int (*) (struct btrace_target_info *))
> + tcomplain);
> + de_fault (to_read_btrace,
> + (VEC (btrace_block_s) * (*) (struct btrace_target_info *))
> + tcomplain);
>
> #undef de_fault
>
> diff --git a/gdb/target.h b/gdb/target.h
> index 84b462a..86513f7 100644
> --- a/gdb/target.h
> +++ b/gdb/target.h
> @@ -62,6 +62,7 @@ struct expression;
> #include "memattr.h"
> #include "vec.h"
> #include "gdb_signals.h"
> +#include "btrace.h"
>
> enum strata
> {
> @@ -849,6 +850,22 @@ struct target_ops
> /* Is the target able to use agent in current state? */
> int (*to_can_use_agent) (void);
>
> + /* Check whether the target supports branch tracing. */
> + int (*to_supports_btrace) (void);
> +
> + /* Enable branch tracing for @ptid and allocate a branch trace target
> + information struct for reading and for disabling branch trace. */
> + struct btrace_target_info *(*to_enable_btrace) (ptid_t ptid);
> +
> + /* Disable branch tracing. Deallocated @tinfo on success. */
> + int (*to_disable_btrace) (struct btrace_target_info *tinfo);
> +
> + /* Check whether branch trace changed on the target. */
> + int (*to_btrace_has_changed) (struct btrace_target_info *);
> +
> + /* Read branch trace data. */
> + VEC (btrace_block_s) *(*to_read_btrace) (struct btrace_target_info *);
> +
> int to_magic;
> /* Need sub-structure for target machine related rather than comm related?
> */
> @@ -1710,6 +1727,21 @@ extern char *target_fileio_read_stralloc (const char *filename);
> #define target_can_use_agent() \
> (*current_target.to_can_use_agent) ()
>
> +#define target_supports_btrace() \
> + (*current_target.to_supports_btrace) ()
> +
> +#define target_enable_btrace(ptid) \
> + (*current_target.to_enable_btrace) (ptid)
> +
> +#define target_disable_btrace(tinfo) \
> + (*current_target.to_disable_btrace) (tinfo)
> +
> +#define target_btrace_has_changed(tinfo) \
> + (*current_target.to_btrace_has_changed) (tinfo)
> +
> +#define target_read_btrace(tinfo) \
> + (*current_target.to_read_btrace) (tinfo)
> +
> /* Command logging facility. */
>
> #define target_log_command(p) \
> diff --git a/gdb/thread.c b/gdb/thread.c
> index d361dd8..e234fff 100644
> --- a/gdb/thread.c
> +++ b/gdb/thread.c
> @@ -34,6 +34,7 @@
> #include "regcache.h"
> #include "gdb.h"
> #include "gdb_string.h"
> +#include "btrace.h"
>
> #include <ctype.h>
> #include <sys/types.h>
> @@ -132,6 +133,8 @@ free_thread (struct thread_info *tp)
> xfree (tp->private);
> }
>
> + disable_btrace (tp);
> +
> xfree (tp->name);
> xfree (tp);
> }
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 04/16] thread, btrace: add generic branch trace support
2012-05-30 20:42 ` Jan Kratochvil
@ 2012-05-31 15:33 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:33 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 6323 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:42 PM
> To: Metzger, Markus T
Thanks for your review!
[...]
> > +#if !defined(EALREADY)
>
> GNU Coding Style formatting would be:
> #if !defined (EALREADY)
> but maybe it is easier:
> #ifndef EALREADY
Fixed.
> > +/* Remap EALREADY for systems that do not define it, e.g. mingw. */
> > +# define EALREADY EBUSY #endif
> > +
> > +int
> > +enable_btrace (struct thread_info *tinfo)
>
> Very every new function must have a comment before.
> It is very common across the whole patchset.
>
> This function is documented in btrace.h so it is enough to write here:
>
> /* See definition in btrace.h. */
>
> int
> enable_btrace (struct thread_info *tinfo)
OK. I'll add comments to every function.
> I did not list them specifically but I see at least some of the new
> functions
> without comment are really not documented in their corresponding .h file (at
> least the 'static' ones).
>
> Also use some common prefix for the global functions in btrace.c, most
> probably just rename this function to btrace_enable and other functions too.
I tried to stick to the existing style. If you look at gdb/tracepoint.h, for
example,
functions are called start_tracing() and stop_tracing() instead of
trace_start() and
trace_stop().
If you're OK, I would leave the names as they are.
> > +{
> > + if (!tinfo)
> > + return EINVAL;
>
> This cannot happen (similarly in other functions) in current code. It could
> be
> rather 'gdb_assert (tinfo != NULL);' but I think it can be even omitted.
I removed those pointer checks.
> Also 'struct thread_info *' is commonly called 'tp' in GDB. But it is not
> required to change it.
Fixed.
> > +
> > + if (tinfo->btrace.target)
> > + return EALREADY;
>
> Isn't more suitable here to say some user message instead?
> error (_("Branch tracing is already enable for %s."),
> target_pid_to_str (tinfo->ptid));
>
> The generic message is not too user friendly, in KVM (assuming not
> supporting btrace that way):
> (gdb) btrace enable all
> warning: Couldn't enable branch tracing for 26535: No such file or
> directory
>
> "No such file or directory" may not be understood well by a user.
Agreed.
> > +
> > + tinfo->btrace.target = target_enable_btrace (tinfo->ptid); if
> > + (!tinfo->btrace.target)
> > + return (errno ? errno : ENOSYS);
>
> I do not see the whole picture now but I do not find these error codes too
> right, it is like in C code. GDB uses more the
> error()/throw_error()/TRY_CATCH exceptions. Wouldn't it simplify the code
> a lot?
The idea was to not have the low levels talk to the user directly. I was not
aware of the extensive use of exception handling until I followed the
discussion
about C++ - which was after I wrote this code.
I am trying to share the low level code with gdbserver, which seems to use a
restricted form of exception handling or none at all for IN_PROCESS_AGENT.
This reminds me that I have not tested IN_PROCESS_AGENT. I have done nothing
to either include or exclude the new btrace packets and I don't know what the
default is. Can you point me to some documentation on how to build and test
it?
If I called error () to indicate that I could not configure branch tracing,
for
example, this would cause the IN_PROCESS_AGENT to exit () and might not
lead to the correct response for standard gdbserver (I have not checked this).
Do you have a proposal on what to do in this case? Is it OK to call error ()
in gdbserver
code and trust the gdbserver infrastructure to handle it correctly?
[...]
> > + if (!errcode)
> > + {
> > + VEC_free (btrace_block_s, btinfo->btrace);
> > + btinfo->btrace = NULL;
>
> VEC_free already does 'btinfo->btrace = NULL;' (I agree it is confusing).
Fixed.
[...]
> > +void
> > +disconnect_btrace (void)
> > +{
> > + ptid_t ptid = inferior_ptid;
>
> Minor style issue - instead:
> struct cleanup *old_chain = save_inferior_ptid ();
>
> > +
> > + iterate_over_threads (do_disconnect_btrace, NULL);
> > +
> > + switch_to_thread (ptid);
>
> Minor style issue - instead:
> do_cleanups (old_chain);
>
> This makes it safe against possible future throws of errors.
Fixed.
[...]
> > + /* The first block ends at the current pc. */
> > + if (!VEC_empty (btrace_block_s, btinfo->btrace))
> > + {
> > + struct frame_info *frame = get_current_frame ();
>
> Empty line after declarations.
Fixed.
> > + if (frame)
> > + {
> > + struct btrace_block *head =
> > + VEC_index (btrace_block_s, btinfo->btrace, 0);
>
> Empty line after declarations.
Fixed.
[...]
> > + if (btinfo->iterator >= VEC_length (btrace_block_s, btinfo->btrace))
> > + {
> > + btinfo->iterator = VEC_length (btrace_block_s, btinfo->btrace);
> > + return NULL;
>
> So == VEC_length is not permitted and you still set it to VEC_length?
> Shouldn't it be set to VEC_length -1 in such case? See more by comment for
> the btrace_thread_info.iterator field.
Changed the condition to >. Also for the other cases.
[...]
> > +struct btrace_block
> > +{
> > + CORE_ADDR begin;
> > + CORE_ADDR end;
>
> Describe END is the last byte (and not one-after-the-last-one). BTW I would
> find easier to make it rather one-after-the-last-byte.
This is not the last byte of the block but the address of the last instruction
in the block.
I'll add a comment.
[...]
> Could you describe here what does mean if it is -1 and what does mean if it
> is
> VEC_length (btrace)? The code is doing some magic with it.
I'll add a comment to the iterator field in struct btrace_thread_info in
gdb/btrace.h
[...]
> > INHERIT (to_traceframe_info, t);
> > INHERIT (to_use_agent, t);
> > INHERIT (to_can_use_agent, t);
> > + INHERIT (to_supports_btrace, t);
>
> This whole INHERIT / de_fault / '#define target_.*' way is the deprecated
> one.
> The currently recommended way is to use stub functions like
> target_verify_memory (and many others). I am sorry it is probably not
> documented anywhere.
I can add those. I used to declare respective macros.
Do you want me to drop the INHERIT changes from the patch?
[...]
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 05/16] cli, btrace: add btrace cli
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (10 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 04/16] thread, btrace: add generic branch trace support markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:42 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 11/16] test, btrace: add branch trace tests markus.t.metzger
` (6 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add branch trace commands:
- "btrace enable/disable" perform the obvious operation
"" on the current thread.
"all" on each existing thread.
"auto" on each newly created thread.
Actually, "btrace enable auto" turns on automatic enabling for new threads,
and "btrace disable auto" turns it off, again.
- "btrace list" prints the blocks that have been traced.
The output may be configured using modifiers. It prints:
- the block number
/a the begin and end code address of that block
/f the function containing the block
/l the source lines contained in the block
With the /t modifier, it prints the total number of blocks and exits.
It accepts an optional range argument specifying the range of blocks to be
listed. If no argument is given, all blocks are listed.
The block number can be used to print the trace for one particular block or
for a range of blocks.
- "btrace" prints the branch trace disassembly for the current thread.
Branch trace is printed block-by-block. Typically, one block at a time is
printed.
By default, the disassembly for the next block is printed, thus iterating
over the full branch trace.
The command supports the /m and /r modifiers accepted by the disassemble
command.
In addition, the command supports the following arguments:
- "<n>" set the iterator to the <n>-th block
- "+[<n>]" advance the iterator by <n> (default: 1)
- "-[<n>]" advance the iterator by -<n> (default: 1)
- "<l>-<h>" set the iterator to the <h>'th block and
print the blocks in the range in reverse (i.e. original
control flow) order.
Mixed source and disassembly does not work very well for inlined functions,
a problem that it shares with the disassemble command.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* command.h (enum command_class): Add class_btrace
* btrace.c (thread_callback): New function
(for_each_thread): New function
(do_enable_btrace): New function
(safe_do_enable_btrace): New function
(do_disable_btrace): New function
(safe_do_disable_btrace): New function
(cmd_btrace_enable): New function
(cmd_btrace_enable_all): New function
(cmd_btrace_enable_auto): New function
(cmd_btrace_disable): New function
(cmd_btrace_disable_all): New function
(cmd_btrace_disable_auto): New function
(cmd_btrace_list): New function
(cmd_btrace): New function
(_initialize_btrace): New function
---
gdb/btrace.c | 604 +++++++++++++++++++++++++++++++++++++++
gdb/command.h | 2 +-
gdb/testsuite/gdb.base/page.exp | 3 +-
3 files changed, 607 insertions(+), 2 deletions(-)
diff --git a/gdb/btrace.c b/gdb/btrace.c
index e66a986..2b57ca7 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -23,8 +23,24 @@
#include "gdbthread.h"
#include "frame.h"
#include "exceptions.h"
+#include "observer.h"
+#include "command.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-utils.h"
+#include "arch-utils.h"
+#include "disasm.h"
#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+
+/* A new thread observer enabling branch tracing for the new thread. */
+static struct observer *btrace_thread_observer;
+
+/* Branch tracing command list. */
+static struct cmd_list_element *btcmdlist;
+static struct cmd_list_element *btencmdlist;
+static struct cmd_list_element *btdiscmdlist;
#if !defined(EALREADY)
/* Remap EALREADY for systems that do not define it, e.g. mingw. */
@@ -252,3 +268,591 @@ next_btrace (struct thread_info *tinfo)
return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
}
+
+static int
+thread_callback (struct thread_info *tinfo, void *arg)
+{
+ observer_new_thread_ftype *tfun = arg;
+ tfun (tinfo);
+
+ return 0;
+}
+
+static void
+for_each_thread (observer_new_thread_ftype *tfun)
+{
+ iterate_over_threads (thread_callback, tfun);
+}
+
+static void
+do_enable_btrace (struct thread_info *tinfo)
+{
+ int errcode = enable_btrace (tinfo);
+ if (errcode)
+ {
+ int pid = ptid_get_lwp (tinfo->ptid);
+ if (!pid)
+ pid = ptid_get_pid (tinfo->ptid);
+
+ error (_("Couldn't enable branch tracing for %d: %s"),
+ pid, safe_strerror (errcode));
+ }
+}
+
+static void
+safe_do_enable_btrace (struct thread_info *tinfo)
+{
+ if (!target_supports_btrace ())
+ warning (_("Target does not support branch tracing."));
+ else
+ {
+ volatile struct gdb_exception error;
+
+ TRY_CATCH (error, RETURN_MASK_ERROR)
+ {
+ do_enable_btrace (tinfo);
+ }
+ if (error.message)
+ warning (_("%s"), error.message);
+ }
+}
+
+static void
+do_disable_btrace (struct thread_info *tinfo)
+{
+ int errcode = disable_btrace (tinfo);
+ if (errcode)
+ {
+ int pid = ptid_get_lwp (tinfo->ptid);
+ if (!pid)
+ pid = ptid_get_pid (tinfo->ptid);
+
+ error (_("Couldn't disable branch tracing for %d: %s"),
+ pid, safe_strerror (errcode));
+ }
+}
+
+static void
+safe_do_disable_btrace (struct thread_info *tinfo)
+{
+ if (!target_supports_btrace ())
+ warning (_("Target does not support branch tracing."));
+ else
+ {
+ volatile struct gdb_exception error;
+
+ TRY_CATCH (error, RETURN_MASK_ERROR)
+ {
+ do_disable_btrace (tinfo);
+ }
+ if (error.message)
+ warning (_("%s"), error.message);
+ }
+}
+
+static int
+do_enable_btrace_list (struct thread_info *tinfo, void *arg)
+{
+ char *range = (char *)arg;
+
+ if (number_is_in_list (range, tinfo->num))
+ {
+ /* Switching threads makes it easier for targets like kgdb, where we need
+ to switch cpus, as well. */
+ switch_to_thread (tinfo->ptid);
+ safe_do_enable_btrace (tinfo);
+ }
+
+ return 0;
+}
+
+static void
+cmd_btrace_enable (char *args, int from_tty)
+{
+ if (args)
+ {
+ ptid_t ptid = inferior_ptid;
+
+ iterate_over_threads (do_enable_btrace_list, args);
+
+ switch_to_thread (ptid);
+ }
+ else
+ {
+ struct thread_info *tinfo = find_thread_ptid (inferior_ptid);
+ if (!tinfo)
+ error (_("Couldn't enable branch tracing: no inferior thread."));
+ else
+ do_enable_btrace (tinfo);
+ }
+}
+
+static void
+cmd_btrace_enable_all (char *args, int from_tty)
+{
+ if (args)
+ error (_("Invalid argument."));
+ else
+ for_each_thread (safe_do_enable_btrace);
+}
+
+static void
+cmd_btrace_enable_auto (char *args, int from_tty)
+{
+ if (args)
+ error (_("Invalid argument."));
+ else if (btrace_thread_observer)
+ error (_("Automatic branch trace enabling already on."));
+ else
+ btrace_thread_observer =
+ observer_attach_new_thread (safe_do_enable_btrace);
+}
+
+static int
+do_disable_btrace_list (struct thread_info *tinfo, void *arg)
+{
+ char *range = (char *)arg;
+
+ if (number_is_in_list (range, tinfo->num))
+ {
+ /* Switching threads makes it easier for targets like kgdb, where we need
+ to switch cpus, as well. */
+ switch_to_thread (tinfo->ptid);
+ safe_do_disable_btrace (tinfo);
+ }
+
+ return 0;
+}
+
+static void
+cmd_btrace_disable (char *args, int from_tty)
+{
+ if (args)
+ {
+ ptid_t ptid = inferior_ptid;
+
+ iterate_over_threads (do_disable_btrace_list, args);
+
+ switch_to_thread (ptid);
+ }
+ else
+ {
+ struct thread_info *tinfo = find_thread_ptid (inferior_ptid);
+ if (!tinfo)
+ error (_("Couldn't disable branch tracing: no inferior thread."));
+ else
+ do_disable_btrace (tinfo);
+ }
+}
+
+static void
+cmd_btrace_disable_all (char *args, int from_tty)
+{
+ if (args)
+ error (_("Invalid argument."));
+ else
+ for_each_thread (safe_do_disable_btrace);
+}
+
+static void
+cmd_btrace_disable_auto (char *args, int from_tty)
+{
+ if (args)
+ error (_("Invalid argument."));
+ else if (!btrace_thread_observer)
+ error (_("Automatic branch trace enabling already off."));
+ else
+ {
+ observer_detach_new_thread (btrace_thread_observer);
+ btrace_thread_observer = NULL;
+ }
+}
+
+#define BTR_LIST_ADDRESS (1 << 0)
+#define BTR_LIST_FUNCTION (1 << 1)
+#define BTR_LIST_LINE (1 << 2)
+#define BTR_LIST_TOTAL (1 << 3)
+
+static void
+do_btrace_list_item (unsigned int block, struct btrace_block *trace,
+ unsigned int flags)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+ struct symtab *symtab = NULL;
+ struct symbol *symbol = NULL;
+
+ if (!trace)
+ return;
+
+ ui_out_field_fmt_int (current_uiout, 5, ui_left, "block", block);
+
+ if (flags & BTR_LIST_ADDRESS)
+ {
+ ui_out_field_core_addr (current_uiout, "begin", gdbarch, trace->begin);
+ ui_out_text (current_uiout, " - ");
+ ui_out_field_core_addr (current_uiout, "end", gdbarch, trace->end);
+ }
+
+ if (flags & BTR_LIST_FUNCTION)
+ {
+ ui_out_text (current_uiout, " in ");
+
+ symbol = find_pc_function (trace->begin);
+ if (symbol)
+ ui_out_field_string (current_uiout, "function",
+ SYMBOL_PRINT_NAME (symbol));
+ else
+ {
+ struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (trace->begin);
+ if (msymbol)
+ ui_out_field_string (current_uiout, "function",
+ SYMBOL_PRINT_NAME (msymbol));
+ else
+ ui_out_text (current_uiout, "??");
+ }
+
+ ui_out_text (current_uiout, " ()");
+ }
+
+ if (flags & BTR_LIST_LINE)
+ {
+ struct linetable *linetable = NULL;
+ const char *filename = NULL;
+
+ if (symbol)
+ symtab = symbol->symtab;
+ if (!symtab)
+ symtab = find_pc_symtab (trace->begin);
+ if (symtab)
+ {
+ linetable = symtab->linetable;
+ filename = symtab->filename;
+ }
+
+ if (filename)
+ {
+ ui_out_text (current_uiout, " at ");
+ ui_out_field_string (current_uiout, "file", filename);
+
+ if (linetable)
+ {
+ struct linetable_entry *line = linetable->item;
+ int nitems = linetable->nitems, i = 0;
+ int begin = INT_MAX, end = 0;
+
+ /* Skip all preceding entries. */
+ for (; i < (nitems - 1) && line[i + 1].pc <= trace->begin; ++i);
+
+ for (; i < nitems && line[i].pc <= trace->end; ++i)
+ {
+ begin = min (begin, line[i].line);
+ end = max (end, line[i].line);
+ }
+
+ if (begin <= end)
+ {
+ ui_out_text (current_uiout, ":");
+ ui_out_field_int (current_uiout, "lbegin", begin);
+
+ if (begin < end)
+ {
+ ui_out_text (current_uiout, "-");
+ ui_out_field_int (current_uiout, "lend", end);
+ }
+ }
+ }
+ }
+ }
+
+ ui_out_text (current_uiout, "\n");
+}
+
+static void
+do_btrace_list (VEC (btrace_block_s) *btrace, char *range,
+ unsigned int flags)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+ struct cleanup *ui_out_chain =
+ make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
+ unsigned int block = 0;
+ struct btrace_block *trace;
+
+ while (VEC_iterate (btrace_block_s, btrace, block, trace))
+ {
+ ++block;
+
+ if (number_is_in_list (range, block))
+ do_btrace_list_item (block, trace, flags);
+ }
+
+ do_cleanups (ui_out_chain);
+}
+
+static void
+cmd_btrace_list (char *args, int from_tty)
+{
+ struct thread_info *thread = find_thread_ptid (inferior_ptid);
+ VEC (btrace_block_s) *btrace = get_btrace (thread);
+ unsigned int flags = BTR_LIST_FUNCTION | BTR_LIST_LINE;
+
+ /* Parse modifier. */
+ if (args)
+ {
+ if (*args == '/')
+ flags = 0;
+
+ while (*args == '/')
+ {
+ ++args;
+
+ if (*args == '\0')
+ error (_("Missing modifier."));
+
+ for (; *args; ++args)
+ {
+ if (isspace (*args))
+ break;
+
+ if (*args == '/')
+ continue;
+
+ switch (*args)
+ {
+ case 'a':
+ flags |= BTR_LIST_ADDRESS;
+ break;
+ case 'f':
+ flags |= BTR_LIST_FUNCTION;
+ break;
+ case 'l':
+ flags |= BTR_LIST_LINE;
+ break;
+ case 't':
+ flags |= BTR_LIST_TOTAL;
+ break;
+ default:
+ error (_("Invalid modifier: %c."), *args);
+ }
+ }
+
+ args = skip_spaces (args);
+ }
+ }
+
+ if (flags & BTR_LIST_TOTAL)
+ {
+ struct cleanup *ui_out_chain;
+ unsigned int total = VEC_length (btrace_block_s, btrace);
+
+ ui_out_chain =
+ make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
+
+ ui_out_text (current_uiout, "total: ");
+ ui_out_field_int (current_uiout, "total", total);
+ ui_out_text (current_uiout, "\n");
+
+ do_cleanups (ui_out_chain);
+ }
+ else if (!btrace)
+ error (_("No trace"));
+ else
+ do_btrace_list (btrace, args, flags);
+}
+
+static void
+do_btrace (struct btrace_block *trace, int flags)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+
+ if (!trace)
+ {
+ error (_("No trace."));
+ return;
+ }
+
+ if (trace->end < trace->begin)
+ error (_("Bad trace: 0x%" BFD_VMA_FMT "x - 0x%" BFD_VMA_FMT "x."),
+ trace->begin, trace->end);
+
+ gdb_disassembly (gdbarch, current_uiout, 0, flags, -1,
+ trace->begin, trace->end + 1);
+}
+
+static void
+cmd_btrace (char *args, int from_tty)
+{
+ struct thread_info *thread = find_thread_ptid (inferior_ptid);
+ struct btrace_block *trace = NULL;
+ int flags = 0;
+
+ if (!thread)
+ {
+ error (_("No thread."));
+ return;
+ }
+
+ /* Parse modifier. We accept the same modifiers as the disas command. */
+ if (args)
+ {
+ while (*args == '/')
+ {
+ ++args;
+
+ if (*args == '\0')
+ error (_("Missing modifier."));
+
+ for (; *args; ++args)
+ {
+ if (isspace (*args))
+ break;
+
+ if (*args == '/')
+ continue;
+
+ switch (*args)
+ {
+ case 'm':
+ flags |= DISASSEMBLY_SOURCE;
+ flags |= DISASSEMBLY_PRECISE_INSN;
+ flags |= DISASSEMBLY_FILENAME;
+ break;
+ case 'r':
+ flags |= DISASSEMBLY_RAW_INSN;
+ break;
+ default:
+ error (_("Invalid modifier: %c."), *args);
+ }
+ }
+
+ args = skip_spaces (args);
+ }
+ }
+
+
+ if (!args || !*args)
+ trace = prev_btrace (thread);
+ else if (args[0] == '+')
+ {
+ size_t skip = 1;
+
+ args++;
+ if (args[0])
+ skip = get_number (&args);
+
+ while (skip--)
+ trace = prev_btrace (thread);
+ }
+ else if (args[0] == '-')
+ {
+ size_t skip = 1;
+
+ args++;
+ if (args[0])
+ skip = get_number (&args);
+
+ while (skip--)
+ trace = next_btrace (thread);
+ }
+ else
+ {
+ /* We store the relevant blocks into a separate vector, so we can display
+ them in reverse order. */
+ VEC (btrace_block_s) *btrace = NULL;
+ struct cleanup *cleanup;
+ struct get_number_or_range_state state;
+ unsigned int i;
+
+ cleanup = make_cleanup (xfree, btrace);
+ init_number_or_range (&state, args);
+ while (!state.finished)
+ {
+ int index = get_number_or_range (&state);
+ if (!index)
+ {
+ error (_("Args must be numbers or '$' variables."));
+ return;
+ }
+
+ trace = read_btrace (thread, index - 1);
+ if (!trace)
+ continue;
+
+ VEC_safe_push (btrace_block_s, btrace, trace);
+ }
+
+ i = VEC_length (btrace_block_s, btrace);
+ while (i--)
+ do_btrace (VEC_index (btrace_block_s, btrace, i), flags);
+
+ do_cleanups (cleanup);
+ return;
+ }
+
+ if (args && *args)
+ {
+ error (_("Junk after argument: %s"), args);
+ return;
+ }
+
+ do_btrace (trace, flags);
+}
+
+void _initialize_btrace (void);
+
+void
+_initialize_btrace (void)
+{
+ struct cmd_list_element *c;
+
+ add_cmd ("branchtrace", class_btrace, NULL,
+ _("Recording a branch trace."), &cmdlist);
+
+ add_prefix_cmd ("btrace", class_btrace, cmd_btrace, _("\
+Disassemble the selected branch trace block.\n\n\
+With a /m modifier, source lines are included (if available).\n\
+With a /r modifier, raw instructions in hex are included.\n\n\
+Without arguments, selects the chronologically preceding block.\n\
+With \"+[<n>]\" argument, selects the n-th chronologically preceding block.\n\
+With \"-[<n>]\" argument, selects the n-th chronologically succeeding block.\n\
+With one positive integer argument, selects the respective block.\n\
+With a range argument \"<l>-<h>\", selects the h-th block and disassembles \
+blocks in the range in reverse (i.e. original control flow) order.\n"),
+ &btcmdlist, "btrace ", 1, &cmdlist);
+
+ add_prefix_cmd ("enable", class_btrace, cmd_btrace_enable, _("\
+Enable branch trace recording for the current thread.\n"),
+ &btencmdlist, "btrace enable ", 1, &btcmdlist);
+
+ add_cmd ("all", class_btrace, cmd_btrace_enable_all, _("\
+Enable branch trace recording for all existing threads.\n"),
+ &btencmdlist);
+
+ add_cmd ("auto", class_btrace, cmd_btrace_enable_auto, _("\
+Enable branch trace recording for each new thread.\n"),
+ &btencmdlist);
+
+ add_prefix_cmd ("disable", class_btrace, cmd_btrace_disable, _("\
+Disable branch trace recording for the current thread.\n"),
+ &btdiscmdlist, "btrace disable ", 1, &btcmdlist);
+
+ add_cmd ("all", class_btrace, cmd_btrace_disable_all, _("\
+Disable branch trace recording for all existing threads.\n"),
+ &btdiscmdlist);
+
+ add_cmd ("auto", class_btrace, cmd_btrace_disable_auto, _("\
+Stop enabling branch trace recording for each new thread.\n"),
+ &btdiscmdlist);
+
+ add_cmd ("list", class_btrace, cmd_btrace_list, _("\
+List branch trace blocks.\n\n\
+Prints a list of all blocks for which branch trace is available.\n\
+With a /a modifier, addresses are included.\n\
+With a /f modifier, the function name is included (if available).\n\
+With a /l modifier, source lines are include (if available).\n\
+With a /t modifier, prints the total number of trace blocks and stops.\n\
+Without any modifier, behaves as if /fl were specified.\n\n\
+Without arguments, the full list of blocks is listed.\n\
+With a range (<start>[-<end>]) argument, the blocks in that range are listed.\n"),
+ &btcmdlist);
+}
diff --git a/gdb/command.h b/gdb/command.h
index c18e2dd..999ec1d 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -37,7 +37,7 @@ enum command_class
no_class = -1, class_run = 0, class_vars, class_stack, class_files,
class_support, class_info, class_breakpoint, class_trace,
class_alias, class_bookmark, class_obscure, class_maintenance,
- class_pseudo, class_tui, class_user, class_xdb,
+ class_pseudo, class_tui, class_user, class_xdb, class_btrace,
no_set_class /* Used for "show" commands that have no corresponding
"set" command. */
};
diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
index 0629807..d9b3899 100644
--- a/gdb/testsuite/gdb.base/page.exp
+++ b/gdb/testsuite/gdb.base/page.exp
@@ -25,6 +25,7 @@ gdb_test_sequence "help" "unpaged help" {
"List of classes of commands:"
""
"aliases -- Aliases of other commands"
+ "branchtrace -- Recording a branch trace"
"breakpoints -- Making program stop at certain points"
"data -- Examining data"
"files -- Specifying and examining files"
@@ -52,12 +53,12 @@ gdb_expect_list "paged help" \
"List of classes of commands:"
""
"aliases -- Aliases of other commands"
+ "branchtrace -- Recording a branch trace"
"breakpoints -- Making program stop at certain points"
"data -- Examining data"
"files -- Specifying and examining files"
"internals -- Maintenance commands"
"obscure -- Obscure features"
- "running -- Running the program"
}
gdb_test "q"
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 05/16] cli, btrace: add btrace cli
2012-05-23 11:25 ` [PATCH 05/16] cli, btrace: add btrace cli markus.t.metzger
@ 2012-05-30 20:42 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:42 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:20 +0200, markus.t.metzger@intel.com wrote:
> diff --git a/gdb/btrace.c b/gdb/btrace.c
> index e66a986..2b57ca7 100644
> --- a/gdb/btrace.c
> +++ b/gdb/btrace.c
> @@ -23,8 +23,24 @@
> #include "gdbthread.h"
> #include "frame.h"
> #include "exceptions.h"
> +#include "observer.h"
> +#include "command.h"
> +#include "cli/cli-cmds.h"
> +#include "cli/cli-utils.h"
> +#include "arch-utils.h"
> +#include "disasm.h"
>
> #include <errno.h>
> +#include <ctype.h>
> +#include <string.h>
> +
> +/* A new thread observer enabling branch tracing for the new thread. */
> +static struct observer *btrace_thread_observer;
> +
> +/* Branch tracing command list. */
> +static struct cmd_list_element *btcmdlist;
> +static struct cmd_list_element *btencmdlist;
> +static struct cmd_list_element *btdiscmdlist;
The variables should be each commented.
>
> #if !defined(EALREADY)
> /* Remap EALREADY for systems that do not define it, e.g. mingw. */
> @@ -252,3 +268,591 @@ next_btrace (struct thread_info *tinfo)
>
> return VEC_index (btrace_block_s, btinfo->btrace, btinfo->iterator);
> }
> +
Function comment.
> +static int
> +thread_callback (struct thread_info *tinfo, void *arg)
Despite it is static there are some wishes for GDB all the functions should
have the filename prefix, therefore btrace_thread_callback here.
> +{
> + observer_new_thread_ftype *tfun = arg;
Empty line after declarations.
> + tfun (tinfo);
> +
> + return 0;
> +}
> +
> +static void
> +for_each_thread (observer_new_thread_ftype *tfun)
> +{
> + iterate_over_threads (thread_callback, tfun);
> +}
> +
> +static void
> +do_enable_btrace (struct thread_info *tinfo)
> +{
> + int errcode = enable_btrace (tinfo);
> + if (errcode)
> + {
> + int pid = ptid_get_lwp (tinfo->ptid);
Empty line after declarations.
> + if (!pid)
> + pid = ptid_get_pid (tinfo->ptid);
> +
> + error (_("Couldn't enable branch tracing for %d: %s"),
> + pid, safe_strerror (errcode));
Just use %s and as argument: target_pid_to_str (tinfo)
But enable_btrace should error on its own as I have recommended.
> + }
> +}
> +
> +static void
> +safe_do_enable_btrace (struct thread_info *tinfo)
> +{
> + if (!target_supports_btrace ())
> + warning (_("Target does not support branch tracing."));
> + else
> + {
> + volatile struct gdb_exception error;
> +
> + TRY_CATCH (error, RETURN_MASK_ERROR)
> + {
> + do_enable_btrace (tinfo);
> + }
> + if (error.message)
> + warning (_("%s"), error.message);
> + }
> +}
> +
> +static void
> +do_disable_btrace (struct thread_info *tinfo)
> +{
> + int errcode = disable_btrace (tinfo);
> + if (errcode)
> + {
> + int pid = ptid_get_lwp (tinfo->ptid);
> + if (!pid)
> + pid = ptid_get_pid (tinfo->ptid);
> +
> + error (_("Couldn't disable branch tracing for %d: %s"),
> + pid, safe_strerror (errcode));
> + }
Likewise above.
> +}
> +
> +static void
> +safe_do_disable_btrace (struct thread_info *tinfo)
> +{
> + if (!target_supports_btrace ())
> + warning (_("Target does not support branch tracing."));
> + else
> + {
> + volatile struct gdb_exception error;
> +
> + TRY_CATCH (error, RETURN_MASK_ERROR)
> + {
> + do_disable_btrace (tinfo);
> + }
> + if (error.message)
> + warning (_("%s"), error.message);
> + }
> +}
> +
> +static int
> +do_enable_btrace_list (struct thread_info *tinfo, void *arg)
> +{
> + char *range = (char *)arg;
> +
> + if (number_is_in_list (range, tinfo->num))
> + {
> + /* Switching threads makes it easier for targets like kgdb, where we need
> + to switch cpus, as well. */
> + switch_to_thread (tinfo->ptid);
In such case it should be switched in the most bottom function.
> + safe_do_enable_btrace (tinfo);
Here is TINFO still passed as a parameter so it is not required to call
switch_to_thread.
> + }
> +
> + return 0;
> +}
> +
> +static void
> +cmd_btrace_enable (char *args, int from_tty)
> +{
> + if (args)
So far I think GDB considers ARGS may be either NULL or "" as no-parameters.
> + {
> + ptid_t ptid = inferior_ptid;
Again use save_inferior_ptid like I suggested before.
> +
> + iterate_over_threads (do_enable_btrace_list, args);
> +
> + switch_to_thread (ptid);
And here likewise.
> + }
> + else
> + {
> + struct thread_info *tinfo = find_thread_ptid (inferior_ptid);
Empty line after declarations.
> + if (!tinfo)
> + error (_("Couldn't enable branch tracing: no inferior thread."));
> + else
'else' is not needed, 'error' doe snot return.
> + do_enable_btrace (tinfo);
> + }
> +}
> +
> +static void
> +cmd_btrace_enable_all (char *args, int from_tty)
> +{
> + if (args)
> + error (_("Invalid argument."));
> + else
Redundant 'else'.
> + for_each_thread (safe_do_enable_btrace);
> +}
> +
> +static void
> +cmd_btrace_enable_auto (char *args, int from_tty)
> +{
> + if (args)
> + error (_("Invalid argument."));
> + else if (btrace_thread_observer)
> + error (_("Automatic branch trace enabling already on."));
> + else
> + btrace_thread_observer =
> + observer_attach_new_thread (safe_do_enable_btrace);
Again redundant 'else's.
> +}
> +
> +static int
> +do_disable_btrace_list (struct thread_info *tinfo, void *arg)
> +{
> + char *range = (char *)arg;
> +
> + if (number_is_in_list (range, tinfo->num))
> + {
> + /* Switching threads makes it easier for targets like kgdb, where we need
> + to switch cpus, as well. */
> + switch_to_thread (tinfo->ptid);
Likewise above.
> + safe_do_disable_btrace (tinfo);
> + }
> +
> + return 0;
> +}
> +
> +static void
> +cmd_btrace_disable (char *args, int from_tty)
> +{
> + if (args)
> + {
> + ptid_t ptid = inferior_ptid;
> +
> + iterate_over_threads (do_disable_btrace_list, args);
> +
> + switch_to_thread (ptid);
> + }
> + else
> + {
> + struct thread_info *tinfo = find_thread_ptid (inferior_ptid);
> + if (!tinfo)
> + error (_("Couldn't disable branch tracing: no inferior thread."));
> + else
> + do_disable_btrace (tinfo);
> + }
All likewise in the enable case.
> +}
> +
> +static void
> +cmd_btrace_disable_all (char *args, int from_tty)
> +{
> + if (args)
> + error (_("Invalid argument."));
> + else
> + for_each_thread (safe_do_disable_btrace);
> +}
> +
> +static void
> +cmd_btrace_disable_auto (char *args, int from_tty)
> +{
> + if (args)
> + error (_("Invalid argument."));
> + else if (!btrace_thread_observer)
> + error (_("Automatic branch trace enabling already off."));
> + else
> + {
> + observer_detach_new_thread (btrace_thread_observer);
> + btrace_thread_observer = NULL;
> + }
> +}
> +
> +#define BTR_LIST_ADDRESS (1 << 0)
> +#define BTR_LIST_FUNCTION (1 << 1)
> +#define BTR_LIST_LINE (1 << 2)
> +#define BTR_LIST_TOTAL (1 << 3)
It should be rather enum. Each item needs its comment.
> +
> +static void
> +do_btrace_list_item (unsigned int block, struct btrace_block *trace,
> + unsigned int flags)
> +{
> + struct gdbarch *gdbarch = get_current_arch ();
gdbarch depends on TRACE, not on current frame. Each frame can have different
gdbarch. But putting gdbarch into each TRACE is probably too expensive.
I would guess target_gdbarch is more acceptable to use for printing CORE_ADDR.
> + struct symtab *symtab = NULL;
> + struct symbol *symbol = NULL;
> +
> + if (!trace)
> + return;
Cannot happen, remove or gdb_assert.
> +
> + ui_out_field_fmt_int (current_uiout, 5, ui_left, "block", block);
> +
> + if (flags & BTR_LIST_ADDRESS)
> + {
> + ui_out_field_core_addr (current_uiout, "begin", gdbarch, trace->begin);
> + ui_out_text (current_uiout, " - ");
> + ui_out_field_core_addr (current_uiout, "end", gdbarch, trace->end);
> + }
> +
> + if (flags & BTR_LIST_FUNCTION)
> + {
> + ui_out_text (current_uiout, " in ");
> +
> + symbol = find_pc_function (trace->begin);
> + if (symbol)
> + ui_out_field_string (current_uiout, "function",
> + SYMBOL_PRINT_NAME (symbol));
> + else
> + {
> + struct minimal_symbol *msymbol =
> + lookup_minimal_symbol_by_pc (trace->begin);
Empty line.
> + if (msymbol)
> + ui_out_field_string (current_uiout, "function",
> + SYMBOL_PRINT_NAME (msymbol));
> + else
> + ui_out_text (current_uiout, "??");
> + }
> +
> + ui_out_text (current_uiout, " ()");
> + }
> +
> + if (flags & BTR_LIST_LINE)
> + {
> + struct linetable *linetable = NULL;
> + const char *filename = NULL;
> +
> + if (symbol)
> + symtab = symbol->symtab;
> + if (!symtab)
> + symtab = find_pc_symtab (trace->begin);
> + if (symtab)
> + {
> + linetable = symtab->linetable;
> + filename = symtab->filename;
> + }
> +
> + if (filename)
> + {
> + ui_out_text (current_uiout, " at ");
> + ui_out_field_string (current_uiout, "file", filename);
> +
> + if (linetable)
> + {
> + struct linetable_entry *line = linetable->item;
> + int nitems = linetable->nitems, i = 0;
> + int begin = INT_MAX, end = 0;
> +
> + /* Skip all preceding entries. */
> + for (; i < (nitems - 1) && line[i + 1].pc <= trace->begin; ++i);
> +
> + for (; i < nitems && line[i].pc <= trace->end; ++i)
> + {
> + begin = min (begin, line[i].line);
> + end = max (end, line[i].line);
> + }
> +
> + if (begin <= end)
> + {
> + ui_out_text (current_uiout, ":");
> + ui_out_field_int (current_uiout, "lbegin", begin);
> +
> + if (begin < end)
> + {
> + ui_out_text (current_uiout, "-");
> + ui_out_field_int (current_uiout, "lend", end);
> + }
> + }
> + }
> + }
> + }
> +
> + ui_out_text (current_uiout, "\n");
> +}
> +
> +static void
> +do_btrace_list (VEC (btrace_block_s) *btrace, char *range,
> + unsigned int flags)
> +{
> + struct gdbarch *gdbarch = get_current_arch ();
Unused variable.
> + struct cleanup *ui_out_chain =
> + make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
> + unsigned int block = 0;
> + struct btrace_block *trace;
> +
> + while (VEC_iterate (btrace_block_s, btrace, block, trace))
> + {
> + ++block;
> +
> + if (number_is_in_list (range, block))
> + do_btrace_list_item (block, trace, flags);
> + }
> +
> + do_cleanups (ui_out_chain);
> +}
> +
> +static void
> +cmd_btrace_list (char *args, int from_tty)
> +{
> + struct thread_info *thread = find_thread_ptid (inferior_ptid);
> + VEC (btrace_block_s) *btrace = get_btrace (thread);
> + unsigned int flags = BTR_LIST_FUNCTION | BTR_LIST_LINE;
> +
> + /* Parse modifier. */
> + if (args)
> + {
> + if (*args == '/')
> + flags = 0;
> +
> + while (*args == '/')
> + {
> + ++args;
> +
> + if (*args == '\0')
> + error (_("Missing modifier."));
> +
> + for (; *args; ++args)
> + {
> + if (isspace (*args))
> + break;
> +
> + if (*args == '/')
> + continue;
> +
> + switch (*args)
> + {
> + case 'a':
> + flags |= BTR_LIST_ADDRESS;
> + break;
> + case 'f':
> + flags |= BTR_LIST_FUNCTION;
> + break;
> + case 'l':
> + flags |= BTR_LIST_LINE;
> + break;
> + case 't':
> + flags |= BTR_LIST_TOTAL;
> + break;
> + default:
> + error (_("Invalid modifier: %c."), *args);
> + }
> + }
> +
> + args = skip_spaces (args);
> + }
> + }
> +
> + if (flags & BTR_LIST_TOTAL)
> + {
> + struct cleanup *ui_out_chain;
> + unsigned int total = VEC_length (btrace_block_s, btrace);
> +
> + ui_out_chain =
> + make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
> +
> + ui_out_text (current_uiout, "total: ");
> + ui_out_field_int (current_uiout, "total", total);
> + ui_out_text (current_uiout, "\n");
> +
> + do_cleanups (ui_out_chain);
> + }
> + else if (!btrace)
> + error (_("No trace"));
dot:
error (_("No trace."));
> + else
> + do_btrace_list (btrace, args, flags);
> +}
> +
> +static void
> +do_btrace (struct btrace_block *trace, int flags)
> +{
> + struct gdbarch *gdbarch = get_current_arch ();
> +
> + if (!trace)
> + {
> + error (_("No trace."));
> + return;
Excessive return.
> + }
> +
> + if (trace->end < trace->begin)
> + error (_("Bad trace: 0x%" BFD_VMA_FMT "x - 0x%" BFD_VMA_FMT "x."),
> + trace->begin, trace->end);
It is CORE_ADDR, not bfd_vma. Therefore use paddress.
> +
> + gdb_disassembly (gdbarch, current_uiout, 0, flags, -1,
> + trace->begin, trace->end + 1);
> +}
> +
> +static void
> +cmd_btrace (char *args, int from_tty)
> +{
> + struct thread_info *thread = find_thread_ptid (inferior_ptid);
> + struct btrace_block *trace = NULL;
> + int flags = 0;
Use enum.
> +
> + if (!thread)
> + {
> + error (_("No thread."));
> + return;
Excessive return.
> + }
> +
> + /* Parse modifier. We accept the same modifiers as the disas command. */
> + if (args)
> + {
> + while (*args == '/')
> + {
> + ++args;
> +
> + if (*args == '\0')
> + error (_("Missing modifier."));
> +
> + for (; *args; ++args)
> + {
> + if (isspace (*args))
> + break;
> +
> + if (*args == '/')
> + continue;
> +
> + switch (*args)
> + {
> + case 'm':
> + flags |= DISASSEMBLY_SOURCE;
> + flags |= DISASSEMBLY_PRECISE_INSN;
> + flags |= DISASSEMBLY_FILENAME;
> + break;
> + case 'r':
> + flags |= DISASSEMBLY_RAW_INSN;
> + break;
> + default:
> + error (_("Invalid modifier: %c."), *args);
> + }
> + }
> +
> + args = skip_spaces (args);
> + }
> + }
> +
> +
> + if (!args || !*args)
> + trace = prev_btrace (thread);
> + else if (args[0] == '+')
> + {
> + size_t skip = 1;
> +
> + args++;
> + if (args[0])
> + skip = get_number (&args);
> +
> + while (skip--)
> + trace = prev_btrace (thread);
> + }
> + else if (args[0] == '-')
> + {
> + size_t skip = 1;
> +
> + args++;
> + if (args[0])
> + skip = get_number (&args);
> +
> + while (skip--)
> + trace = next_btrace (thread);
> + }
> + else
> + {
> + /* We store the relevant blocks into a separate vector, so we can display
> + them in reverse order. */
> + VEC (btrace_block_s) *btrace = NULL;
> + struct cleanup *cleanup;
> + struct get_number_or_range_state state;
> + unsigned int i;
> +
> + cleanup = make_cleanup (xfree, btrace);
You must use VEC_cleanup here, not xfree.
> + init_number_or_range (&state, args);
> + while (!state.finished)
> + {
> + int index = get_number_or_range (&state);
Empty line after declarations.
> + if (!index)
> + {
> + error (_("Args must be numbers or '$' variables."));
> + return;
Excessive return.
> + }
> +
> + trace = read_btrace (thread, index - 1);
> + if (!trace)
> + continue;
> +
> + VEC_safe_push (btrace_block_s, btrace, trace);
> + }
> +
> + i = VEC_length (btrace_block_s, btrace);
> + while (i--)
> + do_btrace (VEC_index (btrace_block_s, btrace, i), flags);
> +
> + do_cleanups (cleanup);
> + return;
The function is a bit spaghetting, maybe you could split it for the different
cases. Just optional.
> + }
> +
> + if (args && *args)
> + {
> + error (_("Junk after argument: %s"), args);
> + return;
Excessive return.
> + }
> +
> + do_btrace (trace, flags);
> +}
> +
> +void _initialize_btrace (void);
> +
> +void
> +_initialize_btrace (void)
> +{
> + struct cmd_list_element *c;
> +
> + add_cmd ("branchtrace", class_btrace, NULL,
> + _("Recording a branch trace."), &cmdlist);
Incorrect indentation, it would be (using tab):
add_cmd ("branchtrace", class_btrace, NULL,
_("Recording a branch trace."), &cmdlist);
but you can:
add_cmd ("branchtrace", class_btrace, NULL, _("Recording a branch trace."),
&cmdlist);
> +
> + add_prefix_cmd ("btrace", class_btrace, cmd_btrace, _("\
> +Disassemble the selected branch trace block.\n\n\
> +With a /m modifier, source lines are included (if available).\n\
> +With a /r modifier, raw instructions in hex are included.\n\n\
> +Without arguments, selects the chronologically preceding block.\n\
> +With \"+[<n>]\" argument, selects the n-th chronologically preceding block.\n\
> +With \"-[<n>]\" argument, selects the n-th chronologically succeeding block.\n\
> +With one positive integer argument, selects the respective block.\n\
> +With a range argument \"<l>-<h>\", selects the h-th block and disassembles \
> +blocks in the range in reverse (i.e. original control flow) order.\n"),
> + &btcmdlist, "btrace ", 1, &cmdlist);
In many cases - you should use tab character instead of 8 spaces.
> +
> + add_prefix_cmd ("enable", class_btrace, cmd_btrace_enable, _("\
> +Enable branch trace recording for the current thread.\n"),
> + &btencmdlist, "btrace enable ", 1, &btcmdlist);
> +
> + add_cmd ("all", class_btrace, cmd_btrace_enable_all, _("\
> +Enable branch trace recording for all existing threads.\n"),
> + &btencmdlist);
> +
> + add_cmd ("auto", class_btrace, cmd_btrace_enable_auto, _("\
> +Enable branch trace recording for each new thread.\n"),
> + &btencmdlist);
> +
> + add_prefix_cmd ("disable", class_btrace, cmd_btrace_disable, _("\
> +Disable branch trace recording for the current thread.\n"),
> + &btdiscmdlist, "btrace disable ", 1, &btcmdlist);
> +
> + add_cmd ("all", class_btrace, cmd_btrace_disable_all, _("\
> +Disable branch trace recording for all existing threads.\n"),
> + &btdiscmdlist);
> +
> + add_cmd ("auto", class_btrace, cmd_btrace_disable_auto, _("\
> +Stop enabling branch trace recording for each new thread.\n"),
> + &btdiscmdlist);
> +
> + add_cmd ("list", class_btrace, cmd_btrace_list, _("\
> +List branch trace blocks.\n\n\
> +Prints a list of all blocks for which branch trace is available.\n\
> +With a /a modifier, addresses are included.\n\
> +With a /f modifier, the function name is included (if available).\n\
> +With a /l modifier, source lines are include (if available).\n\
> +With a /t modifier, prints the total number of trace blocks and stops.\n\
> +Without any modifier, behaves as if /fl were specified.\n\n\
> +Without arguments, the full list of blocks is listed.\n\
> +With a range (<start>[-<end>]) argument, the blocks in that range are listed.\n"),
> + &btcmdlist);
> +}
> diff --git a/gdb/command.h b/gdb/command.h
> index c18e2dd..999ec1d 100644
> --- a/gdb/command.h
> +++ b/gdb/command.h
> @@ -37,7 +37,7 @@ enum command_class
> no_class = -1, class_run = 0, class_vars, class_stack, class_files,
> class_support, class_info, class_breakpoint, class_trace,
> class_alias, class_bookmark, class_obscure, class_maintenance,
> - class_pseudo, class_tui, class_user, class_xdb,
> + class_pseudo, class_tui, class_user, class_xdb, class_btrace,
> no_set_class /* Used for "show" commands that have no corresponding
> "set" command. */
> };
> diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
> index 0629807..d9b3899 100644
> --- a/gdb/testsuite/gdb.base/page.exp
> +++ b/gdb/testsuite/gdb.base/page.exp
> @@ -25,6 +25,7 @@ gdb_test_sequence "help" "unpaged help" {
> "List of classes of commands:"
> ""
> "aliases -- Aliases of other commands"
> + "branchtrace -- Recording a branch trace"
I am not sure if it is worth a new class but it does not fit much in
'tracepoints'.
> "breakpoints -- Making program stop at certain points"
> "data -- Examining data"
> "files -- Specifying and examining files"
> @@ -52,12 +53,12 @@ gdb_expect_list "paged help" \
> "List of classes of commands:"
> ""
> "aliases -- Aliases of other commands"
> + "branchtrace -- Recording a branch trace"
> "breakpoints -- Making program stop at certain points"
> "data -- Examining data"
> "files -- Specifying and examining files"
> "internals -- Maintenance commands"
> "obscure -- Obscure features"
> - "running -- Running the program"
> }
> gdb_test "q"
>
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 05/16] cli, btrace: add btrace cli
2012-05-30 20:42 ` Jan Kratochvil
@ 2012-05-31 15:33 ` Metzger, Markus T
2012-06-01 18:42 ` Jan Kratochvil
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:33 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 9408 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:42 PM
Thanks for your review!
[...]
> > +/* A new thread observer enabling branch tracing for the new thread.
> > +*/ static struct observer *btrace_thread_observer;
> > +
> > +/* Branch tracing command list. */
> > +static struct cmd_list_element *btcmdlist; static struct
> > +cmd_list_element *btencmdlist; static struct cmd_list_element
> > +*btdiscmdlist;
>
> The variables should be each commented.
Fixed.
> > #if !defined(EALREADY)
> > /* Remap EALREADY for systems that do not define it, e.g. mingw. */
> > @@ -252,3 +268,591 @@ next_btrace (struct thread_info *tinfo)
> >
> > return VEC_index (btrace_block_s, btinfo->btrace,
> > btinfo->iterator); }
> > +
>
> Function comment.
Fixed.
> > +static int
> > +thread_callback (struct thread_info *tinfo, void *arg)
>
> Despite it is static there are some wishes for GDB all the functions should
> have the filename prefix, therefore btrace_thread_callback here.
I pity the maintainer of gdb/dwarf2-frame-tailcall.c;-)
You mentioned this for another patch, already. If this is gdb style, I can
certainly
name my functions accordingly. I just don't see this a lot in other gdb files,
and it
results in odd and quite lengthy names.
> > +{
> > + observer_new_thread_ftype *tfun = arg;
>
> Empty line after declarations.
Fixed all occurences in this source file.
[...]
> > + if (!pid)
> > + pid = ptid_get_pid (tinfo->ptid);
> > +
> > + error (_("Couldn't enable branch tracing for %d: %s"),
> > + pid, safe_strerror (errcode));
>
> Just use %s and as argument: target_pid_to_str (tinfo)
Fixed.
> But enable_btrace should error on its own as I have recommended.
Will fix once the situation with gdbserver and shared code is clear.
[...]
> > + error (_("Couldn't disable branch tracing for %d: %s"),
> > + pid, safe_strerror (errcode));
> > + }
>
> Likewise above.
Fixed.
[...]
> > + if (number_is_in_list (range, tinfo->num))
> > + {
> > + /* Switching threads makes it easier for targets like kgdb, where
> > we
> need
> > + to switch cpus, as well. */
> > + switch_to_thread (tinfo->ptid);
>
> In such case it should be switched in the most bottom function.
I can move it to the enable and disable functions. This will result in a few
extra
switches back to the selected thread when processing a list of threads. I hope
that's OK.
> > + safe_do_enable_btrace (tinfo);
>
> Here is TINFO still passed as a parameter so it is not required to call
> switch_to_thread.
I originally did not intend to switch threads, at all. All the btrace
functions take
the thread to operate on as explicit argument.
When I later added btrace support to kgdb, I realized that I had to switch
cpu's
in order to perform certain operations. I should really do this inside kgdb,
but
it was so much easier just to switch threads in gdb.
If you're not OK with this, I can remove all the thread switching and look for
a solution in kgdb.
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void
> > +cmd_btrace_enable (char *args, int from_tty) {
> > + if (args)
>
> So far I think GDB considers ARGS may be either NULL or "" as no-
> parameters.
Fixed.
>
> > + {
> > + ptid_t ptid = inferior_ptid;
>
> Again use save_inferior_ptid like I suggested before.
Fixed all occurrences in this file.
[...]
> > + }
> > + else
> > + {
> > + struct thread_info *tinfo = find_thread_ptid (inferior_ptid);
>
> Empty line after declarations.
Fixed.
> > + if (!tinfo)
> > + error (_("Couldn't enable branch tracing: no inferior thread."));
> > + else
>
> 'else' is not needed, 'error' doe snot return.
Fixed all occurrences in this file.
[...]
> > +#define BTR_LIST_ADDRESS (1 << 0)
> > +#define BTR_LIST_FUNCTION (1 << 1)
> > +#define BTR_LIST_LINE (1 << 2)
> > +#define BTR_LIST_TOTAL (1 << 3)
>
> It should be rather enum. Each item needs its comment.
Fixed.
> > +
> > +static void
> > +do_btrace_list_item (unsigned int block, struct btrace_block *trace,
> > + unsigned int flags) {
> > + struct gdbarch *gdbarch = get_current_arch ();
>
> gdbarch depends on TRACE, not on current frame. Each frame can have
> different gdbarch. But putting gdbarch into each TRACE is probably too
> expensive.
>
> I would guess target_gdbarch is more acceptable to use for printing
> CORE_ADDR.
Replaced this with target_arch.
> > + struct symtab *symtab = NULL;
> > + struct symbol *symbol = NULL;
> > +
> > + if (!trace)
> > + return;
>
> Cannot happen, remove or gdb_assert.
Removed.
[...]
> > + {
> > + struct minimal_symbol *msymbol =
> > + lookup_minimal_symbol_by_pc (trace->begin);
>
> Empty line.
Fixed.
[...]
> > +static void
> > +do_btrace_list (VEC (btrace_block_s) *btrace, char *range,
> > + unsigned int flags)
> > +{
> > + struct gdbarch *gdbarch = get_current_arch ();
>
> Unused variable.
Fixed.
[...]
> > + else if (!btrace)
> > + error (_("No trace"));
>
> dot:
> error (_("No trace."));
Rearranged the if so the error case is at the final else. Since the preceding
then statements
do not return, I still need to put the error () under else.
[...]
> > + error (_("No trace."));
> > + return;
>
> Excessive return.
Fixed all occurrences in this file.
> > + }
> > +
> > + if (trace->end < trace->begin)
> > + error (_("Bad trace: 0x%" BFD_VMA_FMT "x - 0x%" BFD_VMA_FMT
> "x."),
> > + trace->begin, trace->end);
>
> It is CORE_ADDR, not bfd_vma. Therefore use paddress.
Fixed. Changed this to a warning.
> > +
> > + gdb_disassembly (gdbarch, current_uiout, 0, flags, -1,
> > + trace->begin, trace->end + 1); }
> > +
> > +static void
> > +cmd_btrace (char *args, int from_tty) {
> > + struct thread_info *thread = find_thread_ptid (inferior_ptid);
> > + struct btrace_block *trace = NULL;
> > + int flags = 0;
>
> Use enum.
Flags is a bit-vector. The enum just provides names for the bits.
> > +
> > + if (!thread)
> > + {
> > + error (_("No thread."));
> > + return;
>
> Excessive return.
Fixed.
[...]
> > + VEC (btrace_block_s) *btrace = NULL;
> > + struct cleanup *cleanup;
> > + struct get_number_or_range_state state;
> > + unsigned int i;
> > +
> > + cleanup = make_cleanup (xfree, btrace);
>
> You must use VEC_cleanup here, not xfree.
Fixed.
> > + init_number_or_range (&state, args);
> > + while (!state.finished)
> > + {
> > + int index = get_number_or_range (&state);
>
> Empty line after declarations.
Fixed.
> > + if (!index)
> > + {
> > + error (_("Args must be numbers or '$' variables."));
> > + return;
>
> Excessive return.
Fixed.
> > + }
> > +
> > + trace = read_btrace (thread, index - 1);
> > + if (!trace)
> > + continue;
> > +
> > + VEC_safe_push (btrace_block_s, btrace, trace);
> > + }
> > +
> > + i = VEC_length (btrace_block_s, btrace);
> > + while (i--)
> > + do_btrace (VEC_index (btrace_block_s, btrace, i), flags);
> > +
> > + do_cleanups (cleanup);
> > + return;
>
> The function is a bit spaghetting, maybe you could split it for the
> different
> cases. Just optional.
I split the function into argument processing and trace printing.
> > + }
> > +
> > + if (args && *args)
> > + {
> > + error (_("Junk after argument: %s"), args);
> > + return;
>
> Excessive return.
Fixed.
[...]
> > + add_cmd ("branchtrace", class_btrace, NULL,
> > + _("Recording a branch trace."), &cmdlist);
>
> Incorrect indentation, it would be (using tab):
> add_cmd ("branchtrace", class_btrace, NULL,
> _("Recording a branch trace."), &cmdlist); but you can:
> add_cmd ("branchtrace", class_btrace, NULL, _("Recording a branch
> trace."),
> &cmdlist);
Fixed.
> > + add_prefix_cmd ("btrace", class_btrace, cmd_btrace, _("\
> > +Disassemble the selected branch trace block.\n\n\ With a /m modifier,
> > +source lines are included (if available).\n\ With a /r modifier, raw
> > +instructions in hex are included.\n\n\ Without arguments, selects the
> > +chronologically preceding block.\n\ With \"+[<n>]\" argument, selects
> > +the n-th chronologically preceding block.\n\ With \"-[<n>]\"
> > +argument, selects the n-th chronologically succeeding block.\n\ With
> > +one positive integer argument, selects the respective block.\n\ With
> > +a range argument \"<l>-<h>\", selects the h-th block and disassembles
> > +\ blocks in the range in reverse (i.e. original control flow) order.\n"),
> > + &btcmdlist, "btrace ", 1, &cmdlist);
>
> In many cases - you should use tab character instead of 8 spaces.
Fixed.
Do you happen to know how to tell emacs to use tab for indentation?
[...]
> > "List of classes of commands:"
> > ""
> > "aliases -- Aliases of other commands"
> > + "branchtrace -- Recording a branch trace"
>
> I am not sure if it is worth a new class but it does not fit much in
> 'tracepoints'.
It didn't fit anywhere, really, so I ended up adding a new class.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 05/16] cli, btrace: add btrace cli
2012-05-31 15:33 ` Metzger, Markus T
@ 2012-06-01 18:42 ` Jan Kratochvil
2012-06-05 9:56 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-06-01 18:42 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: kettenis, gdb-patches, markus.t.metzger
On Thu, 31 May 2012 17:32:03 +0200, Metzger, Markus T wrote:
> > > +static int
> > > +thread_callback (struct thread_info *tinfo, void *arg)
> >
> > Despite it is static there are some wishes for GDB all the functions should
> > have the filename prefix, therefore btrace_thread_callback here.
>
> I pity the maintainer of gdb/dwarf2-frame-tailcall.c;-)
>
> You mentioned this for another patch, already. If this is gdb style, I can
> certainly name my functions accordingly. I just don't see this a lot in
> other gdb files, and it results in odd and quite lengthy names.
Leaving this for comments from others.
> > But enable_btrace should error on its own as I have recommended.
>
> Will fix once the situation with gdbserver and shared code is clear.
But this part is in gdb/btrace.c, there is 'error' always available.
But I agree gdb/common/ currently cannot use it.
> > > + if (number_is_in_list (range, tinfo->num))
> > > + {
> > > + /* Switching threads makes it easier for targets like kgdb, where
> > > we
> > need
> > > + to switch cpus, as well. */
> > > + switch_to_thread (tinfo->ptid);
> >
> > In such case it should be switched in the most bottom function.
>
> I can move it to the enable and disable functions. This will result in a few
> extra switches back to the selected thread when processing a list of
> threads. I hope that's OK.
Yes, I find it better for future fixes of the underlying functions to accept
tinfo/tp/ptid_t.
> I originally did not intend to switch threads, at all. All the btrace
> functions take the thread to operate on as explicit argument.
>
> When I later added btrace support to kgdb, I realized that I had to switch
> cpu's in order to perform certain operations. I should really do this inside
> kgdb, but it was so much easier just to switch threads in gdb.
>
> If you're not OK with this, I can remove all the thread switching and look for
> a solution in kgdb.
Yes, it should be fixed kgdb. I do not know the kgdb codebase, though.
> > > +static void
> > > +cmd_btrace (char *args, int from_tty) {
> > > + struct thread_info *thread = find_thread_ptid (inferior_ptid);
> > > + struct btrace_block *trace = NULL;
> > > + int flags = 0;
> >
> > Use enum.
>
> Flags is a bit-vector. The enum just provides names for the bits.
It does not matter, you can enumval1 | enumval2 as long as they do not share
any bits. There is even specific pretty printer support for such case:
commit eb28de4a09f016d3de7caccec781eb70995a4001
http://sourceware.org/bugzilla/show_bug.cgi?id=13281
gdb.python/py-pp-maint.c
+enum flag_enum
+ {
+ FLAG_1 = 1,
+ FLAG_2 = 2,
+ FLAG_3 = 4,
+ ALL = FLAG_1 | FLAG_2 | FLAG_3
+ };
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 05/16] cli, btrace: add btrace cli
2012-06-01 18:42 ` Jan Kratochvil
@ 2012-06-05 9:56 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-05 9:56 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 2000 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Friday, June 01, 2012 8:42 PM
> > > But enable_btrace should error on its own as I have recommended.
> >
> > Will fix once the situation with gdbserver and shared code is clear.
>
> But this part is in gdb/btrace.c, there is 'error' always available.
>
> But I agree gdb/common/ currently cannot use it.
I am using error () in gdb proper and I further removed the use of errno
except for checking errors in syscall (), mmap (), and munmap ().
I'm not so sure what to do with gdbserver, though. I'm writing error messages
to stderr and write_enn () to the out buffer. The gdb side can then only print
that the operation failed. That's what others seem to do, as well.
[...]
> > If you're not OK with this, I can remove all the thread switching and
> > look for a solution in kgdb.
>
> Yes, it should be fixed kgdb. I do not know the kgdb codebase, though.
I removed the thread switching.
> > > > +static void
> > > > +cmd_btrace (char *args, int from_tty) {
> > > > + struct thread_info *thread = find_thread_ptid (inferior_ptid);
> > > > + struct btrace_block *trace = NULL;
> > > > + int flags = 0;
> > >
> > > Use enum.
> >
> > Flags is a bit-vector. The enum just provides names for the bits.
>
> It does not matter, you can enumval1 | enumval2 as long as they do not
> share any bits. There is even specific pretty printer support for such
> case:
> commit eb28de4a09f016d3de7caccec781eb70995a4001
> http://sourceware.org/bugzilla/show_bug.cgi?id=13281
> gdb.python/py-pp-maint.c
> +enum flag_enum
> + {
> + FLAG_1 = 1,
> + FLAG_2 = 2,
> + FLAG_3 = 4,
> + ALL = FLAG_1 | FLAG_2 | FLAG_3
> + };
This particular case is about gdb_disassembly () flags, which are defined via
macros. Sorry, my previous comment was wrong.
I did change it for btrace_list_flags (btrace.c) and for
print_source_lines_flags
(symtab.h). Beware that this won't compile in C++.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 11/16] test, btrace: add branch trace tests
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (11 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 05/16] cli, btrace: add btrace cli markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 09/16] btrace, linux: add linux native btrace target ops markus.t.metzger
` (5 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Add tests covering btrace enable/disable/auto and btrace list.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
* .gitignore: add gdb/testsuite/gdb.btrace/list.x
gdb/testsuite/
* configure.ac: Add gdb.btrace makefile
gdb/testsuite/lib/
* btrace.exp: New file
gdb/testsuite/gdb.btrace/
* Makefile.in: New file
* enable.exp: New file
* list.exp: New file
* list.s: New file
---
.gitignore | 2 +
gdb/testsuite/configure.ac | 2 +-
gdb/testsuite/gdb.btrace/Makefile.in | 13 ++
gdb/testsuite/gdb.btrace/dec.c | 4 +
gdb/testsuite/gdb.btrace/enable.exp | 83 ++++++++++++++
gdb/testsuite/gdb.btrace/inc.c | 4 +
gdb/testsuite/gdb.btrace/list.exp | 169 ++++++++++++++++++++++++++++
gdb/testsuite/gdb.btrace/list.s | 68 +++++++++++
gdb/testsuite/gdb.btrace/list_function.c | 12 ++
gdb/testsuite/gdb.btrace/list_function.exp | 59 ++++++++++
gdb/testsuite/lib/btrace.exp | 72 ++++++++++++
11 files changed, 487 insertions(+), 1 deletions(-)
create mode 100755 gdb/testsuite/gdb.btrace/Makefile.in
create mode 100644 gdb/testsuite/gdb.btrace/dec.c
create mode 100644 gdb/testsuite/gdb.btrace/enable.exp
create mode 100644 gdb/testsuite/gdb.btrace/inc.c
create mode 100644 gdb/testsuite/gdb.btrace/list.exp
create mode 100644 gdb/testsuite/gdb.btrace/list.s
create mode 100644 gdb/testsuite/gdb.btrace/list_function.c
create mode 100644 gdb/testsuite/gdb.btrace/list_function.exp
create mode 100644 gdb/testsuite/lib/btrace.exp
diff --git a/.gitignore b/.gitignore
index dc1bf3f..94e43b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ lost+found
*.log
*.sum
+
+gdb/testsuite/gdb.btrace/list.x
diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac
index d9ab9f7..164a505 100644
--- a/gdb/testsuite/configure.ac
+++ b/gdb/testsuite/configure.ac
@@ -98,4 +98,4 @@ AC_OUTPUT([Makefile \
gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
- gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile])
+ gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile gdb.btrace/Makefile])
diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
new file mode 100755
index 0000000..16afe0a
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/Makefile.in
@@ -0,0 +1,13 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+.PHONY: all clean mostlyclean distclean realclean
+
+all info install-info dvi install uninstall installcheck check:
+ @echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+ -rm -f *.o *.x *.diff *~ *.bad core
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log gdb.log gdb.sum
diff --git a/gdb/testsuite/gdb.btrace/dec.c b/gdb/testsuite/gdb.btrace/dec.c
new file mode 100644
index 0000000..abe1ff5
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/dec.c
@@ -0,0 +1,4 @@
+extern int dec (int x)
+{
+ return x - 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp
new file mode 100644
index 0000000..a312ee3
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable.exp
@@ -0,0 +1,83 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+ verbose "Tests ignored for all but x86 based targets."
+ return
+}
+
+load_lib btrace.exp
+
+set testfile "list"
+
+# check for btrace support
+if { [skip_btrace_tests] } { continue }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+
+# automatic enabling can be turned on without an inferior
+gdb_test_no_output "btrace enable auto" "btrace enable 1.0"
+
+# we cannot enable it twice
+gdb_test "btrace enable auto" "Automatic branch trace enabling already on." "btrace enable 1.1"
+
+# but we can disable it
+gdb_test_no_output "btrace disable auto" "btrace enable 1.2"
+
+# we cannot disable it twice
+gdb_test "btrace disable auto" "Automatic branch trace enabling already off." "btrace enable 1.3"
+
+# we cannot enable/disable trace without a thread
+gdb_test "btrace enable" "Couldn't enable branch tracing: no inferior thread." "btrace enable 2.0"
+gdb_test "btrace disable" "Couldn't disable branch tracing: no inferior thread." "btrace enable 2.1"
+
+
+# start a debuggee program
+if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+ untested ${testfile}.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# automatic enabling is off.
+runto test_1
+
+# since we support btrace, we should be able to enable it
+gdb_test_no_output "btrace enable" "btrace enable 3.0"
+
+# btrace is now enabled; we should not be able to enable it twice
+gdb_test "btrace enable" "Couldn't enable branch tracing.*" "btrace enable 3.1"
+
+# btrace is still enabled; we should be able to disable it
+gdb_test_no_output "btrace disable" "btrace enable 3.2"
+
+# btrace is now disabled; we should not be able to disable it twice
+gdb_test "btrace disable" "Couldn't disable branch tracing.*" "btrace enable 3.3"
+
+# rerun with automatic enabling on
+gdb_test_no_output "btrace enable auto"
+runto test_1
+
+# btrace is implicitly enabled; we should not be able to enable it twice
+gdb_test "btrace enable" "Couldn't enable branch tracing.*" "btrace enable 4.0"
+
+return 0
diff --git a/gdb/testsuite/gdb.btrace/inc.c b/gdb/testsuite/gdb.btrace/inc.c
new file mode 100644
index 0000000..03966f3
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/inc.c
@@ -0,0 +1,4 @@
+extern int inc (int x)
+{
+ return x + 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/list.exp b/gdb/testsuite/gdb.btrace/list.exp
new file mode 100644
index 0000000..de33b59
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list.exp
@@ -0,0 +1,169 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+ verbose "Tests ignored for all but x86 based targets."
+ return
+}
+
+load_lib btrace.exp
+
+set testfile "list"
+
+# check for btrace support
+if { [skip_btrace_tests] } { continue }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+ untested ${testfile}.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Automatically enable branch tracing.
+gdb_test_no_output "btr enable auto"
+
+# Make sure we don't die when enabling trace for a newly created thread.
+runto test_1
+# we expect some trace at this point, but we don't really know how much or how
+# it would look like. Ignore it.
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.1"
+
+# We assume 5 bytes for call.
+gdb_test "stepi" "0x0*400215 in test_1.*" ""
+
+# We assume 5 bytes for call.
+gdb_test "btr list /af" "
+1 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.2"
+
+gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
+gdb_test "stepi" "0x0*40021a in test_1.*" ""
+
+# We assume 5 bytes for call.
+gdb_test "btr list /af" "
+1 *0x0*40021a - 0x0*40021a in test_1 \\(\\)\r
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.3"
+
+# List a single block.
+gdb_test "btr list /af 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.4"
+
+# List a range of blocks.
+gdb_test "btr list /af 2-4" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.5"
+
+# We ignore too big upper bounds.
+gdb_test "btr list /af 3-9" "
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.6"
+
+# If the entire range is out of bounds, the list is empty.
+gdb_test "btr list /a 9-18" "" "btrace list 1.7"
+
+# Check modifiers individually
+gdb_test "btr list /a 2" "
+2 *0x0*400200 - 0x0*400200" "btrace list 1.8"
+
+gdb_test "btr list /f 2" "
+2 *in test_1_sub \\(\\)" "btrace list 1.9"
+
+# Check order of modifiers
+gdb_test "btr list /fa 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.10"
+
+gdb_test "btr list /f /a 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.11"
+
+gdb_test "btr list /a /f 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.12"
+
+
+# Proceed to the next test.
+runto test_2
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400231 in test_2.*" ""
+
+# We have not seen a branch, yet, so there is no trace.
+gdb_test "btr list" "No trace." "btrace list 2.1"
+
+gdb_test "stepi" "0x0*400220 in test_2_sub.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400220 in test_2_sub \\(\\)" "btrace list 2.2"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400221 in test_2_sub.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400221 in test_2_sub \\(\\)" "btrace list 2.3"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400222 in test_2_sub.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400222 in test_2_sub \\(\\)" "btrace list 2.4"
+
+
+# Proceed to the next test.
+runto test_3
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "stepi" "0x0*400260 in test_3.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.1"
+
+gdb_test "stepi" "0x0*400250 in test_3.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400250 - 0x0*400250 in test_3 \\(\\)\r
+2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.2"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400251 in test_3.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400250 - 0x0*400251 in test_3 \\(\\)\r
+2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.3"
+
+return 0
diff --git a/gdb/testsuite/gdb.btrace/list.s b/gdb/testsuite/gdb.btrace/list.s
new file mode 100644
index 0000000..7659a8b
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list.s
@@ -0,0 +1,68 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+ .text
+ .globl _start
+ .globl main
+ .globl test_1
+ .globl test_2
+ .globl test_3
+ .align 0x100 # 0x400100
+_start:
+ call main
+ hlt
+
+ .align 0x10 # 0x400110
+main:
+ call test_1
+ call test_2
+ call test_3
+ ret
+
+ .align 0x100 # 0x400200
+test_1_sub:
+ ret
+
+ .align 0x10 # 0x400210
+test_1:
+ call test_1_sub
+ call test_1_sub
+ nop
+ ret
+
+ .align 0x10 # 0x400220
+test_2_sub:
+ nop
+ nop
+ ret
+
+ .align 0x10 # 0x400230
+test_2:
+ nop
+ call test_2_sub
+ ret
+
+ .align 0x10 # 0x400240
+test_3:
+ jmp .L3.1
+ .align 0x10 # 0x400250
+.L3.2:
+ nop
+ ret
+ .align 0x10 # 0x400260
+.L3.1:
+ jmp .L3.2
diff --git a/gdb/testsuite/gdb.btrace/list_function.c b/gdb/testsuite/gdb.btrace/list_function.c
new file mode 100644
index 0000000..0372126
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_function.c
@@ -0,0 +1,12 @@
+extern int inc (int);
+extern int dec (int);
+
+extern int main (void)
+{
+ int x = 0;
+
+ x = inc (x);
+ x = dec (x);
+
+ return x; /* End of main breakpoint location */
+}
diff --git a/gdb/testsuite/gdb.btrace/list_function.exp b/gdb/testsuite/gdb.btrace/list_function.exp
new file mode 100644
index 0000000..9585289
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_function.exp
@@ -0,0 +1,59 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+load_lib btrace.exp
+
+set testfile "list_function"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}.x
+
+set sources "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/inc.c ${srcdir}/${subdir}/dec.c"
+
+# check for btrace support
+if { [skip_btrace_tests] } { continue }
+
+if { [gdb_compile "${sources}" "${binfile}" executable {debug}] != "" } {
+ untested list_function.exp
+ return -1
+}
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+set bp_location [gdb_get_line_number "End of main breakpoint location"]
+
+gdb_breakpoint $bp_location
+
+gdb_test_no_output "btr enable"
+
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$srcfile:$bp_location.*"
+
+gdb_test "btr list /f" "
+1 *in main \\(\\)\r
+2 *in dec \\(\\)\r
+3 *in main \\(\\)\r
+4 *in inc \\(\\)" "btrace list function 1.0"
+
+return 0
diff --git a/gdb/testsuite/lib/btrace.exp b/gdb/testsuite/lib/btrace.exp
new file mode 100644
index 0000000..92ca50f
--- /dev/null
+++ b/gdb/testsuite/lib/btrace.exp
@@ -0,0 +1,72 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+proc btrace_assemble { testfile } {
+ global srcdir
+ global objdir
+ global subdir
+
+ set srcfile ${srcdir}/${subdir}/${testfile}.s
+ set objfile ${objdir}/${subdir}/${testfile}.o
+ set binfile ${objdir}/${subdir}/${testfile}.x
+
+ if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return "" }
+
+ if {[target_link ${objfile} ${binfile} "-Ttext 0x400100"] != ""} { return "" }
+
+ return ${binfile}
+}
+
+proc skip_btrace_tests {} {
+ global gdb_prompt
+
+ set testfile "list"
+ set skip 0
+
+ if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+ return 1
+ }
+
+ gdb_exit
+ gdb_start
+ gdb_load $binfile
+
+ runto main
+
+ gdb_test_multiple "btrace enable" "check btrace support" {
+ -re "You can't do that when your target is.*" {
+ unsupported "target does not support btrace"
+ set skip 1
+ }
+ -re "Couldn't enable branch tracing.*Operation not supported" {
+ unsupported "target does not support btrace"
+ set skip 1
+ }
+ -re "$gdb_prompt $" {}
+ }
+ gdb_exit
+ remote_file build delete $testfile
+
+ return $skip
+}
+
+proc btrace_reset_trace {} {
+ gdb_test_no_output "btr disable"
+ gdb_test_no_output "btr enable"
+
+ gdb_test "btr list" "No trace." "reset btrace"
+}
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 11/16] test, btrace: add branch trace tests
2012-05-23 11:25 ` [PATCH 11/16] test, btrace: add branch trace tests markus.t.metzger
@ 2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 11:37 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:44 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:26 +0200, markus.t.metzger@intel.com wrote:
> --- a/.gitignore
> +++ b/.gitignore
> @@ -38,3 +38,5 @@ lost+found
>
> *.log
> *.sum
> +
> +gdb/testsuite/gdb.btrace/list.x
This is excessive.
> diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac
> index d9ab9f7..164a505 100644
> --- a/gdb/testsuite/configure.ac
> +++ b/gdb/testsuite/configure.ac
> @@ -98,4 +98,4 @@ AC_OUTPUT([Makefile \
> gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
> gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
> gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
> - gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile])
> + gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile gdb.btrace/Makefile])
> diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
> new file mode 100755
> index 0000000..16afe0a
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/Makefile.in
> @@ -0,0 +1,13 @@
> +VPATH = @srcdir@
> +srcdir = @srcdir@
> +
> +.PHONY: all clean mostlyclean distclean realclean
> +
> +all info install-info dvi install uninstall installcheck check:
> + @echo "Nothing to be done for $@..."
> +
> +clean mostlyclean:
> + -rm -f *.o *.x *.diff *~ *.bad core
> +
> +distclean maintainer-clean realclean: clean
> + -rm -f Makefile config.status config.log gdb.log gdb.sum
> diff --git a/gdb/testsuite/gdb.btrace/dec.c b/gdb/testsuite/gdb.btrace/dec.c
> new file mode 100644
> index 0000000..abe1ff5
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/dec.c
> @@ -0,0 +1,4 @@
Missing copyright header.
> +extern int dec (int x)
> +{
> + return x - 1;
> +}
> diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp
> new file mode 100644
> index 0000000..a312ee3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/enable.exp
> @@ -0,0 +1,83 @@
> +# Copyright 2012 Free Software Foundation, Inc.
> +#
> +# Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +
> +if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
> + verbose "Tests ignored for all but x86 based targets."
> + return
> +}
> +
> +load_lib btrace.exp
> +
> +set testfile "list"
> +
> +# check for btrace support
> +if { [skip_btrace_tests] } { continue }
> +
> +# start fresh - without an executable
> +gdb_exit
> +gdb_start
> +
> +
> +# automatic enabling can be turned on without an inferior
> +gdb_test_no_output "btrace enable auto" "btrace enable 1.0"
> +
> +# we cannot enable it twice
> +gdb_test "btrace enable auto" "Automatic branch trace enabling already on." "btrace enable 1.1"
> +
> +# but we can disable it
> +gdb_test_no_output "btrace disable auto" "btrace enable 1.2"
> +
> +# we cannot disable it twice
> +gdb_test "btrace disable auto" "Automatic branch trace enabling already off." "btrace enable 1.3"
> +
> +# we cannot enable/disable trace without a thread
> +gdb_test "btrace enable" "Couldn't enable branch tracing: no inferior thread." "btrace enable 2.0"
> +gdb_test "btrace disable" "Couldn't disable branch tracing: no inferior thread." "btrace enable 2.1"
> +
> +
> +# start a debuggee program
> +if { [set binfile [btrace_assemble ${testfile}]] == "" } {
> + untested ${testfile}.exp
> + return -1
> +}
> +
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load $binfile
> +
> +# automatic enabling is off.
> +runto test_1
> +
> +# since we support btrace, we should be able to enable it
> +gdb_test_no_output "btrace enable" "btrace enable 3.0"
> +
> +# btrace is now enabled; we should not be able to enable it twice
> +gdb_test "btrace enable" "Couldn't enable branch tracing.*" "btrace enable 3.1"
> +
> +# btrace is still enabled; we should be able to disable it
> +gdb_test_no_output "btrace disable" "btrace enable 3.2"
> +
> +# btrace is now disabled; we should not be able to disable it twice
> +gdb_test "btrace disable" "Couldn't disable branch tracing.*" "btrace enable 3.3"
> +
> +# rerun with automatic enabling on
> +gdb_test_no_output "btrace enable auto"
> +runto test_1
> +
> +# btrace is implicitly enabled; we should not be able to enable it twice
> +gdb_test "btrace enable" "Couldn't enable branch tracing.*" "btrace enable 4.0"
> +
> +return 0
> diff --git a/gdb/testsuite/gdb.btrace/inc.c b/gdb/testsuite/gdb.btrace/inc.c
> new file mode 100644
> index 0000000..03966f3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/inc.c
> @@ -0,0 +1,4 @@
> +extern int inc (int x)
> +{
> + return x + 1;
> +}
> diff --git a/gdb/testsuite/gdb.btrace/list.exp b/gdb/testsuite/gdb.btrace/list.exp
> new file mode 100644
> index 0000000..de33b59
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/list.exp
> @@ -0,0 +1,169 @@
> +# Copyright 2012 Free Software Foundation, Inc.
> +#
> +# Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +
> +if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
> + verbose "Tests ignored for all but x86 based targets."
> + return
> +}
> +
> +load_lib btrace.exp
> +
> +set testfile "list"
> +
> +# check for btrace support
> +if { [skip_btrace_tests] } { continue }
> +
> +# start fresh - without an executable
> +gdb_exit
> +gdb_start
> +
> +if { [set binfile [btrace_assemble ${testfile}]] == "" } {
> + untested ${testfile}.exp
> + return -1
> +}
> +
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load $binfile
> +
> +# Automatically enable branch tracing.
> +gdb_test_no_output "btr enable auto"
> +
> +# Make sure we don't die when enabling trace for a newly created thread.
> +runto test_1
> +# we expect some trace at this point, but we don't really know how much or how
> +# it would look like. Ignore it.
> +
> +# Reset branch trace so we get predictable output.
> +btrace_reset_trace
> +
> +gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
> +
> +gdb_test "btr list /af" "
> +1 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.1"
> +
> +# We assume 5 bytes for call.
> +gdb_test "stepi" "0x0*400215 in test_1.*" ""
> +
> +# We assume 5 bytes for call.
> +gdb_test "btr list /af" "
> +1 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.2"
> +
> +gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
> +gdb_test "stepi" "0x0*40021a in test_1.*" ""
> +
> +# We assume 5 bytes for call.
> +gdb_test "btr list /af" "
> +1 *0x0*40021a - 0x0*40021a in test_1 \\(\\)\r
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
> +3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
> +4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.3"
> +
> +# List a single block.
> +gdb_test "btr list /af 2" "
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.4"
> +
> +# List a range of blocks.
> +gdb_test "btr list /af 2-4" "
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
> +3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
> +4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.5"
> +
> +# We ignore too big upper bounds.
> +gdb_test "btr list /af 3-9" "
> +3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
> +4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.6"
> +
> +# If the entire range is out of bounds, the list is empty.
> +gdb_test "btr list /a 9-18" "" "btrace list 1.7"
> +
> +# Check modifiers individually
> +gdb_test "btr list /a 2" "
> +2 *0x0*400200 - 0x0*400200" "btrace list 1.8"
> +
> +gdb_test "btr list /f 2" "
> +2 *in test_1_sub \\(\\)" "btrace list 1.9"
> +
> +# Check order of modifiers
> +gdb_test "btr list /fa 2" "
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.10"
> +
> +gdb_test "btr list /f /a 2" "
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.11"
> +
> +gdb_test "btr list /a /f 2" "
> +2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.12"
> +
> +
> +# Proceed to the next test.
> +runto test_2
> +
> +# Reset branch trace so we get predictable output.
> +btrace_reset_trace
> +
> +# We assume 1 byte for nop.
> +gdb_test "stepi" "0x0*400231 in test_2.*" ""
> +
> +# We have not seen a branch, yet, so there is no trace.
> +gdb_test "btr list" "No trace." "btrace list 2.1"
> +
> +gdb_test "stepi" "0x0*400220 in test_2_sub.*" ""
> +
> +gdb_test "btr list /af" "
> +1 *0x0*400220 - 0x0*400220 in test_2_sub \\(\\)" "btrace list 2.2"
> +
> +# We assume 1 byte for nop.
> +gdb_test "stepi" "0x0*400221 in test_2_sub.*" ""
> +
> +# We assume 1 byte for nop.
> +gdb_test "btr list /af" "
> +1 *0x0*400220 - 0x0*400221 in test_2_sub \\(\\)" "btrace list 2.3"
> +
> +# We assume 1 byte for nop.
> +gdb_test "stepi" "0x0*400222 in test_2_sub.*" ""
> +
> +# We assume 1 byte for nop.
> +gdb_test "btr list /af" "
> +1 *0x0*400220 - 0x0*400222 in test_2_sub \\(\\)" "btrace list 2.4"
> +
> +
> +# Proceed to the next test.
> +runto test_3
> +
> +# Reset branch trace so we get predictable output.
> +btrace_reset_trace
> +
> +gdb_test "stepi" "0x0*400260 in test_3.*" ""
> +
> +gdb_test "btr list /af" "
> +1 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.1"
> +
> +gdb_test "stepi" "0x0*400250 in test_3.*" ""
> +
> +gdb_test "btr list /af" "
> +1 *0x0*400250 - 0x0*400250 in test_3 \\(\\)\r
> +2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.2"
> +
> +# We assume 1 byte for nop.
> +gdb_test "stepi" "0x0*400251 in test_3.*" ""
> +
> +# We assume 1 byte for nop.
> +gdb_test "btr list /af" "
> +1 *0x0*400250 - 0x0*400251 in test_3 \\(\\)\r
> +2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.3"
> +
> +return 0
> diff --git a/gdb/testsuite/gdb.btrace/list.s b/gdb/testsuite/gdb.btrace/list.s
> new file mode 100644
> index 0000000..7659a8b
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/list.s
It should end with .S as it is used in GDB. It should have i386 in its name
as it is x86-specific file.
> @@ -0,0 +1,68 @@
> +# Copyright 2012 Free Software Foundation, Inc.
> +#
> +# Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +
> + .text
> + .globl _start
> + .globl main
> + .globl test_1
> + .globl test_2
> + .globl test_3
> + .align 0x100 # 0x400100
> +_start:
> + call main
> + hlt
> +
> + .align 0x10 # 0x400110
> +main:
> + call test_1
> + call test_2
> + call test_3
> + ret
> +
> + .align 0x100 # 0x400200
> +test_1_sub:
> + ret
> +
> + .align 0x10 # 0x400210
> +test_1:
> + call test_1_sub
> + call test_1_sub
> + nop
> + ret
> +
> + .align 0x10 # 0x400220
> +test_2_sub:
> + nop
> + nop
> + ret
> +
> + .align 0x10 # 0x400230
> +test_2:
> + nop
> + call test_2_sub
> + ret
> +
> + .align 0x10 # 0x400240
> +test_3:
> + jmp .L3.1
> + .align 0x10 # 0x400250
> +.L3.2:
> + nop
> + ret
> + .align 0x10 # 0x400260
> +.L3.1:
> + jmp .L3.2
> diff --git a/gdb/testsuite/gdb.btrace/list_function.c b/gdb/testsuite/gdb.btrace/list_function.c
> new file mode 100644
> index 0000000..0372126
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/list_function.c
> @@ -0,0 +1,12 @@
Missing copyright header.
> +extern int inc (int);
> +extern int dec (int);
> +
> +extern int main (void)
> +{
> + int x = 0;
> +
> + x = inc (x);
> + x = dec (x);
> +
> + return x; /* End of main breakpoint location */
> +}
> diff --git a/gdb/testsuite/gdb.btrace/list_function.exp b/gdb/testsuite/gdb.btrace/list_function.exp
> new file mode 100644
> index 0000000..9585289
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/list_function.exp
> @@ -0,0 +1,59 @@
> +# Copyright 2012 Free Software Foundation, Inc.
> +#
> +# Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +
> +load_lib btrace.exp
> +
> +set testfile "list_function"
> +set srcfile ${testfile}.c
> +set binfile ${objdir}/${subdir}/${testfile}.x
> +
> +set sources "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/inc.c ${srcdir}/${subdir}/dec.c"
> +
> +# check for btrace support
> +if { [skip_btrace_tests] } { continue }
> +
> +if { [gdb_compile "${sources}" "${binfile}" executable {debug}] != "" } {
> + untested list_function.exp
> + return -1
> +}
> +# start fresh - without an executable
> +gdb_exit
> +gdb_start
> +
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load $binfile
Why not to use prepare_for_testing here?
> +
> +if ![runto_main] then {
> + fail "Can't run to main"
> + return 0
> +}
> +
> +set bp_location [gdb_get_line_number "End of main breakpoint location"]
> +
> +gdb_breakpoint $bp_location
> +
> +gdb_test_no_output "btr enable"
> +
> +gdb_continue_to_breakpoint "cont to $bp_location" ".*$srcfile:$bp_location.*"
> +
> +gdb_test "btr list /f" "
> +1 *in main \\(\\)\r
> +2 *in dec \\(\\)\r
> +3 *in main \\(\\)\r
> +4 *in inc \\(\\)" "btrace list function 1.0"
> +
> +return 0
> diff --git a/gdb/testsuite/lib/btrace.exp b/gdb/testsuite/lib/btrace.exp
> new file mode 100644
> index 0000000..92ca50f
> --- /dev/null
> +++ b/gdb/testsuite/lib/btrace.exp
> @@ -0,0 +1,72 @@
> +# Copyright 2012 Free Software Foundation, Inc.
> +#
> +# Contributed by Intel Corp. <markus.t.metzger@intel.com>
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +
> +proc btrace_assemble { testfile } {
> + global srcdir
> + global objdir
> + global subdir
> +
> + set srcfile ${srcdir}/${subdir}/${testfile}.s
> + set objfile ${objdir}/${subdir}/${testfile}.o
> + set binfile ${objdir}/${subdir}/${testfile}.x
> +
> + if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return "" }
> +
> + if {[target_link ${objfile} ${binfile} "-Ttext 0x400100"] != ""} { return "" }
> +
> + return ${binfile}
> +}
> +
> +proc skip_btrace_tests {} {
> + global gdb_prompt
> +
> + set testfile "list"
> + set skip 0
> +
> + if { [set binfile [btrace_assemble ${testfile}]] == "" } {
> + return 1
> + }
> +
> + gdb_exit
> + gdb_start
> + gdb_load $binfile
> +
> + runto main
Rather always check for 'runto' error codes, it sometimes happens and the rest
of testfile does not recover well in such case.
> +
> + gdb_test_multiple "btrace enable" "check btrace support" {
> + -re "You can't do that when your target is.*" {
Missing termination:
-re "You can't do that when your target is.*\r\n$gdb_prompt $" {
As otherwise it will be racy, the leftover prompt can be read in by next
gdb_test.
> + unsupported "target does not support btrace"
> + set skip 1
Here should be:
xfail "check btrace support"
> + }
> + -re "Couldn't enable branch tracing.*Operation not supported" {
Again.
> + unsupported "target does not support btrace"
> + set skip 1
Here should be:
xfail "check btrace support"
> + }
> + -re "$gdb_prompt $" {}
One may disagree but I think this block should contain:
pass "check btrace support"
> + }
> + gdb_exit
> + remote_file build delete $testfile
> +
> + return $skip
> +}
> +
> +proc btrace_reset_trace {} {
> + gdb_test_no_output "btr disable"
> + gdb_test_no_output "btr enable"
> +
> + gdb_test "btr list" "No trace." "reset btrace"
For real correctness either
gdb_test "btr list" "No trace\\." "reset btrace"
or:
gdb_test "btr list" {No trace\.} "reset btrace"
> +}
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 11/16] test, btrace: add branch trace tests
2012-05-30 20:44 ` Jan Kratochvil
@ 2012-06-01 11:37 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-01 11:37 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 2691 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:44 PM
Thanks for your review!
> > *.log
> > *.sum
> > +
> > +gdb/testsuite/gdb.btrace/list.x
>
> This is excessive.
Removed.
[...]
> > +++ b/gdb/testsuite/gdb.btrace/dec.c
> > @@ -0,0 +1,4 @@
>
> Missing copyright header.
Fixed.
> > +++ b/gdb/testsuite/gdb.btrace/list.s
>
> It should end with .S as it is used in GDB. It should have i386 in its name
> as it
> is x86-specific file.
I renamed it to x86-list.S. It is used for i386 and for x86_64.
[...]
> > +++ b/gdb/testsuite/gdb.btrace/list_function.c
> > @@ -0,0 +1,12 @@
>
> Missing copyright header.
Fixed.
[...]
> > +gdb_reinitialize_dir $srcdir/$subdir
> > +gdb_load $binfile
>
> Why not to use prepare_for_testing here?
Prepare_for_testing uses gcc for linking which pulls in the startup object.
I need more control over what gets linked since I want to be able to rely
on the exact addresses in the final executable.
I used it in list_function.exp, though. Thanks for the hint.
[...]
> > + runto main
>
> Rather always check for 'runto' error codes, it sometimes happens and the
> rest of testfile does not recover well in such case.
Fixed.
> > +
> > + gdb_test_multiple "btrace enable" "check btrace support" {
> > + -re "You can't do that when your target is.*" {
>
> Missing termination:
> -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
>
> As otherwise it will be racy, the leftover prompt can be read in by next
> gdb_test.
Fixed.
> > + unsupported "target does not support btrace"
> > + set skip 1
>
> Here should be:
> xfail "check btrace support"
Fixed.
> > + }
> > + -re "Couldn't enable branch tracing.*Operation not supported"
> > + {
>
> Again.
Fixed.
> > + unsupported "target does not support btrace"
> > + set skip 1
>
> Here should be:
> xfail "check btrace support"
Fixed.
> > + }
>
> > + -re "$gdb_prompt $" {}
>
> One may disagree but I think this block should contain:
> pass "check btrace support"
I added it.
> > + }
> > + gdb_exit
> > + remote_file build delete $testfile
> > +
> > + return $skip
> > +}
> > +
> > +proc btrace_reset_trace {} {
> > + gdb_test_no_output "btr disable"
> > + gdb_test_no_output "btr enable"
> > +
> > + gdb_test "btr list" "No trace." "reset btrace"
>
> For real correctness either
> gdb_test "btr list" "No trace\\." "reset btrace"
> or:
> gdb_test "btr list" {No trace\.} "reset btrace"
Changed to "No trace\.". "No trace\\." wouldn't compile.
Thanks,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 09/16] btrace, linux: add linux native btrace target ops
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (12 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 11/16] test, btrace: add branch trace tests markus.t.metzger
@ 2012-05-23 11:25 ` markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-23 11:26 ` [PATCH 12/16] test, btrace: more branch tracing tests markus.t.metzger
` (4 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:25 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Implement btrace target ops for linux native based on the common linux btrace
support.
We use a separate file for this to allow sharing between multiple targets
(i.e. i386 and x86_64) and to avoid having to guard this for targets that do not
support branch tracing.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* linux-nat-btrace.h: New file
* linux-nat-btrace.c: New file
---
gdb/linux-nat-btrace.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++
gdb/linux-nat-btrace.h | 28 +++++++++++++++
2 files changed, 114 insertions(+), 0 deletions(-)
create mode 100644 gdb/linux-nat-btrace.c
create mode 100644 gdb/linux-nat-btrace.h
diff --git a/gdb/linux-nat-btrace.c b/gdb/linux-nat-btrace.c
new file mode 100644
index 0000000..f69fc6f
--- /dev/null
+++ b/gdb/linux-nat-btrace.c
@@ -0,0 +1,86 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#include "linux-nat-btrace.h"
+#include "linux-btrace.h"
+#include "btrace.h"
+#include "target.h"
+#include "gdbarch.h"
+#include "arch-utils.h"
+#include <errno.h>
+
+static int
+linux_nat_push_btrace_record (struct linux_btrace_block *raw, void *arg)
+{
+ VEC (btrace_block_s) **btrace = arg;
+ struct btrace_block *block;
+
+ if (!raw)
+ return EINVAL;
+
+ if (!btrace)
+ return EINVAL;
+
+ block = VEC_safe_push (btrace_block_s, *btrace, NULL);
+ if (!block)
+ return ENOMEM;
+
+ block->begin = raw->begin;
+ block->end = raw->end;
+
+ return 0;
+}
+
+static VEC (btrace_block_s) *
+linux_nat_read_btrace (struct btrace_target_info *tinfo)
+{
+ VEC (btrace_block_s) *btrace = NULL;
+ int errcode;
+
+ if (!tinfo)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (!tinfo->ptr_bits)
+ {
+ struct gdbarch *gdbarch = get_current_arch ();
+ if (gdbarch)
+ tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
+ }
+
+ errcode = linux_read_btrace (tinfo, linux_nat_push_btrace_record, &btrace);
+ if (errcode)
+ warning (_("error while reading branch trace data: %s. "
+ "trace might be incomplete."), safe_strerror (errcode));
+
+ return btrace;
+}
+
+void
+linux_nat_add_btrace_ops (struct target_ops *t)
+{
+ t->to_supports_btrace = linux_supports_btrace;
+ t->to_enable_btrace = linux_enable_btrace;
+ t->to_disable_btrace = linux_disable_btrace;
+ t->to_btrace_has_changed = linux_btrace_has_changed;
+ t->to_read_btrace = linux_nat_read_btrace;
+}
diff --git a/gdb/linux-nat-btrace.h b/gdb/linux-nat-btrace.h
new file mode 100644
index 0000000..cbe9c89
--- /dev/null
+++ b/gdb/linux-nat-btrace.h
@@ -0,0 +1,28 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LINUX_NAT_BTRACE_H
+#define LINUX_NAT_BTRACE_H
+
+struct target_ops;
+extern void linux_nat_add_btrace_ops (struct target_ops *);
+
+#endif /* LINUX_NAT_BTRACE_H */
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 09/16] btrace, linux: add linux native btrace target ops
2012-05-23 11:25 ` [PATCH 09/16] btrace, linux: add linux native btrace target ops markus.t.metzger
@ 2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:43 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:24 +0200, markus.t.metzger@intel.com wrote:
> diff --git a/gdb/linux-nat-btrace.c b/gdb/linux-nat-btrace.c
> new file mode 100644
> index 0000000..f69fc6f
> --- /dev/null
> +++ b/gdb/linux-nat-btrace.c
> @@ -0,0 +1,86 @@
> +/* Branch trace support for GDB, the GNU debugger.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#include "linux-nat-btrace.h"
> +#include "linux-btrace.h"
> +#include "btrace.h"
> +#include "target.h"
> +#include "gdbarch.h"
> +#include "arch-utils.h"
> +#include <errno.h>
> +
> +static int
> +linux_nat_push_btrace_record (struct linux_btrace_block *raw, void *arg)
> +{
> + VEC (btrace_block_s) **btrace = arg;
> + struct btrace_block *block;
> +
> + if (!raw)
> + return EINVAL;
> +
> + if (!btrace)
> + return EINVAL;
I did not check now but probably excessive.
> +
> + block = VEC_safe_push (btrace_block_s, *btrace, NULL);
> + if (!block)
> + return ENOMEM;
Incorrect indentation.
> +
> + block->begin = raw->begin;
> + block->end = raw->end;
Do not use alignment/indentation.
> +
> + return 0;
> +}
> +
> +static VEC (btrace_block_s) *
> +linux_nat_read_btrace (struct btrace_target_info *tinfo)
> +{
> + VEC (btrace_block_s) *btrace = NULL;
> + int errcode;
> +
> + if (!tinfo)
> + {
> + errno = EINVAL;
> + return NULL;
> + }
> + if (!tinfo->ptr_bits)
> + {
> + struct gdbarch *gdbarch = get_current_arch ();
Empty line.
> + if (gdbarch)
> + tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
> + }
> +
> + errcode = linux_read_btrace (tinfo, linux_nat_push_btrace_record, &btrace);
> + if (errcode)
> + warning (_("error while reading branch trace data: %s. "
Captitalize "Error". Use two spaces at the end.
> + "trace might be incomplete."), safe_strerror (errcode));
> +
> + return btrace;
> +}
> +
> +void
> +linux_nat_add_btrace_ops (struct target_ops *t)
> +{
> + t->to_supports_btrace = linux_supports_btrace;
> + t->to_enable_btrace = linux_enable_btrace;
> + t->to_disable_btrace = linux_disable_btrace;
> + t->to_btrace_has_changed = linux_btrace_has_changed;
> + t->to_read_btrace = linux_nat_read_btrace;
> +}
> diff --git a/gdb/linux-nat-btrace.h b/gdb/linux-nat-btrace.h
> new file mode 100644
> index 0000000..cbe9c89
> --- /dev/null
> +++ b/gdb/linux-nat-btrace.h
> @@ -0,0 +1,28 @@
> +/* Branch trace support for GDB, the GNU debugger.
> +
> + Copyright (C) 2012 Free Software Foundation, Inc.
> +
> + Contributed by Intel Corp. <markus.t.metzger@intel.com>.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + 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, see <http://www.gnu.org/licenses/>. */
> +
> +#ifndef LINUX_NAT_BTRACE_H
> +#define LINUX_NAT_BTRACE_H
> +
> +struct target_ops;
> +extern void linux_nat_add_btrace_ops (struct target_ops *);
> +
> +#endif /* LINUX_NAT_BTRACE_H */
> --
> 1.7.1
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 09/16] btrace, linux: add linux native btrace target ops
2012-05-30 20:43 ` Jan Kratochvil
@ 2012-05-31 15:34 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:34 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1617 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:43 PM
> To: Metzger, Markus T
Thanks for your review!
> > +static int
> > +linux_nat_push_btrace_record (struct linux_btrace_block *raw, void
> > +*arg) {
> > + VEC (btrace_block_s) **btrace = arg;
> > + struct btrace_block *block;
> > +
> > + if (!raw)
> > + return EINVAL;
> > +
> > + if (!btrace)
> > + return EINVAL;
>
> I did not check now but probably excessive.
Removed.
> > +
> > + block = VEC_safe_push (btrace_block_s, *btrace, NULL); if (!block)
> > + return ENOMEM;
>
> Incorrect indentation.
Fixed.
> > +
> > + block->begin = raw->begin;
> > + block->end = raw->end;
>
> Do not use alignment/indentation.
Fixed.
> > +
> > + return 0;
> > +}
> > +
> > +static VEC (btrace_block_s) *
> > +linux_nat_read_btrace (struct btrace_target_info *tinfo) {
> > + VEC (btrace_block_s) *btrace = NULL;
> > + int errcode;
> > +
> > + if (!tinfo)
> > + {
> > + errno = EINVAL;
> > + return NULL;
> > + }
> > + if (!tinfo->ptr_bits)
> > + {
> > + struct gdbarch *gdbarch = get_current_arch ();
>
> Empty line.
Fixed. Replaced with target_gdbarch as by your earlier recommendation.
> > + if (gdbarch)
> > + tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
> > + }
> > +
> > + errcode = linux_read_btrace (tinfo, linux_nat_push_btrace_record,
> > + &btrace); if (errcode)
> > + warning (_("error while reading branch trace data: %s. "
>
> Captitalize "Error". Use two spaces at the end.
Fixed.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 12/16] test, btrace: more branch tracing tests
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (13 preceding siblings ...)
2012-05-23 11:25 ` [PATCH 09/16] btrace, linux: add linux native btrace target ops markus.t.metzger
@ 2012-05-23 11:26 ` markus.t.metzger
2012-05-23 11:26 ` [PATCH 07/16] configure: autoreconf markus.t.metzger
` (3 subsequent siblings)
18 siblings, 0 replies; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:26 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Barkha Ahuja
From: Barkha Ahuja <barkha.ahuja@intel.com>
Non-stop tests are failing with gdbserver.
2012-05-23 Barkha Ahuja <barkha.ahuja@intel.com>
gdb/testsuite/gdb.btrace/
* a.s: New file
* allthreads_trace.exp: New file
* b.s: New file
* decrement.exp: New file
* decrement.s: New file
* disable_all.exp: New file
* enable_all.exp: New file
* enable_range.exp: New file
* list_options.exp: New file
* main.s: New file
* main_asm.exp: New file
* main_segv.exp: New file
* main_segv.s: New file
* sanity_crash.exp: New file
* sanity_crash.s: New file
* thr_callback_32.s: New file
* thr_callback_64.s: New file
* threads.c: New file
* threads_asm.c: New file
* threads_auto.exp: New file
* threads_independent.exp: New file
* threads_nonstop.exp: New file
* trace_iteration.exp: New file
---
gdb/testsuite/gdb.btrace/a.s | 24 ++
gdb/testsuite/gdb.btrace/allthreads_trace.exp | 270 ++++++++++++++++++++++
gdb/testsuite/gdb.btrace/b.s | 23 ++
gdb/testsuite/gdb.btrace/decrement.exp | 140 +++++++++++
gdb/testsuite/gdb.btrace/decrement.s | 32 +++
gdb/testsuite/gdb.btrace/disable_all.exp | 198 ++++++++++++++++
gdb/testsuite/gdb.btrace/enable_all.exp | 201 ++++++++++++++++
gdb/testsuite/gdb.btrace/enable_range.exp | 198 ++++++++++++++++
gdb/testsuite/gdb.btrace/list_options.exp | 107 +++++++++
gdb/testsuite/gdb.btrace/main.s | 32 +++
gdb/testsuite/gdb.btrace/main_asm.exp | 113 +++++++++
gdb/testsuite/gdb.btrace/main_segv.exp | 84 +++++++
gdb/testsuite/gdb.btrace/main_segv.s | 28 +++
gdb/testsuite/gdb.btrace/sanity_crash.exp | 69 ++++++
gdb/testsuite/gdb.btrace/sanity_crash.s | 52 ++++
gdb/testsuite/gdb.btrace/thr_callback_32.s | 116 +++++++++
gdb/testsuite/gdb.btrace/thr_callback_64.s | 116 +++++++++
gdb/testsuite/gdb.btrace/threads.c | 96 ++++++++
gdb/testsuite/gdb.btrace/threads_asm.c | 78 +++++++
gdb/testsuite/gdb.btrace/threads_auto.exp | 113 +++++++++
gdb/testsuite/gdb.btrace/threads_independent.exp | 119 ++++++++++
gdb/testsuite/gdb.btrace/threads_nonstop.exp | 182 +++++++++++++++
gdb/testsuite/gdb.btrace/trace_iteration.exp | 264 +++++++++++++++++++++
23 files changed, 2655 insertions(+), 0 deletions(-)
create mode 100755 gdb/testsuite/gdb.btrace/a.s
create mode 100755 gdb/testsuite/gdb.btrace/allthreads_trace.exp
create mode 100755 gdb/testsuite/gdb.btrace/b.s
create mode 100755 gdb/testsuite/gdb.btrace/decrement.exp
create mode 100755 gdb/testsuite/gdb.btrace/decrement.s
create mode 100755 gdb/testsuite/gdb.btrace/disable_all.exp
create mode 100755 gdb/testsuite/gdb.btrace/enable_all.exp
create mode 100755 gdb/testsuite/gdb.btrace/enable_range.exp
create mode 100755 gdb/testsuite/gdb.btrace/list_options.exp
create mode 100755 gdb/testsuite/gdb.btrace/main.s
create mode 100755 gdb/testsuite/gdb.btrace/main_asm.exp
create mode 100755 gdb/testsuite/gdb.btrace/main_segv.exp
create mode 100755 gdb/testsuite/gdb.btrace/main_segv.s
create mode 100755 gdb/testsuite/gdb.btrace/sanity_crash.exp
create mode 100755 gdb/testsuite/gdb.btrace/sanity_crash.s
create mode 100755 gdb/testsuite/gdb.btrace/thr_callback_32.s
create mode 100755 gdb/testsuite/gdb.btrace/thr_callback_64.s
create mode 100755 gdb/testsuite/gdb.btrace/threads.c
create mode 100755 gdb/testsuite/gdb.btrace/threads_asm.c
create mode 100755 gdb/testsuite/gdb.btrace/threads_auto.exp
create mode 100755 gdb/testsuite/gdb.btrace/threads_independent.exp
create mode 100755 gdb/testsuite/gdb.btrace/threads_nonstop.exp
create mode 100755 gdb/testsuite/gdb.btrace/trace_iteration.exp
diff --git a/gdb/testsuite/gdb.btrace/a.s b/gdb/testsuite/gdb.btrace/a.s
new file mode 100755
index 0000000..75e7ba3
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/a.s
@@ -0,0 +1,24 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+ .text
+ .globl callA
+ .type callA, @function
+callA:
+ nop
+ ret
+
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/allthreads_trace.exp b/gdb/testsuite/gdb.btrace/allthreads_trace.exp
new file mode 100755
index 0000000..250e24d
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/allthreads_trace.exp
@@ -0,0 +1,270 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, thr_callback_32.s, thr_callback_64.s
+# Compiled using '-g -lpthread' option.
+#executed as :
+# make check RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/allthreads_trace.exp"
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/allthreads_trace.x
+set options "{debug}"
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[ishost "i?86-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_32.s
+} elseif {[ishost "x86_64-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_64.s
+} else {
+ warning "host platform not supported "
+ untested allthreads_trace.exp
+ return -1
+}
+set objfiles "${objmain} ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+ untested allthreads_trace.exp
+ return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+ untested allthreads_trace.exp
+ return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+ untested allthreads_trace.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+runto main
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr_callback_...s:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+gdb_test "btr enable auto"
+send_gdb "continue\n"
+gdb_expect 8 {
+ -re "Breakpoint 3, mybarrier \\(\\) at.*thr_callback_...s:114.*"
+ {
+ pass "continuing"
+ }
+ }
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+ -re ".*\n" {
+ pass $test
+ }
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+gdb_test "thread 2" ".*Switching to thread 2.*mybarrier.*" " switch to thread 2, 1.3"
+# 64 bit platform
+if {[ishost "x86_64-*-*"]} {
+
+# trace for thread 2
+gdb_test "btr list /a" "
+1 0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2 0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+.*" "BTR listing for thread 2, 1.4"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 2, 1.5"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_a\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_a\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 2, 1.6"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.7"
+
+gdb_test "btr list /la" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_64.s:112-114\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_64.s:44-45\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_64.s:85-89\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_64.s:40-43\r
+.*" "BTR listing for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 3, 1.9"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 3, 1.10"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.11"
+
+gdb_test "btr list /lf" "
+1 *in mybarrier \\(\\) at.*thr_callback_64.s:112-114\r
+2 *in th_c \\(\\) at.*thr_callback_64.s:56-57\r
+3 *in call_C \\(\\) at.*thr_callback_64.s:94-98\r
+4 *in th_c \\(\\) at.*thr_callback_64.s:52-55\r
+.*" "BTR listing for thread 4, 1.12"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 4, 1.13"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_c\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_c\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 4, 1.14"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.15"
+
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*" "BTR listing for thread 5, 1.16"
+
+gdb_test "btr " "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 5, 1.17"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_d\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_d\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 5, 1.18"
+
+ gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_D\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_D\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+4>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+9>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_D\\+10>:\[\[:blank:\]\]*ret.*\r" " BTR of 3 for thread 5, 1.19"
+
+} elseif {[ishost "i?86-*-*"]} {
+# 32 bit platform
+
+#trace for thread 2
+gdb_test "btr list /a" "
+1 0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2 0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+.*" "BTR listing for thread 2, 1.4"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 2, 1.5"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_a\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_a\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 2, 1.6"
+
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.7"
+
+#trace for thread 3
+gdb_test "btr list /la" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_32.s:112-114\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_32.s:44-45\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_32.s:85-89\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*thr_callback_32.s:40-43\r
+.*" "BTR listing for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 3, 1.9"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 3, 1.10"
+
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.11"
+
+#trace for thread 4
+gdb_test "btr list /lf" "
+1 *in mybarrier \\(\\) at.*thr_callback_32.s:112-114\r
+2 *in th_c \\(\\) at.*thr_callback_32.s:56-57\r
+3 *in call_C \\(\\) at.*thr_callback_32.s:94-98\r
+4 *in th_c \\(\\) at.*thr_callback_32.s:52-55\r
+.*" "BTR listing for thread 4, 1.12"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 4, 1.13"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_c\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_c\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 4, 1.14"
+
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.15"
+
+#trace for thread 5
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*" "BTR listing for thread 5, 1.16"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 5, 1.17"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_d\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_d\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 5, 1.18"
+
+ gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_D\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_D\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+3>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+8>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_D\\+9>:\[\[:blank:\]\]*ret.*\r" " BTR of 3 for thread 5, 1.19"
+
+} else {
+ note "Platform not supported"
+ untested allthreads_trace.exp
+}
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/b.s b/gdb/testsuite/gdb.btrace/b.s
new file mode 100755
index 0000000..271091f
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/b.s
@@ -0,0 +1,23 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+ .text
+ .globl callB
+ .type callB, @function
+callB:
+ nop
+ ret
diff --git a/gdb/testsuite/gdb.btrace/decrement.exp b/gdb/testsuite/gdb.btrace/decrement.exp
new file mode 100755
index 0000000..11f3900
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/decrement.exp
@@ -0,0 +1,140 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Fix a location while linking, where teh debuggee will be loaded and then
+# see that trace gives the correct addresses.
+# Source file: decrement.s
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+set srcfile ${srcdir}/${subdir}/decrement.s
+set objfile ${objdir}/${subdir}/decrement.o
+set binfile ${objdir}/${subdir}/decrement.x
+set options "{debug}"
+#compile
+if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return "" }
+#link
+if {[target_link ${objfile} ${binfile} " -Ttext 0x400400 "] != ""} {
+ untested decrement.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+
+# Make sure we don't die when enabling trace for a newly created thread.
+runto L1
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "next" "0x0*40041a in L1.*" ""
+
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)" "list L1, 1.1"
+
+gdb_continue_to_breakpoint "L1"
+
+if {[ishost "x86_64-*-*"]} {
+#We enter the loop for 5 times from here.
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400421 in L1 \\(\\)" "list L1 again , 1.2"
+} elseif {[ishost "i?86-*-*"]} {
+#We enter the loop for 5 times from here.
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400420 in L1 \\(\\)" "list L1 again, 1.2"
+}
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+if {[ishost "x86_64-*-*"]} {
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /lfa" "
+1 *0x0*400423 - 0x0*400423 in L2 \\(\\)\r
+2 *0x0*40041a - 0x0*40041d in L1 \\(\\)\r
+3 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+4 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+5 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+6 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r" "BTR listing at L2, 1.3"
+
+# Exit the loop
+gdb_test "btr /m 1" "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*ret.*\r" "BTR at block 1, 1.4"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr /m 2" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 *<L2>" "BTR at block 2, 1.5"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at block 3, 1.6"
+
+} elseif {[ishost "i?86-*-*"]} {
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /lfa" "
+1 *0x0*400422 - 0x0*400422 in L2 \\(\\)\r
+2 *0x0*40041a - 0x0*40041d in L1 \\(\\)\r
+3 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+4 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+5 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+6 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r" "BTR listing at L2, 1.3"
+
+# Exit the loop
+gdb_test "btr /m 1" "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret.*\r" "BTR at block 1, 1.4"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr /m 2" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at block 2, 1.5"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at block 3, 1.6"
+
+} else {
+ warning "host platform not supported "
+ return -1
+}
+
diff --git a/gdb/testsuite/gdb.btrace/decrement.s b/gdb/testsuite/gdb.btrace/decrement.s
new file mode 100755
index 0000000..c94a98a
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/decrement.s
@@ -0,0 +1,32 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+#Decrements the number 5 by 1 untill it is 0. The
+ .text
+ .globl _start
+_start:
+ .align 0x10 # 0x400010
+ movl $5, %eax
+ .align 0x10 # 0x400010
+ movl $1, %ebx
+ call L1
+
+L1: cmpl $0, %eax #compare 0 with value in eax
+ je L2 #jump to L2 if 0==eax (je - jump if equal)
+ decl %eax #decrement eax
+ jmp L1 # unconditional jump to L1
+L2: ret
diff --git a/gdb/testsuite/gdb.btrace/disable_all.exp b/gdb/testsuite/gdb.btrace/disable_all.exp
new file mode 100755
index 0000000..7f67503
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/disable_all.exp
@@ -0,0 +1,198 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, thr_callback_32.s, thr_callback_64.s
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as :
+# make check RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/thread_auto.exp"
+#executed on 64 bit as :
+# make check RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host x86_64-linux-gnu --target x86_64-linux-gnu gdb.trace/thread_auto.exp"
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/disable_all.x
+set options "{debug}"
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[ishost "i?86-*-*"]} {
+ note "This is 32 bit host."
+ set srccallback ${srcdir}/${subdir}/thr_callback_32.s
+} elseif {[ishost "x86_64-*-*"]} {
+ note "This is 64 bit host."
+ set srccallback ${srcdir}/${subdir}/thr_callback_64.s
+} else {
+ warning "host platform not supported "
+ untested disable_all.exp
+ return -1
+}
+set objfiles "${objmain} ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+ untested disable_all.exp
+ return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+ untested disable_all.exp
+ return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+ untested disable_all.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+runto main
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr_callback_...s:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+gdb_test "btr enable auto"
+send_gdb "continue\n"
+gdb_expect 8 {
+ -re "Breakpoint 3, mybarrier \\(\\) at.*thr_callback_...s:114.*"
+ {
+ pass "continuing"
+ }
+ }
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+ -re ".*\n" {
+ pass $test
+ }
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr disable all"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+gdb_test "thread 2" ".*Switching to thread 2.*mybarrier.*" " switch to thread 2, 1.7"
+# 64 bit platform
+if {[ishost "x86_64-*-*"]} {
+note "64 bit platform"
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+No trace." " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+No trace." " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} elseif {[ishost "i?86-*-*"]} {
+# 32 bit platform
+note "32 bit platform"
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+No trace." " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+No trace." " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+}
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/enable_all.exp b/gdb/testsuite/gdb.btrace/enable_all.exp
new file mode 100755
index 0000000..2ccd02c
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable_all.exp
@@ -0,0 +1,201 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, thr_callback_32.s, thr_callback_64.s
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as :
+# make check RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/enable_all.exp"
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/enable_all.x
+set options "{debug}"
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[ishost "i?86-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_32.s
+} elseif {[ishost "x86_64-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_64.s
+} else {
+ warning "host platform not supported "
+ untested enable_all.exp
+ return -1
+}
+set objfiles "${objmain} ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+ untested enable_all.exp
+ return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+ untested enable_all.exp
+ return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+ untested enable_all.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+runto main
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr_callback_...s:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+#gdb_test "btr enable all"
+send_gdb "continue\n"
+gdb_expect 8 {
+ -re "Breakpoint 3, mybarrier \\(\\) at.*thr_callback_...s:114.*"
+ {
+ pass "continuing"
+ }
+ }
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+ -re ".*\n" {
+ pass $test
+ }
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr enable all"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+gdb_test "thread 2" ".*Switching to thread 2.*mybarrier.*" " switch to thread 2, 1.7"
+# 64 bit platform
+if {[ishost "x86_64-*-*"]} {
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_c\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_c\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_d\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_d\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 5, 1.18"
+
+} elseif {[ishost "i?86-*-*"]} {
+# 32 bit platform
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_c\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_c\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_d\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_d\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+ untested enable_all.exp
+}
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/enable_range.exp b/gdb/testsuite/gdb.btrace/enable_range.exp
new file mode 100755
index 0000000..509f93c
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable_range.exp
@@ -0,0 +1,198 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace for a range of threads on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, thr_callback_32.s, thr_callback_64.s
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as :
+# make check RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/enable_range.exp"
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/enable_range.x
+set options "{debug}"
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[ishost "i?86-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_32.s
+} elseif {[ishost "x86_64-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_64.s
+} else {
+ warning "host platform not supported "
+ untested enable_range.exp
+ return -1
+}
+set objfiles "${objmain} ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+ untested enable_range.exp
+ return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+ untested enable_range.exp
+ return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+ untested enable_range.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+runto main
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr_callback_...s:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*thr_callback_...s, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+#gdb_test "btr enable all"
+send_gdb "continue\n"
+gdb_expect 8 {
+ -re "Breakpoint 3, mybarrier \\(\\) at.*thr_callback_...s:114.*"
+ {
+ pass "continuing"
+ }
+ }
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+ -re ".*\n" {
+ pass $test
+ }
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr enable 2-3"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+gdb_test "thread 2" ".*Switching to thread 2.*mybarrier.*" " switch to thread 2, 1.7"
+# 64 bit platform
+if {[ishost "x86_64-*-*"]} {
+
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} elseif {[ishost "i?86-*-*"]} {
+# 32 bit platform
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr_callback_...s:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+gdb_test "thread 3" ".*Switching to thread 3.*mybarrier.*" " switch to thread 3, 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr_callback_...s:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr_callback_...s:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " switch to thread 5, 1.16"
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr_callback_...s:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+ untested enable_range.exp
+}
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/list_options.exp b/gdb/testsuite/gdb.btrace/list_options.exp
new file mode 100755
index 0000000..103f22a
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_options.exp
@@ -0,0 +1,107 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Testing the other options of btrace list like /t, /af
+#Also tests the other commands like giving a range to btr list "btr list n1-n2"
+# Sourcefiles : main.s, a.s, b.s
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main.s
+set srcfilea ${srcdir}/${subdir}/a.s
+set srcfileb ${srcdir}/${subdir}/b.s
+set objfilemain ${objdir}/${subdir}/main_asm.o
+set objfilea ${objdir}/${subdir}/a.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/list_options.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfilea} ${objfilea} ${options}]!= ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb} ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain} ${objfilea} ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} {
+ untested list_options.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_breakpoint "25" "Breakpoint 1 at .*:.*main.s, line 25." "Breakpoint at line 25, 1.1"
+gdb_breakpoint "30" "Breakpoint 4 at .*:.*main.s, line 30." "Breakpoint at line 30, 1.2"
+
+gdb_test "r" ".*Breakpoint 1, _start .* at.*main.s:25\r
+25.*" "Run to Breakpoint at line 25, 1.3"
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+gdb_test "c"
+
+gdb_test "btr list /t" "total: 4" "total number of btrace blocks, 1.4"
+
+#Get the trace listing after it returns from callB
+gdb_test "btr list /af" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in _start \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callB \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in _start \\(\\)\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callA \\(\\)\r" "Listing at return, 1.5"
+
+#Get the trace listing for only 1-3
+gdb_test "btr list /lf 1-3" "
+1 *in _start \\(\\) at .*main.s:29-30\r
+2 *in callB \\(\\) at .*b.s:22-23\r
+3 *in _start \\(\\) at .*main.s:27-28\r" "Listing at return, 1.6"
+
+#Get the trace listing for only 2-3
+gdb_test "btr list /lf 2-4" "
+2 *in callB \\(\\) at .*b.s:22-23\r
+3 *in _start \\(\\) at .*main.s:27-28\r
+4 *in callA \\(\\) at .*a.s:22-23\r" "Listing at return, 1.7"
+
+gdb_test "btrace /m 3" "
+.*main.s:27\[\[:blank:\]\]*movl *.0, %eax\r
+ *0x\[a-f0-9\]* <_start\\+10>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+\r
+.*main.s:28\[\[:blank:\]\]*call\[\[:blank:\]\]*callB\r
+ *0x\[a-f0-9\]* <_start\\+15>:\[\[:blank:\]\]*call. *0x\[a-f0-9\]* *<callB>" "btrace for 1 to 3, 1.8"
+
+gdb_test "btrace /r 3" "
+ *0x\[a-f0-9\]* <_start\\+10>:.*mov *.0x0,%eax\r
+ *0x\[a-f0-9\]* <_start\\+15>:.*call. *0x\[a-f0-9\]* <callB>" "btrace with /r options at 3, 1.9"
+
+
+gdb_test "btrace /r -" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*90\[\[:blank:\]\]*nop *\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*c3\[\[:blank:\]\]*ret. *" " btrace with /r option at 2, 1.10"
diff --git a/gdb/testsuite/gdb.btrace/main.s b/gdb/testsuite/gdb.btrace/main.s
new file mode 100755
index 0000000..b314ada
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main.s
@@ -0,0 +1,32 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+###################
+# main.s, uses a.s and b.s
+###################
+
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ movl $0, %eax
+ call callA
+ movl $0, %eax
+ call callB
+ movl $0, %eax
+ leave
+ ret
+
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.btrace/main_asm.exp b/gdb/testsuite/gdb.btrace/main_asm.exp
new file mode 100755
index 0000000..0e7363d
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_asm.exp
@@ -0,0 +1,113 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works when we step into multiple source files in '.s' format
+# Sourcefiles : main.s, a.s, b.s
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main.s
+set srcfilea ${srcdir}/${subdir}/a.s
+set srcfileb ${srcdir}/${subdir}/b.s
+set objfilemain ${objdir}/${subdir}/main_asm.o
+set objfilea ${objdir}/${subdir}/a.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/main_asm.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfilea} ${objfilea} ${options}]!= ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb} ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain} ${objfilea} ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} {
+ untested main_asm.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_breakpoint "25" "Breakpoint 1 at .*:.*main.s, line 25." "Breakpoint at line 25, 1.1"
+gdb_breakpoint "26" "Breakpoint 2 at .*:.*main.s, line 26." "Breakpoint at line 26, 1.2"
+gdb_breakpoint "28" "Breakpoint 3 at .*:.*main.s, line 28." "Breakpoint at line 28, 1.3"
+gdb_breakpoint "30" "Breakpoint 4 at .*:.*main.s, line 30." "Breakpoint at line 30, 1.4"
+
+gdb_test "r" ".*Breakpoint 1, _start .* at.*main.s:25\r
+25.*" "Run to Breakpoint at line 25, 1.5"
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+gdb_test "c" ".*Breakpoint 2, _start .* at.*main.s:26\r
+26.*call.*callA" "Run to Breakpoint at line 26, 1.6"
+
+# run to callB
+gdb_test "c" ".*Breakpoint 3, _start .* at.*main.s:28\r
+28.*call.*callB" "Run to Breakpoint at line 28, 1.7"
+
+#get BTR listing in CallB
+gdb_test "btr list /lfa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in _start \\(\\) at .*main.s:27-28\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callA \\(\\) at .*a.s:22-23" "BTR listing at line 28, 1.8"
+
+#return to main
+gdb_test "c" ".*Breakpoint 4, _start .* at.*main.s:30\r
+30.*leave" "Run to Breakpoint at line 30, 1.9"
+
+# we do get trace for main, callB, main, callA here
+gdb_test "btr list /lfa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in _start \\(\\) at .*main.s:29-30\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callB \\(\\) at .*b.s:22-23\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in _start \\(\\) at .*main.s:27-28\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callA \\(\\) at .*a.s:22-23" "BTR listing at line 30, 1.10"
+
+
+gdb_test "btr /m 1" "
+.*main.s:29\[\[:blank:\]\]*movl *.0, %eax\r
+ *0x\[a-f0-9\]* <_start\\+20>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+\r
+.*main.s:30\[\[:blank:\]\]*leave\r
+=> *0x\[a-f0-9\]* <_start\\+25>: leave.*" "BTR of 1, 1.11"
+
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 2, 1.12"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <_start\\+10>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+ *0x\[a-f0-9\]* <_start\\+15>:\[\[:blank:\]\]*call.*<callB>." "BTR of 3, 1.13"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callA\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callA\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 4, 1.14"
diff --git a/gdb/testsuite/gdb.btrace/main_segv.exp b/gdb/testsuite/gdb.btrace/main_segv.exp
new file mode 100755
index 0000000..402d6d0
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_segv.exp
@@ -0,0 +1,84 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace shows up when the debugge crashes with SIGSEGV
+# Sourcefiles : main_segv.s, b.s,
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main_segv.s
+set srcfileb ${srcdir}/${subdir}/b.s
+set objfilemain ${objdir}/${subdir}/main_segv.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/main_segv.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb} ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain} ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} { return "" }
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_breakpoint "25" "Breakpoint 1 at .*:.*main_segv.s, line 25." "Breakpoint at line 25, 1.1"
+gdb_breakpoint "28" "Breakpoint 2 at .*:.*main_segv.s, line 28." "Breakpoint at line 28, 1.2"
+
+gdb_test "r" ".*Breakpoint 1, _start .* at.*main_segv.s:25\r
+25.*" "Run to Breakpoint at line 25, 1.3"
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+gdb_test "stepi" ".*22.*" "Stepping into callB, 1.4"
+
+gdb_test "btr list /lfa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callB \\(\\) at .*b.s.*" "BTR listing in b.s, 1.5"
+
+#check that we got SEGV
+gdb_test "c" ".*Program received signal SIGSEGV, Segmentation fault.\r
+_start.*at.*main_segv.s:27.*" "Program received SEGV at line 27, 1.6"
+
+#Check that we do get trace after SEGV too.
+gdb_test "btr list /a" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]*" "BTR listing at line 29, 1.7"
+
+#Check where we got SEGV
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <_start\\+5>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+=> 0x\[a-f0-9\]* <_start\\+10>:\[\[:blank:\]\]*leave.*" "BTR of 1, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 2, 1.9"
diff --git a/gdb/testsuite/gdb.btrace/main_segv.s b/gdb/testsuite/gdb.btrace/main_segv.s
new file mode 100755
index 0000000..f1ca686
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_segv.s
@@ -0,0 +1,28 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+###################
+# main.s, uses callB from b.s
+###################
+
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ call callB
+ movl $0, %eax
+ leave
+ ret
diff --git a/gdb/testsuite/gdb.btrace/sanity_crash.exp b/gdb/testsuite/gdb.btrace/sanity_crash.exp
new file mode 100755
index 0000000..2eaf96f
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/sanity_crash.exp
@@ -0,0 +1,69 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+#Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: Check that we get SEGV trace, in single source file.
+# see that trace gives the correct addresses.
+# Source file: sanity_crash.s
+###############
+load_lib btrace.exp
+
+set testfile "sanity_crash"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfile ${srcdir}/${subdir}/sanity_crash.s
+set objfile ${objdir}/${subdir}/sanity_crash.o
+set binfile ${objdir}/${subdir}/sanity_crash.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfile} ${objfile} ${options}] != ""} { return "" }
+#link
+if {[target_link ${objfile} ${binfile} " "] != ""} { return "" }
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# At breakpoint on line 20, we reset the trace.
+gdb_breakpoint "40" "Breakpoint 1 at .*:.*sanity_crash.s, line 40." "Breakpoint at line 40, 1.1"
+gdb_breakpoint "47" "Breakpoint 2 at .*:.*sanity_crash.s, line 47." "Breakpoint at line 47, 1.2"
+
+#Reach line 20 and enable trace
+gdb_test "run"
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+# we get Segv in between line 24 and 27.
+gdb_test "continue" ".*Program received signal SIGSEGV, Segmentation fault.\r
+_start .* at .*sanity_crash.s:44.*" "Continue, Program received SIGSEGV, 1.3"
+
+# check, we do get Segv for single trace too
+gdb_test "btr list /lf" "
+1 *in _start \\(\\) at.*sanity_crash.s:42-44\r
+2 *in somethingToDo \\(\\) at.*sanity_crash.s:28-36" "BTR listing, 1.4"
+
+#Check where we got SEGV
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* *<_start\\+14>:\[\[:blank:\]\]movl *.0x2,0x20000f.%rip.*\r
+ *0x\[a-f0-9\]* *<_start\\+24>:\[\[:blank:\]\]mov *.0x0,%eax.*\r
+=> 0x\[a-f0-9\]* *<_start\\+29>:\[\[:blank:\]\]movb *.0x0,.%rax." "BTR at 1, 1.5"
diff --git a/gdb/testsuite/gdb.btrace/sanity_crash.s b/gdb/testsuite/gdb.btrace/sanity_crash.s
new file mode 100755
index 0000000..bbfc303
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/sanity_crash.s
@@ -0,0 +1,52 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+###################
+# sanity_crash.s
+# Gives segv after calling somethingToDo in _start
+###################
+ .file "sanity_crash.c"
+ .text
+ .globl _start
+ .type _start, @function
+ .globl somethingToDo
+ .type somethingToDo, @function
+somethingToDo:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl x.2043(%rip), %eax
+ movl %eax, %edx
+ addl $1, %eax
+ movl %eax, x.2043(%rip)
+ movl %edx, %eax
+ popq %rbp
+ ret
+_start:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ call somethingToDo
+ movl $2, jvar.2046(%rip)
+ movl $0, %eax
+ movb $0, (%rax)
+ movl $0, %eax
+ popq %rbp
+ ret
+.LFE1:
+ .local jvar.2046
+ .comm jvar.2046,4,4
+ .local x.2043
+ .comm x.2043,4,4
diff --git a/gdb/testsuite/gdb.btrace/thr_callback_32.s b/gdb/testsuite/gdb.btrace/thr_callback_32.s
new file mode 100755
index 0000000..c94285b
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/thr_callback_32.s
@@ -0,0 +1,116 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+#
+###############
+# threads.c calls th_a(), th_b(),th_c() and th_d() as callback methods
+# for 4 threads being created.
+###############
+
+
+ .globl th_a
+ .type th_a, @function
+th_a:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ call call_A
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_b
+ .type th_b @function
+th_b:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ call call_B
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_c
+ .type th_c @function
+th_c:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ call call_C
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_d
+ .type th_d @function
+th_d:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ call call_D
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl call_A
+ .type call_A, @function
+call_A:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_B
+ .type call_B @function
+call_B:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_C
+ .type call_C @function
+call_C:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_D
+ .type call_D @function
+call_D:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl mybarrier
+ .type mybarrier @function
+mybarrier:
+ pushl %ebp
+ movl %esp, %ebp
+ movl $0, %eax
+ leave
+ ret
diff --git a/gdb/testsuite/gdb.btrace/thr_callback_64.s b/gdb/testsuite/gdb.btrace/thr_callback_64.s
new file mode 100755
index 0000000..6d4c0bd
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/thr_callback_64.s
@@ -0,0 +1,116 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+#
+###############
+# threads.c calls th_a(), th_b(),th_c() and th_d() as callback methods
+# for 4 threads being created.
+###############
+
+
+ .globl th_a
+ .type th_a, @function
+th_a:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ call call_A
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_b
+ .type th_b @function
+th_b:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ call call_B
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_c
+ .type th_c @function
+th_c:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ call call_C
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl th_d
+ .type th_d @function
+th_d:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ call call_D
+ movl $0, %eax
+ call mybarrier
+ leave
+ ret
+
+ .globl call_A
+ .type call_A, @function
+call_A:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_B
+ .type call_B @function
+call_B:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_C
+ .type call_C @function
+call_C:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl call_D
+ .type call_D @function
+call_D:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ leave
+ ret
+
+ .globl mybarrier
+ .type mybarrier @function
+mybarrier:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $0, %eax
+ leave
+ ret
diff --git a/gdb/testsuite/gdb.btrace/threads.c b/gdb/testsuite/gdb.btrace/threads.c
new file mode 100755
index 0000000..2d81715
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads.c
@@ -0,0 +1,96 @@
+/*
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#This program spawns 4 threads and each thread has a seperate callback function and
+# a diffierent function call from callback function.
+# Purpose: To check the trace functionality of gdb, ("btr auto on" and "btr enable" for individual threads)
+###############
+*/
+#include <pthread.h>
+#include <stdio.h>
+
+
+//function being called by Thread[0],
+int call_A(){ return 0;}
+//function being called by Thread[1]
+int call_B(){ return 0;}
+//function being called by Thread[2]
+int call_C(){ return 0;}
+//function being called by Thread[3]
+int call_D(){ return 0;}
+
+//Callback function for thread[0]
+void* th_a(void* arg){
+ int number = *((int*) arg);
+ call_A();
+ return arg;
+}
+//Callback function for thread[1]
+void* th_b(void* arg){
+ int number = *((int*) arg);
+ call_B();
+ return arg;
+}
+//Callback function for thread[2]
+void* th_c(void* arg){
+ int number = *((int*) arg);
+ call_C();
+ return arg;
+}
+//Callback function for thread[3]
+void* th_d(void* arg){
+ int number = *((int*) arg);
+ call_D();
+ return arg;
+}
+// Terminate the already created thread
+int join_thread(pthread_t *thr)
+{
+ int* resultp;
+ if (pthread_join(*thr, (void**) &resultp))
+ {
+ printf("ERROR: pthread_join failed, aborting!\n");
+ return(1);
+ }
+ return(0);
+}
+
+int main(){
+ const int THREADS = 4;
+ pthread_t thread[THREADS];
+ int args[THREADS];
+ args[0]=0;
+ args[1]=1;
+ args[2]=2;
+ args[3]=3;
+
+ // To be deterministic, we have to first terminate the
+ // created thread before creating a new one.
+ pthread_create(&thread[0], 0, th_a ,&args[0]);
+ join_thread(&thread[0]);
+ pthread_create(&thread[1], 0, th_b ,&args[1]);
+ join_thread(&thread[1]);
+ pthread_create(&thread[2], 0, th_c ,&args[2]);
+ join_thread(&thread[2]);
+ pthread_create(&thread[3], 0, th_d ,&args[3]);
+ join_thread(&thread[3]);
+
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/threads_asm.c b/gdb/testsuite/gdb.btrace/threads_asm.c
new file mode 100755
index 0000000..eb58ecf
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_asm.c
@@ -0,0 +1,78 @@
+/*
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#This program spawns 4 threads and each thread has a seperate callback function and
+# a different function call from callback function.
+# th_a(), th_b(), th_c() and th_d are called from file th_callback.s
+#
+# Purpose: To check the trace functionality of gdb, ("btr auto on" and "btr enable" for individual threads and "btr enable" in GDb non-stop mode)
+###############
+*/
+#include <pthread.h>
+#include <stdio.h>
+
+pthread_barrier_t bar;
+
+void* th_a(void* arg);
+void* th_b(void* arg);
+void* th_c(void* arg);
+void* th_d(void* arg);
+
+// Terminate the already created thread
+int join_thread(pthread_t *thr)
+{
+ int* resultp;
+ if (pthread_join(*thr, (void**) &resultp))
+ {
+ printf("ERROR: pthread_join failed, aborting!\n");
+ return(1);
+ }
+ return(-1);
+}
+
+int main(){
+ const int THREADS = 4;
+ pthread_t thread[THREADS];
+ int args[THREADS];
+ int i;
+ args[0]=0;
+ args[1]=1;
+ args[2]=2;
+ args[3]=3;
+ pthread_barrier_init(&bar, NULL, 5);
+
+ //create 4 threads having different callback fucntions.
+ pthread_create(&thread[0], 0, th_a ,&args[0]);
+ pthread_create(&thread[1], 0, th_b ,&args[1]);
+ pthread_create(&thread[2], 0, th_c ,&args[2]);
+ pthread_create(&thread[3], 0, th_d ,&args[3]);
+ mybarrier();
+ printf(" All the threads are created by now ");
+ //wait for all the threads to terminate
+
+ for(i=0;i<4;i++) {
+ join_thread(&thread[i]);
+ }
+ //destroy barrier
+ pthread_barrier_destroy(&bar);
+
+ return 1;
+}
+
diff --git a/gdb/testsuite/gdb.btrace/threads_auto.exp b/gdb/testsuite/gdb.btrace/threads_auto.exp
new file mode 100755
index 0000000..d9e85a6
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_auto.exp
@@ -0,0 +1,113 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works for multi-threaded application and the trace is automatically enabled for all the threads created, if we execute the GDB command "btr enable auto".
+# Sourcefiles : threads.c
+# Compiled using '-g -lpthread' option.
+#executed as :
+# make check RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/threads_auto.exp"
+###############
+
+
+
+load_lib btrace.exp
+
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads.c
+set objfilemain ${objdir}/${subdir}/threads.o
+set binfile ${objdir}/${subdir}/threads_auto.x
+set options "{debug}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objfilemain} "object" ${options}] != ""} {
+ untested threads_auto.exp
+ return -1
+}
+if {[gdb_compile_pthreads ${objfilemain} ${binfile} "executable" ""] != ""} {
+ untested threads_auto.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Make sure we don't die when enabling trace for a newly created thread.
+runto main
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "43" "Breakpoint 2 at .*:.*, line 43." "Breakpoint at line 42, 1.1"
+
+gdb_breakpoint "49" "Breakpoint 3 at .*:.*, line 49." "Breakpoint at line 48, 1.2"
+
+gdb_breakpoint "55" "Breakpoint 4 at .*:.*, line 55." "Breakpoint at line 54, 1.3"
+
+gdb_breakpoint "61" "Breakpoint 5 at .*:.*, line 61." "Breakpoint at line 60, 1.4"
+
+# Reset branch trace on all new threads automatically
+gdb_test_no_output "btr enable auto"
+
+gdb_test "continue" ".*
+Breakpoint 2, th_a.*threads\.c:43\r
+43\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 2, line 43, 1.5"
+
+#Get the trace listing after it returns from call_A, while ignoring the trace listing of trace pthread libs.
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_A \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+.*\r" "listing is not correct thread\[0\], 1.6"
+
+
+gdb_test "continue" ".*
+Breakpoint 3, th_b.*threads\.c:49\r
+49\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 32, line 49, 1.7"
+
+#Get the trace listing after it returns from call_B
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_B \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\)\r
+.*\r" "listing is not correct thread\[1\], 1.8"
+
+gdb_test "continue" ".*
+Breakpoint 4, th_c.*threads\.c:55\r
+55\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 4, line 55, 1.9"
+
+#Get the trace listing after it returns from call_C
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_C \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+.*\r" "listing is not correct thread\[2\], 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_d.*threads\.c:61\r
+61\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 52, line 61, 1.11"
+
+#Get the trace listing after it returns from call_D
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_D \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*\r" "listing is not correct for thread\[3\], 1.12"
diff --git a/gdb/testsuite/gdb.btrace/threads_independent.exp b/gdb/testsuite/gdb.btrace/threads_independent.exp
new file mode 100755
index 0000000..a37be7f
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_independent.exp
@@ -0,0 +1,119 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works for multi-threaded application and the trace is enabled for only the current thread.
+# Sourcefiles : threads.c
+# Compiled using '-g -lpthread' option.
+#executed as :
+# make check RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/threads_independent.exp"
+###############
+
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads.c
+set objfilemain ${objdir}/${subdir}/threads.o
+set binfile ${objdir}/${subdir}/threads_independent.x
+set options "{debug}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${binfile} "executable" ${options}] != ""} {
+ untested threads_independent.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Make sure we don't die when enabling trace for a newly created thread.
+runto main
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "th_a" "Breakpoint 2 at .*:.*, line 41." "Breakpoint at th_a, 1.1"
+
+gdb_breakpoint "th_c" "Breakpoint 4 at .*:.*, line 53." "Breakpoint at th_c, 1.2"
+
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "43" "Breakpoint 6 at .*:.*, line 43." "Breakpoint at line 43, 1.3"
+
+gdb_breakpoint "49" "Breakpoint 7 at .*:.*, line 49." "Breakpoint at line 49, 1.4"
+
+gdb_breakpoint "55" "Breakpoint 8 at .*:.*, line 55." "Breakpoint at line 55, 1.5"
+
+gdb_breakpoint "61" "Breakpoint 9 at .*:.*, line 61." "Breakpoint at line 61, 1.6"
+
+# move to th_a for thread[0]and enable trace
+gdb_test "continue" ".*
+Breakpoint 2, th_a.*threads\.c:41\r.*" "Stopping at breakpoint 2, th_a, 1.7"
+
+# Reset branch trace
+gdb_test_no_output "btrace enable"
+
+gdb_test "continue" ".*
+Breakpoint 4, th_a.*threads\.c:43\r
+43\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 4, line 43, 1.8"
+
+#Get the trace listing after it returns from call_A
+gdb_test "btrace list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_A \\(\\)" "listing of thread\[0\], 1.9"
+
+
+# move to th_b for thread[1]and do not enable trace
+gdb_test "continue" ".*
+Breakpoint 5, th_b.*threads\.c:49\r
+49\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 5, line 49, 1.10"
+
+#Get the trace listing after it returns from call_B
+gdb_test "btr list" "No trace." "No trace for thread\[1\], 1.11"
+
+
+# move to th_c and enable trace
+gdb_test "continue" ".*
+Breakpoint 3, th_c.*threads\.c:53\r
+53.*" "Stopping at breakpoint 3, th_c, 1.12"
+
+
+# Reset branch trace for thread[2]
+gdb_test_no_output "btrace enable"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c.*threads\.c:55\r
+55\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 6, line 55, 1.13"
+
+#Get the trace listing after it returns from call_C
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_C \\(\\)" "listing of thread\[2\], 1.14"
+
+
+# move to th_d and do not enable trace
+gdb_test "continue" ".*
+Breakpoint 7, th_d.*threads\.c:61\r
+61\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 7, line 61, 1.15"
+
+#Get the trace listing after it returns from call_D
+gdb_test "btr list" "No trace." "No trace for thread\[3\], 1.16"
diff --git a/gdb/testsuite/gdb.btrace/threads_nonstop.exp b/gdb/testsuite/gdb.btrace/threads_nonstop.exp
new file mode 100755
index 0000000..f22e8f9
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_nonstop.exp
@@ -0,0 +1,182 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, when btrace is enabled for only one thread (created by pthread_create()), then trace is also generated for only that thread and not for all threads
+# Sourcefiles : threads_asm.c
+# Compiled using '-g -lpthread' option.
+#executed as :
+# make check RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/threads_nonstop.exp"
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/threads_nonstop.x
+set options "{debug}"
+
+# We need to do a seperate listing from here, since the instr lenght is different
+# on different platforms.
+# 32 bit platform
+if {[ishost "i?86-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_32.s
+} elseif {[ishost "x86_64-*-*"]} {
+ set srccallback ${srcdir}/${subdir}/thr_callback_64.s
+} else {
+ warning "host platform not supported "
+ return -1
+}
+
+set objfiles "${objmain} ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} { return "" }
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} { return "" }
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+ untested threads_nonstop.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+runto main
+
+#set breakpoint at mybarrier to prevent all the pthreads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 2 at .*:thr_callback_\[32|64\].s, line .*." "Breakpoint in reach barrier, 1.1"
+
+#set a breakpoint in callback of thread 3, where we enable trace for only thread 3
+gdb_breakpoint "th_b" "Breakpoint 3 at .*:thr_callback_\[32|64\].s.*" "Breakpoint in reach barrier, 1.2"
+
+send_gdb "continue\n"
+gdb_expect 8 {
+ -re "Breakpoint 2.*"
+ {
+ pass "continuing"
+ }
+ }
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+ -re ".*\n" {
+ pass $test
+ }
+}
+
+# this is added to get the prompt, which is missing after creating new threads in non-stop mode.
+gdb_test "" ""
+
+# thread 3 reaches its callback th_b(), while all threads wait at mybarrier()
+gdb_test "info threads" " Id Target Id Frame \r
+ 5 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+ 4 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+ 3 Thread 0x\[a-f0-9\]*.*th_b \\(\\) at.*thr_callback_...s:42\r
+ 2 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+.* 1 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114" "info threads before thread 3 reaches mybarrier(), 1.3"
+
+gdb_test "thread 3" ".*Switching to thread 3.*th_b.*" " Thread 3 is still waiting at th_b(), 1.4"
+#enable trace for only thread 3
+
+gdb_test "btr enable"
+# thread 3 also continues to mybarrier()
+
+gdb_test "continue" ".*Breakpoint 2, mybarrier \\(\\) at .*thr_callback_...s:114.*" " thread 3 also reached at breakpoint 1 at line 53, 1.5"
+# back trace for thread 3.
+
+gdb_test "btr list /lfa" "
+1 0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\) at.*thr_callback_...s:112-114\r
+2 0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\) at.*thr_callback_...s:44-45\r
+3 0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_B \\(\\) at.*thr_callback_...s:85-89" "BTR listing at line mybarrier for thread 3, 1.6"
+
+# 32 bit host
+if {[ishost "i?86-*-*"]} {
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> 0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" "btr 0 for thread 3, 1.7"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+18>:\[\[:blank:\]\]*call.*<mybarrier>" "btr 1 for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_B\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_B\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+3>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+8>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_B\\+9>:\[\[:blank:\]\]*ret.*\r" "btr 1 for thread 3, 1.9"
+
+} elseif {[ishost "x86_64-*-*"]} {
+# 64 bit host
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> 0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" "btr 0 for thread 3, 1.7"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+19>:\[\[:blank:\]\]*call.*<mybarrier>" "btr 1 for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_B\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_B\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+4>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+9>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_B\\+10>:\[\[:blank:\]\]*ret.*\r" "btr 1 for thread 3, 1.9"
+
+}
+# All the threads are at mybarrier()
+gdb_test "info threads" " Id Target Id Frame \r
+ 5 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+ 4 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+.* 3 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+ 2 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114\r
+ 1 Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr_callback_...s:114" "Info threads, when all threads reached barrier, 1.10"
+
+# trace was enabled for only thread 3, and none other thread has trace
+gdb_test "thread 2" ".*Switching to thread 2.*mybarrier.*" " switch to thread 2, 1.11"
+
+gdb_test "btr list" "No trace" " no trace for thread 2, 1.12"
+
+gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " swtich to thread 4, 1.13"
+
+gdb_test "btr list" "No trace" " no trace for thread 4, 1.14"
+
+gdb_test "thread 5" ".*Switching to thread 5.*mybarrier.*" " swtich to thread 5, 1.15"
+
+gdb_test "btr list" "No trace" " no trace for thread 5, 1.16"
+
+
+
+
diff --git a/gdb/testsuite/gdb.btrace/trace_iteration.exp b/gdb/testsuite/gdb.btrace/trace_iteration.exp
new file mode 100755
index 0000000..1a63e11
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/trace_iteration.exp
@@ -0,0 +1,264 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Fix a location while linking, where the debuggee will be loaded and then
+# see that trace gives the correct addresses.
+# Iterate over the btrace using the commands "btr", "btr +", "btr -", and check that it gives the correct output.
+# Source file: decrement.s
+###############
+
+load_lib btrace.exp
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+set srcfile ${srcdir}/${subdir}/decrement.s
+set objfile ${objdir}/${subdir}/decrement.o
+set binfile ${objdir}/${subdir}/trace_iteration.x
+set options "{debug}"
+#compile
+if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return -1 }
+#link
+if {[target_link ${objfile} ${binfile} " -Ttext 0x400400 "] != ""} {
+ untested trace_iteration.exp
+ return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+
+# Make sure we don't die when enabling trace for a newly created thread.
+runto L1
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "next" "0x0*40041a in L1.*" ""
+
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)" "list L1, 1.1"
+
+gdb_continue_to_breakpoint "L1, 1.2"
+
+if {[ishost "x86_64-*-*"]} {
+#64 bit host
+
+#We enter the loop for 5 times from here.
+gdb_test "btr list /af" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400421 in L1 \\(\\)" "list L1 again, 1.3"
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /a" "
+1 *0x0*400423 - 0x0*400423\r
+2 *0x0*40041a - 0x0*40041d\r
+3 *0x0*40041a - 0x0*400421\r
+4 *0x0*40041a - 0x0*400421\r
+5 *0x0*40041a - 0x0*400421\r.*" "BTR listing at L2, 1.4"
+
+# Exit the loop
+gdb_test "btr " "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR of 0, 1.5"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.6"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.7"
+
+gdb_test "btr " "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR of 1, 1.8"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2, 1.9"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.10"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2 second time, 1.11"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3 second time, 1.12"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2 third time, 1.13"
+
+#in the loop
+gdb_test "btr -" "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR at 1 Again, 1.14"
+
+gdb_test "btr 6" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6, 1.15"
+
+gdb_test "btr +" "
+No trace." "BTR of non existing at end, 1.16"
+
+gdb_test "btr" "
+No trace." "BTR still at 6 , 1.17"
+
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6, 1.18"
+
+} elseif {[ishost "i?86-*-*"]} {
+#32 bit host
+
+#We enter the loop for 5 times from here.
+gdb_test "btr list /af" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400420 in L1 \\(\\)" "list L1 again, 1.3"
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /a" "
+1 *0x0*400422 - 0x0*400422\r
+2 *0x0*40041a - 0x0*40041d\r
+3 *0x0*40041a - 0x0*400420\r
+4 *0x0*40041a - 0x0*400420\r
+5 *0x0*40041a - 0x0*400420\r
+6 *0x0*40041a - 0x0*400420\r" "BTR listing at L2, 1.4"
+
+# Exit the loop
+gdb_test "btr " "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret *" "BTR of 1, 1.5"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.6"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.7"
+
+#BTR of non existing trace
+gdb_test "btr " "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret *" "BTR of 1, 1.8"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at 2, 1.9"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.10"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.11"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 2 second time, 1.12"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3 second time, 1.13"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 2nd third time, 1.14"
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at 1 Again, 1.15"
+
+gdb_test "btr 6" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6, 1.16"
+
+gdb_test "btr +" "" "BTR of non existing at end, 1.17"
+
+gdb_test "btr" "" "BTR still at 6 , 1.18"
+
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR still at 6 , 1.19"
+
+ } else {
+ warning "host platform not supported "
+}
+
+#reset the trace
+btrace_reset_trace
+
+gdb_test "btr list" "No trace." "No trace should be available now"
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 07/16] configure: autoreconf
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (14 preceding siblings ...)
2012-05-23 11:26 ` [PATCH 12/16] test, btrace: more branch tracing tests markus.t.metzger
@ 2012-05-23 11:26 ` markus.t.metzger
2012-06-22 20:44 ` Tom Tromey
2012-05-25 19:18 ` [PATCH 00/16] branch tracing support (resend) Pedro Alves
` (2 subsequent siblings)
18 siblings, 1 reply; 62+ messages in thread
From: markus.t.metzger @ 2012-05-23 11:26 UTC (permalink / raw)
To: kettenis; +Cc: gdb-patches, markus.t.metzger, Markus Metzger
From: Markus Metzger <markus.t.metzger@intel.com>
Ran autoreconf in gdb.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/
* config.in: Regenerate
* configure: Regenerate
gdb/gdbserver/
* config.in: Regenerate
* configure: Regenerate
---
gdb/config.in | 3 +++
gdb/configure | 13 +++++++++++++
gdb/gdbserver/config.in | 3 +++
gdb/gdbserver/configure | 2 +-
4 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/gdb/config.in b/gdb/config.in
index a3bd8dd..62f61e7 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -222,6 +222,9 @@
/* Define to 1 if you have the <link.h> header file. */
#undef HAVE_LINK_H
+/* Define to 1 if you have the <linux/perf_event.h> header file. */
+#undef HAVE_LINUX_PERF_EVENT_H
+
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
diff --git a/gdb/configure b/gdb/configure
index f638268..9fc40a8 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -8918,6 +8918,19 @@ fi
done
+for ac_header in linux/perf_event.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "linux/perf_event.h" "ac_cv_header_linux_perf_event_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_perf_event_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_PERF_EVENT_H 1
+_ACEOF
+
+fi
+
+done
+
+
# ------------------------- #
# Checks for declarations. #
# ------------------------- #
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index 26742ac..11d2194 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -72,6 +72,9 @@
/* Define to 1 if you have the <linux/elf.h> header file. */
#undef HAVE_LINUX_ELF_H
+/* Define to 1 if you have the <linux/perf_event.h> header file. */
+#undef HAVE_LINUX_PERF_EVENT_H
+
/* Define if the target supports register sets. */
#undef HAVE_LINUX_REGSETS
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index 63e25c2..29e52e6 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4419,7 +4419,7 @@ $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cach
cd "$ac_popdir"
-for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h
+for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h linux/perf_event.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
--
1.7.1
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH 07/16] configure: autoreconf
2012-05-23 11:26 ` [PATCH 07/16] configure: autoreconf markus.t.metzger
@ 2012-06-22 20:44 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Tom Tromey @ 2012-06-22 20:44 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
>>>>> "Markus" == markus t metzger <markus.t.metzger@intel.com> writes:
Markus> Ran autoreconf in gdb.
Markus> 2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
Markus> gdb/
Markus> * config.in: Regenerate
Markus> * configure: Regenerate
Markus> gdb/gdbserver/
Markus> * config.in: Regenerate
Markus> * configure: Regenerate
You should just merge this in with the configure.ac patch.
It doesn't make sense to change configure.ac and not re-run auto*.
Tom
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 07/16] configure: autoreconf
2012-06-22 20:44 ` Tom Tromey
@ 2012-06-25 8:50 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-25 8:50 UTC (permalink / raw)
To: Tom Tromey; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 895 bytes --]
> -----Original Message-----
> From: Tom Tromey [mailto:tromey@redhat.com]
> Sent: Friday, June 22, 2012 10:44 PM
> To: Metzger, Markus T
[...]
> Markus> Ran autoreconf in gdb.
> Markus> 2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
> Markus> gdb/
> Markus> * config.in: Regenerate
> Markus> * configure: Regenerate
> Markus> gdb/gdbserver/
> Markus> * config.in: Regenerate
> Markus> * configure: Regenerate
>
> You should just merge this in with the configure.ac patch.
> It doesn't make sense to change configure.ac and not re-run auto*.
Done.
I noticed that when I run autoreconf, I see unrelated changes.
What I did was to run autoreconf before my changes as well as afterwards. Then I dropped the patch for the first autoconf.
When I moved the linux/perf_event.h header check, I simply edited the configure file since the changes were obvious.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (15 preceding siblings ...)
2012-05-23 11:26 ` [PATCH 07/16] configure: autoreconf markus.t.metzger
@ 2012-05-25 19:18 ` Pedro Alves
2012-05-29 14:31 ` Metzger, Markus T
2012-05-30 20:41 ` Jan Kratochvil
2012-06-22 20:31 ` Tom Tromey
18 siblings, 1 reply; 62+ messages in thread
From: Pedro Alves @ 2012-05-25 19:18 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
Hi, I've just tried out this series applied on current mainline, and I get:
>./gdb ./gdb
...
(gdb) start
Temporary breakpoint 1 at 0x456a03: file ../../src/gdb/gdb.c, line 29.
Starting program: /home/pedro/gdb/mygit/build/gdb/gdb
warning: Skipping deprecated .gdb_index section in /usr/lib/debug/lib64/ld-2.14.90.so.debug, pass --use-deprecated-index-sections to use them anyway
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdd78) at ../../src/gdb/gdb.c:29
29 memset (&args, 0, sizeof args);
(gdb) btrace enable auto
(gdb) btrace enable all
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x0000000000456a0e in main (argc=1, argv=0x7fffffffdd78) at ../../src/gdb/gdb.c:29
29 memset (&args, 0, sizeof args);
(gdb)
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
Any idea off hand what this would be?
This in on x86_64 Fedora 16, Linux 3.3.5-2.fc16.x86_64.
Running the new tests with
$ make check RUNTESTFLAGS="--directory=gdb.btrace"
Results in
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../../src/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../../../src/gdb/testsuite/gdb.btrace/allthreads_trace.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/decrement.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/disable_all.exp ...
NOTE: This is 64 bit host.
Running ../../../src/gdb/testsuite/gdb.btrace/enable.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_all.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_range.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_function.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_options.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_asm.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_segv.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/sanity_crash.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_auto.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_independent.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_nonstop.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/trace_iteration.exp ...
=== gdb Summary ===
# of untested testcases 6
# of unsupported tests 7
The log file has a bunch of:
Assembler messages:
Fatal error: can't create /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.btrace/threads_asm.o: No such file or directory
compiler exited with status 1
output is:
Assembler messages:
Fatal error: can't create /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.btrace/threads_asm.o: No such file or directory
I build gdb with srcdir != builddir.
--
Pedro Alves
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-25 19:18 ` [PATCH 00/16] branch tracing support (resend) Pedro Alves
@ 2012-05-29 14:31 ` Metzger, Markus T
2012-05-30 14:49 ` Pedro Alves
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-29 14:31 UTC (permalink / raw)
To: Pedro Alves; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 4192 bytes --]
> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Friday, May 25, 2012 9:18 PM
> To: Metzger, Markus T
> Cc: kettenis@gnu.org; gdb-patches@sourceware.org;
> markus.t.metzger@gmail.com
> Subject: Re: [PATCH 00/16] branch tracing support (resend)
>
> Hi, I've just tried out this series applied on current mainline, and I
get:
Hello Pedro,
Thanks for trying this out and for reporting the issues!
> >./gdb ./gdb
> ...
> (gdb) start
> Temporary breakpoint 1 at 0x456a03: file ../../src/gdb/gdb.c, line 29.
> Starting program: /home/pedro/gdb/mygit/build/gdb/gdb
> warning: Skipping deprecated .gdb_index section in
/usr/lib/debug/lib64/ld-
> 2.14.90.so.debug, pass --use-deprecated-index-sections to use them anyway
> [Thread debugging using libthread_db enabled] Using host libthread_db
> library "/lib64/libthread_db.so.1".
>
> Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdd78) at
> ../../src/gdb/gdb.c:29
> 29 memset (&args, 0, sizeof args);
> (gdb) btrace enable auto
> (gdb) btrace enable all
> (gdb) n
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000456a0e in main (argc=1, argv=0x7fffffffdd78) at
> ../../src/gdb/gdb.c:29
> 29 memset (&args, 0, sizeof args);
> (gdb)
>
> Program terminated with signal SIGSEGV, Segmentation fault.
> The program no longer exists.
> (gdb)
>
> Any idea off hand what this would be?
>
> This in on x86_64 Fedora 16, Linux 3.3.5-2.fc16.x86_64.
I cannot reproduce this. I tried on several different systems including
3.3.7-1.fc16.x86_64.
Have you seen this on other systems, as well?
Is there some configuration file or so that would allow me to build gdb
exactly the same way you do?
Would it be possible that you send me the gdb you built?
> Running the new tests with
>
> $ make check RUNTESTFLAGS="--directory=gdb.btrace"
>
> Results in
>
> Running target unix
> Using /usr/share/dejagnu/baseboards/unix.exp as board description file for
> target.
> Using /usr/share/dejagnu/config/unix.exp as generic interface file for
target.
> Using ../../../src/gdb/testsuite/config/unix.exp as
tool-and-target-specific
> interface file.
> Running ../../../src/gdb/testsuite/gdb.btrace/allthreads_trace.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/decrement.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/disable_all.exp ...
> NOTE: This is 64 bit host.
> Running ../../../src/gdb/testsuite/gdb.btrace/enable.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/enable_all.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/enable_range.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/list.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/list_function.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/list_options.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/main_asm.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/main_segv.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/sanity_crash.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/threads_auto.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/threads_independent.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/threads_nonstop.exp ...
> Running ../../../src/gdb/testsuite/gdb.btrace/trace_iteration.exp ...
>
> === gdb Summary ===
>
> # of untested testcases 6
> # of unsupported tests 7
>
> The log file has a bunch of:
>
> Assembler messages:
> Fatal error: can't create
> /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.btrace/threads_asm.o:
> No such file or directory compiler exited with status 1 output is:
> Assembler messages:
> Fatal error: can't create
> /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.btrace/threads_asm.o:
> No such file or directory
>
> I build gdb with srcdir != builddir.
I can reproduce this. I changed the configuration without running autoconf.
After
configuring, the gdb/testsuite/gdb.btrace directory is missing. I'll add a
patch
with the autoconf changes to the series.
You may run the tests if you do a "make check" once. After that, running
only the
btrace tests works, as well. I guess that's why I haven't noticed it.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-05-29 14:31 ` Metzger, Markus T
@ 2012-05-30 14:49 ` Pedro Alves
2012-05-30 15:51 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Pedro Alves @ 2012-05-30 14:49 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: kettenis, gdb-patches, markus.t.metzger
On 05/29/2012 03:30 PM, Metzger, Markus T wrote:
> I cannot reproduce this. I tried on several different systems including
> 3.3.7-1.fc16.x86_64.
> Have you seen this on other systems, as well?
I tried again with the same kernel, and the crash was still there.
I've updated my kernel to that version, and the crashes disappeared.
I reverted to the previous kernel, and the crashes disappeared too...
The update also brought along other system components, but it might
be that there was just something broken in my gdb build. I don't
have that particular binary any more.
> Is there some configuration file or so that would allow me to build gdb
> exactly the same way you do?
just the usual: configure CFLAGS="-g3 -O0" && make
> I can reproduce this. I changed the configuration without running autoconf.
...
> After
> configuring, the gdb/testsuite/gdb.btrace directory is missing. I'll add a
> patch
> with the autoconf changes to the series.
Ah, I ran autoconf. The tests now run, but I get intermittent failures. Tested
in a loop with:
$ (set -e; while true; do make check RUNTESTFLAGS="--directory=gdb.btrace"; done)
I got one time:
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../../src/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../../../src/gdb/testsuite/gdb.btrace/allthreads_trace.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/decrement.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/disable_all.exp ...
NOTE: This is 64 bit host.
NOTE: 64 bit platform
Running ../../../src/gdb/testsuite/gdb.btrace/enable.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_all.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_range.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list.exp ...
FAIL: gdb.btrace/list.exp: btrace list 1.3
FAIL: gdb.btrace/list.exp: btrace list 1.4
FAIL: gdb.btrace/list.exp: btrace list 1.5
FAIL: gdb.btrace/list.exp: btrace list 1.6
FAIL: gdb.btrace/list.exp: btrace list 1.8
FAIL: gdb.btrace/list.exp: btrace list 1.9
FAIL: gdb.btrace/list.exp: btrace list 1.10
FAIL: gdb.btrace/list.exp: btrace list 1.11
FAIL: gdb.btrace/list.exp: btrace list 1.12
Running ../../../src/gdb/testsuite/gdb.btrace/list_function.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_options.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_asm.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_segv.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/sanity_crash.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_auto.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_independent.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_nonstop.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/trace_iteration.exp ...
=== gdb Summary ===
# of expected passes 240
# of unexpected failures 9
On another run I got:
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../../src/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../../../src/gdb/testsuite/gdb.btrace/allthreads_trace.exp ...
FAIL: gdb.btrace/allthreads_trace.exp: BTR listing for thread 4, 1.12
Running ../../../src/gdb/testsuite/gdb.btrace/decrement.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/disable_all.exp ...
NOTE: This is 64 bit host.
NOTE: 64 bit platform
Running ../../../src/gdb/testsuite/gdb.btrace/enable.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_all.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_range.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list.exp ...
FAIL: gdb.btrace/list.exp: btrace list 3.2
FAIL: gdb.btrace/list.exp: btrace list 3.3
Running ../../../src/gdb/testsuite/gdb.btrace/list_function.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_options.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_asm.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_segv.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/sanity_crash.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_auto.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_independent.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_nonstop.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/trace_iteration.exp ...
=== gdb Summary ===
# of expected passes 246
# of unexpected failures 3
/home/pedro/gdb/mygit/build/gdb/testsuite/../../gdb/gdb version 7.4.50.20120524-cvs -nw -nx -data-directory /home/pedro/gdb/mygit/build/gdb/testsuite/../data-directory
Yet another I got:
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../../src/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../../../src/gdb/testsuite/gdb.btrace/allthreads_trace.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/decrement.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/disable_all.exp ...
NOTE: This is 64 bit host.
NOTE: 64 bit platform
Running ../../../src/gdb/testsuite/gdb.btrace/enable.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_all.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/enable_range.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_function.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/list_options.exp ...
FAIL: gdb.btrace/list_options.exp: Listing at return, 1.6
FAIL: gdb.btrace/list_options.exp: Listing at return, 1.7
FAIL: gdb.btrace/list_options.exp: btrace for 1 to 3, 1.8
FAIL: gdb.btrace/list_options.exp: btrace with /r options at 3, 1.9
Running ../../../src/gdb/testsuite/gdb.btrace/main_asm.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/main_segv.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/sanity_crash.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_auto.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_independent.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/threads_nonstop.exp ...
Running ../../../src/gdb/testsuite/gdb.btrace/trace_iteration.exp ...
=== gdb Summary ===
# of expected passes 245
# of unexpected failures 4
(Those "NOTE"'s looks quite unnecessary, btw.)
--
Pedro Alves
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-30 14:49 ` Pedro Alves
@ 2012-05-30 15:51 ` Metzger, Markus T
2012-05-30 17:56 ` Pedro Alves
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-30 15:51 UTC (permalink / raw)
To: Pedro Alves; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1986 bytes --]
> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> owner@sourceware.org] On Behalf Of Pedro Alves
> Sent: Wednesday, May 30, 2012 4:49 PM
> To: Metzger, Markus T
> Cc: kettenis@gnu.org; gdb-patches@sourceware.org;
> markus.t.metzger@gmail.com
> Subject: Re: [PATCH 00/16] branch tracing support (resend)
>
> On 05/29/2012 03:30 PM, Metzger, Markus T wrote:
>
> > I cannot reproduce this. I tried on several different systems
> > including 3.3.7-1.fc16.x86_64.
> > Have you seen this on other systems, as well?
>
>
> I tried again with the same kernel, and the crash was still there.
> I've updated my kernel to that version, and the crashes disappeared.
> I reverted to the previous kernel, and the crashes disappeared too...
> The update also brought along other system components, but it might be
> that there was just something broken in my gdb build. I don't have that
> particular binary any more.
Hmmm, strange.
> > Is there some configuration file or so that would allow me to build
> > gdb exactly the same way you do?
>
>
> just the usual: configure CFLAGS="-g3 -O0" && make
Depending on the state of the system, this can unfortunately result in very
different
things.
> > I can reproduce this. I changed the configuration without running
> > autoconf.
> ...
> > After
> > configuring, the gdb/testsuite/gdb.btrace directory is missing. I'll
> > add a
>
> > patch
> > with the autoconf changes to the series.
>
>
> Ah, I ran autoconf. The tests now run, but I get intermittent failures.
> Tested
> in a loop with:
>
> $ (set -e; while true; do make check RUNTESTFLAGS="--
> directory=gdb.btrace"; done)
[...]
The first hundred iterations are looking good on my system. I'm using
2.6.32-220.el6.x86_64, this time.
I'll let this run overnight and I'll try the fc16 system, as well.
If you could send me the gdb.log file, this would help.
> (Those "NOTE"'s looks quite unnecessary, btw.)
I removed them.
Thanks,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-05-30 15:51 ` Metzger, Markus T
@ 2012-05-30 17:56 ` Pedro Alves
2012-05-31 17:11 ` Metzger, Markus T
2012-06-12 11:32 ` Metzger, Markus T
0 siblings, 2 replies; 62+ messages in thread
From: Pedro Alves @ 2012-05-30 17:56 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1: Type: text/plain, Size: 882 bytes --]
On 05/30/2012 04:49 PM, Metzger, Markus T wrote:
>> Ah, I ran autoconf. The tests now run, but I get intermittent failures.
>> Tested
>> in a loop with:
>>
>> $ (set -e; while true; do make check RUNTESTFLAGS="--
>> directory=gdb.btrace"; done)
>
> [...]
>
> The first hundred iterations are looking good on my system.
In that case,
> I'm using 2.6.32-220.el6.x86_64, this time.
> I'll let this run overnight
that is probably unnecessary -- I get failures in almost every run, but the
set of tests that fail changes between runs.
> and I'll try the fc16 system, as well.
> If you could send me the gdb.log file, this would help.
I rebuilt my gdb from scratch just in case.
Attached two gdb.log files, of different runs showing different failures.
If you can't reproduce it on your f16 machine, it'd be perhaps good if
someone else also tried it.
--
Pedro Alves
[-- Attachment #2: gdb.log.1.gz --]
[-- Type: application/x-gzip, Size: 11278 bytes --]
[-- Attachment #3: gdb.log.2.gz --]
[-- Type: application/x-gzip, Size: 11079 bytes --]
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-30 17:56 ` Pedro Alves
@ 2012-05-31 17:11 ` Metzger, Markus T
2012-06-04 6:46 ` Metzger, Markus T
2012-06-12 11:32 ` Metzger, Markus T
1 sibling, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 17:11 UTC (permalink / raw)
To: Pedro Alves; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 2084 bytes --]
> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Wednesday, May 30, 2012 7:56 PM
> To: Metzger, Markus T
> > The first hundred iterations are looking good on my system.
>
>
> In that case,
>
> > I'm using 2.6.32-220.el6.x86_64, this time.
> > I'll let this run overnight
>
>
> that is probably unnecessary -- I get failures in almost every run, but the
> set of tests that fail changes between runs.
I get sporadic fails about every 1000th run. Most occur when switching
threads, i.e.
gdb_test "thread 2" ".*Switching to thread 2.*"
I got two timeouts while switching threads, as well.
> Attached two gdb.log files, of different runs showing different failures.
In the files you sent me, we do not get the full trace sometimes.
This might be related to a Linux perf_event feature. The perf_event consumer
is responsible for detecting when there are new records. The tracee is
scheduled
out after it notified its ptracer. When it is scheduled out, it may write a
few more
trace records. The ptracer may already be running, at this time.
In gdb/common/linux-btrace.c, I check for new data after I finished reading
the
trace, and start over again when I see new records. This was meant to mitigate
this.
Until now, I thought that this would be sufficient. In general, however, there
is no
guarantee that we will not get new trace records after we finished reading.
For interactive debugger use, this should not be a problem. There is plenty of
time
for the debuggee to write its last trace records before we start reading the
trace.
For scripting, however, it seems that we may indeed be too fast sometimes.
I don't have a solution for this. Ideally, the kernel would write branch trace
records
before notifying the ptracer. Or it would allow access to the actual trace
buffer given
to the hardware (which would avoid the write-back problem). In gdb, we could
yield
when reading branch trace to increase the chance that the debuggee finished
writing.
Or we simply accept this behavior as a strange curiosity.
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-31 17:11 ` Metzger, Markus T
@ 2012-06-04 6:46 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-04 6:46 UTC (permalink / raw)
To: Pedro Alves; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 673 bytes --]
> -----Original Message-----
> From: Metzger, Markus T
> Sent: Thursday, May 31, 2012 7:11 PM
[...]
> > Attached two gdb.log files, of different runs showing different failures.
>
> In the files you sent me, we do not get the full trace sometimes.
>
> This might be related to a Linux perf_event feature. The perf_event
> consumer
> is responsible for detecting when there are new records. The tracee is
> scheduled
> out after it notified its ptracer. When it is scheduled out, it may write a
> few more
> trace records. The ptracer may already be running, at this time.
I would mark this a known fail in the test suites until we can fix it.
[...]
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-30 17:56 ` Pedro Alves
2012-05-31 17:11 ` Metzger, Markus T
@ 2012-06-12 11:32 ` Metzger, Markus T
2012-06-12 12:09 ` Jan Kratochvil
2012-06-12 12:23 ` Pedro Alves
1 sibling, 2 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-12 11:32 UTC (permalink / raw)
To: Pedro Alves, Jan Kratochvil (jan.kratochvil@redhat.com)
Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1058 bytes --]
> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Wednesday, May 30, 2012 7:56 PM
> To: Metzger, Markus T
> >> Ah, I ran autoconf. The tests now run, but I get intermittent failures.
> >> Tested
> >> in a loop with:
> >>
> >> $ (set -e; while true; do make check RUNTESTFLAGS="--
> >> directory=gdb.btrace"; done)
[...]
> Attached two gdb.log files, of different runs showing different failures.
>
> If you can't reproduce it on your f16 machine, it'd be perhaps good if
> someone else also tried it.
I looked at your test logs again. Not all of the fails are covered by the
incomplete
trace theory.
I also tried reproducing the fails on different systems again - without
success. It
would be good to know if someone else sees those sporadic fails, as well.
Jan, have you applied the patches and run the tests when you reviewed the
series?
Pedro, can you give some more information about the system you are using that
might help me reproduce the fails? What hardware are you using, for example?
Thanks,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-06-12 11:32 ` Metzger, Markus T
@ 2012-06-12 12:09 ` Jan Kratochvil
2012-06-12 12:23 ` Pedro Alves
1 sibling, 0 replies; 62+ messages in thread
From: Jan Kratochvil @ 2012-06-12 12:09 UTC (permalink / raw)
To: Metzger, Markus T; +Cc: Pedro Alves, kettenis, gdb-patches, markus.t.metzger
On Tue, 12 Jun 2012 13:28:54 +0200, Metzger, Markus T wrote:
> Jan, have you applied the patches and run the tests when you reviewed the
> series?
Yes, I see no problems. Currently running kernel-3.3.8-1.fc16.x86_64 on
i7-2620M (it was apparently slightly older but still fc16 kernel before).
It all PASSes except for:
FAIL: gdb.btrace/threads_independent.exp: listing of thread[2], 1.14
FAIL: gdb.btrace/list.exp: btrace list 2.2
FAIL: gdb.btrace/list.exp: btrace list 2.3
FAIL: gdb.btrace/list.exp: btrace list 2.4
It is the [PATCH xx/17] series, IIRC the previous run fully PASSed otherwise
I would reply something about it but I no longer remember.
Thanks,
Jan
btr list /fa^M
1 0x0000000000400731 - 0x0000000000400731 in th_c ()^M
(gdb) FAIL: gdb.btrace/threads_independent.exp: listing of thread[2], 1.14
[...]
(gdb) btr list /af^M
No trace.^M
(gdb) FAIL: gdb.btrace/list.exp: btrace list 2.2
stepi^M
0x0000000000400221 in test_2_sub ()^M
(gdb) btr list /af^M
No trace.^M
(gdb) FAIL: gdb.btrace/list.exp: btrace list 2.3
stepi^M
0x0000000000400222 in test_2_sub ()^M
(gdb) btr list /af^M
No trace.^M
(gdb) FAIL: gdb.btrace/list.exp: btrace list 2.4
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-06-12 11:32 ` Metzger, Markus T
2012-06-12 12:09 ` Jan Kratochvil
@ 2012-06-12 12:23 ` Pedro Alves
2012-06-12 12:25 ` Jan Kratochvil
1 sibling, 1 reply; 62+ messages in thread
From: Pedro Alves @ 2012-06-12 12:23 UTC (permalink / raw)
To: Metzger, Markus T
Cc: Jan Kratochvil (jan.kratochvil@redhat.com),
kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
On 06/12/2012 12:28 PM, Metzger, Markus T wrote:
>
> Pedro, can you give some more information about the system you are using that
> might help me reproduce the fails? What hardware are you using, for example?
x86_64 Fedora 16, kernel 3.3.7-1.fc16.x86_64, running on an
i7-2620M @ 2.70GHz (an IBM ThinkPad T520)
A gz of my /proc/cpuinfo is attached, in case more detail helps.
--
Pedro Alves
[-- Attachment #2: cpuinfo.gz --]
[-- Type: application/x-gzip, Size: 649 bytes --]
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-06-12 12:23 ` Pedro Alves
@ 2012-06-12 12:25 ` Jan Kratochvil
2012-06-12 13:38 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-06-12 12:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: Metzger, Markus T, kettenis, gdb-patches, markus.t.metzger
On Tue, 12 Jun 2012 14:22:44 +0200, Pedro Alves wrote:
> x86_64 Fedora 16, kernel 3.3.7-1.fc16.x86_64, running on an
> i7-2620M @ 2.70GHz (an IBM ThinkPad T520)
IBM ThinkPad X220
> A gz of my /proc/cpuinfo is attached, in case more detail helps.
The only difference:
yours: microcode : 0x25
mine: microcode : 0x28
microcode_ctl-1.17-25.fc16.x86_64
Regards,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 00/16] branch tracing support (resend)
2012-06-12 12:25 ` Jan Kratochvil
@ 2012-06-12 13:38 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-12 13:38 UTC (permalink / raw)
To: Jan Kratochvil, Pedro Alves; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 878 bytes --]
Thanks Jan, Pedro,
I found an i7 laptop on which I can now reproduce the sporadic fails - about
once every dozen or so test iterations.
Thanks,
Markus.
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Tuesday, June 12, 2012 2:26 PM
> To: Pedro Alves
> Cc: Metzger, Markus T; kettenis@gnu.org; gdb-patches@sourceware.org;
> markus.t.metzger@gmail.com
> Subject: Re: [PATCH 00/16] branch tracing support (resend)
>
> On Tue, 12 Jun 2012 14:22:44 +0200, Pedro Alves wrote:
> > x86_64 Fedora 16, kernel 3.3.7-1.fc16.x86_64, running on an
> > i7-2620M @ 2.70GHz (an IBM ThinkPad T520)
>
> IBM ThinkPad X220
>
>
> > A gz of my /proc/cpuinfo is attached, in case more detail helps.
>
> The only difference:
> yours: microcode : 0x25
> mine: microcode : 0x28
>
> microcode_ctl-1.17-25.fc16.x86_64
>
>
> Regards,
> Jan
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (16 preceding siblings ...)
2012-05-25 19:18 ` [PATCH 00/16] branch tracing support (resend) Pedro Alves
@ 2012-05-30 20:41 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
2012-06-22 20:31 ` Tom Tromey
18 siblings, 1 reply; 62+ messages in thread
From: Jan Kratochvil @ 2012-05-30 20:41 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
On Wed, 23 May 2012 13:22:15 +0200, markus.t.metzger@intel.com wrote:
> - "btrace enable/disable" perform the obvious operation
>
> They accept an optional range argument specifying the range of threads to
> enable/disable branch tracing for. If no argument is given, they target the
> current thread.
>
> They further accept the following arguments:
>
> all targets all threads
> auto turns automatic enabling for new threads on/off
This threads selection should probably use the pending:
[RFC/WIP I/T sets V2 PATCH 00/14] I/T sets
http://sourceware.org/ml/gdb-patches/2011-12/msg00550.html
Thanks,
Jan
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 00/16] branch tracing support (resend)
2012-05-30 20:41 ` Jan Kratochvil
@ 2012-05-31 15:33 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-05-31 15:33 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 682 bytes --]
> -----Original Message-----
> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Wednesday, May 30, 2012 10:41 PM
> To: Metzger, Markus T
> > They further accept the following arguments:
> >
> > all targets all threads
> > auto turns automatic enabling for new threads on/off
>
> This threads selection should probably use the pending:
> [RFC/WIP I/T sets V2 PATCH 00/14] I/T sets
> http://sourceware.org/ml/gdb-patches/2011-12/msg00550.html
I'm currently using get_number_or_range () and friends for handling thread
ranges, and simple iteration over all threads for all.
I'll have a look at thread sets once they are in.
regards,
markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 00/16] branch tracing support (resend)
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
` (17 preceding siblings ...)
2012-05-30 20:41 ` Jan Kratochvil
@ 2012-06-22 20:31 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
18 siblings, 1 reply; 62+ messages in thread
From: Tom Tromey @ 2012-06-22 20:31 UTC (permalink / raw)
To: markus.t.metzger; +Cc: kettenis, gdb-patches, markus.t.metzger
>>>>> "Markus" == markus t metzger <markus.t.metzger@intel.com> writes:
Markus> IA hardware offers a feature called Branch Trace Store (BTS)
Markus> that stores a log of branches into an OS provided ring buffer.
Thanks for doing this. I think this is a feature we've wanted for quite
a while.
Markus> - "btrace enable/disable" perform the obvious operation
I think it may be more "gdb-ish" to make this a set/show option, by
analogy with "set stop-on-solib-events" and the like.
This would give users a way to see whether it is currently enabled, as
well.
Tom
^ permalink raw reply [flat|nested] 62+ messages in thread* RE: [PATCH 00/16] branch tracing support (resend)
2012-06-22 20:31 ` Tom Tromey
@ 2012-06-25 8:50 ` Metzger, Markus T
2012-07-02 8:29 ` Metzger, Markus T
0 siblings, 1 reply; 62+ messages in thread
From: Metzger, Markus T @ 2012-06-25 8:50 UTC (permalink / raw)
To: Tom Tromey; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 557 bytes --]
> -----Original Message-----
> From: Tom Tromey [mailto:tromey@redhat.com]
> Sent: Friday, June 22, 2012 10:31 PM
> To: Metzger, Markus T
[...]
> Markus> - "btrace enable/disable" perform the obvious operation
>
> I think it may be more "gdb-ish" to make this a set/show option, by
> analogy with "set stop-on-solib-events" and the like.
>
> This would give users a way to see whether it is currently enabled, as
> well.
You mean something like "set btrace on"?
Should we keep "auto" as sub-command? I.e. "set btrace auto on/off".
Regards,
Markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: [PATCH 00/16] branch tracing support (resend)
2012-06-25 8:50 ` Metzger, Markus T
@ 2012-07-02 8:29 ` Metzger, Markus T
0 siblings, 0 replies; 62+ messages in thread
From: Metzger, Markus T @ 2012-07-02 8:29 UTC (permalink / raw)
To: Tom Tromey; +Cc: kettenis, gdb-patches, markus.t.metzger
[-- Attachment #1.1: Type: text/plain, Size: 1120 bytes --]
> -----Original Message-----
> From: Metzger, Markus T
> Sent: Monday, June 25, 2012 10:50 AM
[...]
> > Markus> - "btrace enable/disable" perform the obvious operation
> >
> > I think it may be more "gdb-ish" to make this a set/show option, by
> > analogy with "set stop-on-solib-events" and the like.
> >
> > This would give users a way to see whether it is currently enabled, as
> > well.
>
> You mean something like "set btrace on"?
I looked at some other gdb commands with related behavior. Tracepoints uses tstart/tstop; record uses record/record stop. Record
uses set/show for configuration options.
By analogy, this could be used for configuring the size of the trace buffer. Or it could be used to turn automatic enabling on and
off.
Set typically changes some global setting, whereas the btrace enable/disable commands operate on the current thread or a range of
threads.
It might make sense to turn "btrace enable/disable auto" into "set btrace auto on/off". But I would leave the "btrace
enable/disable" commands, as they are - or maybe rename them into "btrace start/stop".
[...]
Regards,
markus.
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 417 bytes --]
--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 62+ messages in thread