[GSOC 2014][PATCH 4/7] JSON: Add support to entering/exiting of syscall

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


Each syscall in the output will be a object in a single line.
The object has at least 3 attributes:"type", "name", "args" and "ret".
the vaule of "args" is an array and the output now  only support string
as the basic value.

* syscall.c (trace_syscall_entering, trace_syscall_exiting):
Add support for entering/exiting of syscalls.

* process.c(sys_exit): Add support for special case of sys_exit().
---
 process.c |  3 ++-
 syscall.c | 84 +++++++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/process.c b/process.c
index 2cd0f01..93678ad 100644
--- a/process.c
+++ b/process.c
@@ -260,7 +260,8 @@ sys_exit(struct tcb *tcp)
 	/* special case: we stop tracing this process, finish line now */
 	tprintf("%ld) ", tcp->u_arg[0]);
 	tabto();
-	tprints("= ?\n");
+	tprintf("= %s\n", "?");
+	json_event(JSON_ARG, JSON_ARGS_END, JSON_SEPA, JSON_RET, JSON_CALL_END ,JSON_NEWLINE);
 	line_ended();
 	return 0;
 }
diff --git a/syscall.c b/syscall.c
index b0ad47e..19e0b6e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -1984,8 +1984,11 @@ trace_syscall_entering(struct tcb *tcp)
 
 	if (res != 1) {
 		printleader(tcp);
-		if (scno_good != 1)
-			tprints("????" /* anti-trigraph gap */ "(");
+		json_event(JSON_CALL_BEGIN, JSON_SEPA);
+		if (scno_good != 1) {
+			tprintf("%s", "????");
+			tprints("(");
+		}
 		else if (tcp->qual_flg & UNDEFINED_SCNO)
 			tprintf("%s(", undefined_scno_name(tcp));
 		else
@@ -1994,6 +1997,7 @@ trace_syscall_entering(struct tcb *tcp)
 		 * " <unavailable>" will be added later by the code which
 		 * detects ptrace errors.
 		 */
+		json_event(JSON_NAME, JSON_SEPA, JSON_ARGS_BEGIN);
 		goto ret;
 	}
 
@@ -2048,14 +2052,19 @@ trace_syscall_entering(struct tcb *tcp)
 #endif
 
 	printleader(tcp);
+	json_event(JSON_CALL_BEGIN, JSON_SEPA);
 	if (tcp->qual_flg & UNDEFINED_SCNO)
 		tprintf("%s(", undefined_scno_name(tcp));
 	else
 		tprintf("%s(", tcp->s_ent->sys_name);
-	if ((tcp->qual_flg & QUAL_RAW) && tcp->s_ent->sys_func != sys_exit)
+	json_event(JSON_NAME, JSON_SEPA, JSON_ARGS_BEGIN);
+
+	if ((tcp->qual_flg & QUAL_RAW) && tcp->s_ent->sys_func != sys_exit) {
 		res = printargs(tcp);
-	else
+	}
+	else {
 		res = tcp->s_ent->sys_func(tcp);
+	}
 
 	fflush(tcp->outf);
  ret:
@@ -2567,10 +2576,13 @@ trace_syscall_exiting(struct tcb *tcp)
 	printing_tcp = tcp;
 
 	if (res != 1) {
-		/* There was error in one of prior ptrace ops */
-		tprints(") ");
+				/* There was error in one of prior ptrace ops */
+		tprintf(") = %s <%s>\n", "?", "unavailable");
+		json_event(JSON_ARGS_END, JSON_SEPA,
+					  JSON_RET, JSON_SEPA,
+					  JSON_DESC,
+					  JSON_CALL_END , JSON_NEWLINE);
 		tabto();
-		tprints("= ? <unavailable>\n");
 		line_ended();
 		tcp->flags &= ~TCB_INSYSCALL;
 		return res;
@@ -2594,15 +2606,21 @@ trace_syscall_exiting(struct tcb *tcp)
 	}
 
 	tprints(") ");
+	json_event(JSON_ARGS_END, JSON_SEPA);
 	tabto();
