[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