[GSOC 2014][PATCH 2/7] JSON: Add '-j' option to support JSON output

Zhu YangMin zym0017d at gmail.com
Mon Jul 21 14:35:24 UTC 2014


Modify strace to use the JSON framework.

* Makefile.am: Add json.c to compile list.
* strace.c(tprintf, tprints, usage, init): Add a new option '-j'
in init(), Modify tprintf/tprints to use the basic JSON framework,
Add 2 new function:_tprintf/_tprints for the original output.
* strace.1: Add document for '-j' option.
---
 Makefile.am |  1 +
 strace.1    |  3 +++
 strace.c    | 45 +++++++++++++++++++++++++++++++++++++++------
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index be05946..4ce8d44 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,6 +29,7 @@ strace_SOURCES =	\
 	ioctl.c		\
 	ioprio.c	\
 	ipc.c		\
+	json.c		\
 	kexec.c		\
 	keyctl.c	\
 	ldt.c		\
diff --git a/strace.1 b/strace.1
index 2a24c38..d1bb3aa 100644
--- a/strace.1
+++ b/strace.1
@@ -267,6 +267,9 @@ Print the help summary.
 .B \-i
 Print the instruction pointer at the time of the system call.
 .TP
+.B \-j
+Print the trace results in JSON format.
+.TP
 .B \-k
 Print the execution stack trace of the traced processes after each system call (experimental).
 .TP
diff --git a/strace.c b/strace.c
index 4154cde..deb636b 100644
--- a/strace.c
+++ b/strace.c
@@ -89,6 +89,8 @@ static unsigned int syscall_trap_sig = SIGTRAP;
 static unsigned int tflag = 0;
 static bool rflag = 0;
 static bool print_pid_pfx = 0;
+/* Support option '-j' to enable JSON output */
+int jflag = 0;
 
 /* -I n */
 enum {
@@ -210,6 +212,7 @@ usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
 -D -- run tracer process as a detached grandchild, not as parent\n\
 -f -- follow forks, -ff -- with output into separate files\n\
 -i -- print instruction pointer at time of syscall\n\
+-j -- print the trace results in JSON format\n\
 -q -- suppress messages about attaching, detaching, etc.\n\
 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
 -T -- print time spent in each syscall\n\
@@ -535,11 +538,8 @@ strace_popen(const char *command)
 }
 
 void
-tprintf(const char *fmt, ...)
+_tvprintf(const char *fmt, va_list args)
 {
-	va_list args;
-
-	va_start(args, fmt);
 	if (current_tcp) {
 		int n = strace_vfprintf(current_tcp->outf, fmt, args);
 		if (n < 0) {
@@ -548,6 +548,21 @@ tprintf(const char *fmt, ...)
 		} else
 			current_tcp->curcol += n;
 	}
+}
+
+void
+tprintf(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	// json_tprintf is defined in json.c
+	extern void json_tprintf(const char *fmt, va_list args);
+	if (jflag == 0)
+		_tvprintf(fmt, args);
+	else
+		json_tprintf(fmt, args);
+
 	va_end(args);
 }
 
@@ -556,7 +571,7 @@ tprintf(const char *fmt, ...)
 #endif
 
 void
-tprints(const char *str)
+_tprints(const char *str)
 {
 	if (current_tcp) {
 		int n = fputs_unlocked(str, current_tcp->outf);
@@ -570,6 +585,17 @@ tprints(const char *str)
 }
 
 void
+tprints(const char *str)
+{
+	// json_tprints is defined in json.c
+	extern void json_tprints(const char *str);
+	if (jflag == 0)
+		_tprints(str);
+	else
+		json_tprints(str);
+}
+
+void
 line_ended(void)
 {
 	if (current_tcp) {
@@ -1672,7 +1698,7 @@ init(int argc, char *argv[])
 #endif
 	qualify("signal=all");
 	while ((c = getopt(argc, argv,
-		"+b:cCdfFhiqrtTvVwxyz"
+		"+b:cCdfFhijqrtTvVwxyz"
 #ifdef USE_LIBUNWIND
 		"k"
 #endif
@@ -1715,6 +1741,13 @@ init(int argc, char *argv[])
 		case 'i':
 			iflag = 1;
 			break;
+		case 'j':
+			jflag = 1; // must before json_init()
+			if (json_init() == -1) {
+				fprintf(stderr, "json_init() failed, back to normal output.\n");
+				jflag = 0;
+			}
+			break;
 		case 'q':
 			qflag++;
 			break;
-- 
1.9.1





More information about the Strace-devel mailing list