-	u_error = tcp->u_error;
+		u_error = tcp->u_error;
 	if (tcp->qual_flg & QUAL_RAW) {
-		if (u_error)
-			tprintf("= -1 (errno %ld)", u_error);
-		else
+		if (u_error) {
+			tprintf("= %s (errno %ld)", "-1", u_error);
+			json_event(JSON_RET, JSON_SEPA, JSON_ERRNO);
+		}
+		else {
 			tprintf("= %#lx", tcp->u_rval);
+			json_event(JSON_RET);
+		}
 	}
 	else if (!(sys_res & RVAL_NONE) && u_error) {
+		json_event_t second = JSON_DESC;
 		switch (u_error) {
 		/* Blocked signals do not interrupt any syscalls.
 		 * In this case syscalls don't return ERESTARTfoo codes.
@@ -2625,13 +2643,13 @@ trace_syscall_exiting(struct tcb *tcp)
 			 * The system call will be restarted with the same arguments
 			 * if SA_RESTART is set; otherwise, it will fail with EINTR.
 			 */
-			tprints("= ? ERESTARTSYS (To be restarted if SA_RESTART is set)");
+			tprintf("= %s %s (%s)", "?", "ERESTARTSYS", "To be restarted if SA_RESTART is set");
 			break;
 		case ERESTARTNOINTR:
 			/* Rare. For example, fork() returns this if interrupted.
 			 * SA_RESTART is ignored (assumed set): the restart is unconditional.
 			 */
-			tprints("= ? ERESTARTNOINTR (To be restarted)");
+			tprintf("= %s %s (%s)", "?", "ERESTARTNOINTR", "To be restarted");
 			break;
 		case ERESTARTNOHAND:
 			/* pause(), rt_sigsuspend() etc use this code.
@@ -2641,7 +2659,7 @@ trace_syscall_exiting(struct tcb *tcp)
 			 * after SIG_IGN or SIG_DFL signal it will restart
 			 * (thus the name "restart only if has no handler").
 			 */
-			tprints("= ? ERESTARTNOHAND (To be restarted if no handler)");
+			tprintf("= %s %s (%s)", "?", "ERESTARTNOHAND", "To be restarted if no handler");
 			break;
 		case ERESTART_RESTARTBLOCK:
 			/* Syscalls like nanosleep(), poll() which can't be
@@ -2655,25 +2673,30 @@ trace_syscall_exiting(struct tcb *tcp)
 			 * which in turn saves another such restart block,
 			 * old data is lost and restart becomes impossible)
 			 */
-			tprints("= ? ERESTART_RESTARTBLOCK (Interrupted by signal)");
+			tprintf("= %s %s (%s)", "?", "ERESTART_RESTARTBLOCK", "Interrupted by signal");
 			break;
 		default:
 			if (u_error < 0)
-				tprintf("= -1 E??? (errno %ld)", u_error);
+				tprintf("= %d %s (errno %ld)", -1, "E???", u_error);
 			else if (u_error < nerrnos)
-				tprintf("= -1 %s (%s)", errnoent[u_error],
-					strerror(u_error));
-			else
-				tprintf("= -1 ERRNO_%ld (%s)", u_error,
-					strerror(u_error));
+				tprintf("= %d %s (%s)", -1, errnoent[u_error], strerror(u_error));
+			else {
+				tprintf("= %d ERRNO_%ld (%s)", -1, u_error, strerror(u_error));
+				second = JSON_ERRNO;
+			}
 			break;
 		}
-		if ((sys_res & RVAL_STR) && tcp->auxstr)
-			tprintf(" (%s)", tcp->auxstr);
+		json_event(JSON_RET, JSON_SEPA, second, JSON_SEPA, JSON_DESC_LONG);
+
+		if ((sys_res & RVAL_STR) && tcp->auxstr) {
+						tprintf(" (%s)", tcp->auxstr);
+			json_event(JSON_SEPA, JSON_AUXSTR);
+		}
 	}
 	else {
-		if (sys_res & RVAL_NONE)
-			tprints("= ?");
+		if (sys_res & RVAL_NONE) {
+			tprintf("= %s", "?");
+		}
 		else {
 			switch (sys_res & RVAL_MASK) {
 			case RVAL_HEX:
@@ -2715,13 +2738,15 @@ trace_syscall_exiting(struct tcb *tcp)
 			*/
 #endif
 			default:
-				fprintf(stderr,
-					"invalid rval format\n");
+				fprintf(stderr, "invalid rval format\n");
 				break;
 			}
+			json_event(JSON_RET);
+		}
+		if ((sys_res & RVAL_STR) && tcp->auxstr) {
+						tprintf(" (%s)", tcp->auxstr);
+			json_event(JSON_SEPA, JSON_AUXSTR);
 		}
-		if ((sys_res & RVAL_STR) && tcp->auxstr)
-			tprintf(" (%s)", tcp->auxstr);
 	}
 	if (Tflag) {
 		tv_sub(&tv, &tv, &tcp->etime);
@@ -2729,6 +2754,7 @@ trace_syscall_exiting(struct tcb *tcp)
 			(long) tv.tv_sec, (long) tv.tv_usec);
 	}
 	tprints("\n");
+	json_event(JSON_CALL_END , JSON_NEWLINE);
 	dumpio(tcp);
 	line_ended();
 
-- 
1.9.1





More information about the Strace-devel mailing list