Now the JSON output is one dict object each line, representing a
the enter/exit of a syscall. The dict object contain key filed
such as 'type', 'name', 'ret' of a syscall. All the value are string.

* syscall.c(trace_syscall_entering, trace_syscall_exiting): Modify to support
in JSON format.
* process.c(sys_exit): Modify to support in JSON format.
* strace.c(trace): Modify to support the last exited signal in JSON format.
---
 process.c |  6 +++++
 strace.c  |  7 +++++-
 syscall.c | 84 +++++++++++++++++++++++++++++++++++++++++++--------------------
 3 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/process.c b/process.c
index a880f9e..9b40922 100644
--- a/process.c
+++ b/process.c
@@ -258,7 +258,13 @@ sys_exit(struct tcb *tcp)
                return -1;
        }
        /* special case: we stop tracing this process, finish line now */
+       JSON_BEGIN_META_MODE;
        tprintf("%ld) ", tcp->u_arg[0]);
+       json_event(4, EVENT_ARG,
+                                 EVENT_ARGS_END | SEPARATOR,
+                                 EVENT_RET,
+                                 EVENT_CALL_END | NEWLINE);
+
        tabto();
        tprints("= ?\n");
        line_ended();
diff --git a/strace.c b/strace.c
index 800f229..792189f 100644
--- a/strace.c
+++ b/strace.c
@@ -2303,7 +2303,12 @@ trace(void)
                        if (cflag != CFLAG_ONLY_STATS &&
                            qflag < 2) {
                                printleader(tcp);
-                               tprintf("+++ exited with %d +++\n", 
WEXITSTATUS(status));
+                               JSON_BEGIN_META_MODE;
+                               tprintf("+++ %s with %d +++\n", "exited", 
WEXITSTATUS(status));
+                               json_event(4, EVENT_SIGNAL_BEGIN | SEPARATOR,
+                                                         EVENT_DESC | 
SEPARATOR,
+                                                         EVENT_SIGCODE,
+                                                         EVENT_SIGNAL_END | 
NEWLINE);
                                line_ended();
                        }
                        droptcb(tcp);
diff --git a/syscall.c b/syscall.c
index b0ad47e..9ccc504 100644
--- a/syscall.c
+++ b/syscall.c
@@ -1984,8 +1984,12 @@ trace_syscall_entering(struct tcb *tcp)
 
        if (res != 1) {
                printleader(tcp);
-               if (scno_good != 1)
-                       tprints("????" /* anti-trigraph gap */ "(");
+               json_event(1, EVENT_CALL_BEGIN | SEPARATOR);
+               JSON_BEGIN_META_MODE;
+               if (scno_good != 1) {
+                       JSON_META( tprints("????"); );
+                       tprints("(");
+               }
                else if (tcp->qual_flg & UNDEFINED_SCNO)
                        tprintf("%s(", undefined_scno_name(tcp));
                else
@@ -1994,6 +1998,7 @@ trace_syscall_entering(struct tcb *tcp)
                 * " <unavailable>" will be added later by the code which
                 * detects ptrace errors.
                 */
+               json_event(2, EVENT_NAME | SEPARATOR, EVENT_ARGS_BEGIN);
                goto ret;
        }
 
@@ -2048,14 +2053,20 @@ trace_syscall_entering(struct tcb *tcp)
 #endif
 
        printleader(tcp);
+       json_event(1, EVENT_CALL_BEGIN | SEPARATOR);
+       JSON_BEGIN_META_MODE;
        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(2, EVENT_NAME | SEPARATOR, EVENT_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 +2578,14 @@ trace_syscall_exiting(struct tcb *tcp)
        printing_tcp = tcp;
 
        if (res != 1) {
+               JSON_BEGIN_META_MODE;
                /* There was error in one of prior ptrace ops */
-               tprints(") ");
+               tprintf(") = %s <%s>\n", "?", "unavailable");
+               json_event(4, EVENT_ARGS_END | SEPARATOR,
+                                         EVENT_RET | SEPARATOR,
+                                         EVENT_DESC,
+                                         EVENT_CALL_END | NEWLINE);
                tabto();
-               tprints("= ? <unavailable>\n");
                line_ended();
                tcp->flags &= ~TCB_INSYSCALL;
                return res;
@@ -2594,15 +2609,22 @@ trace_syscall_exiting(struct tcb *tcp)
        }
 
        tprints(") ");
+       json_event(1, EVENT_ARGS_END | SEPARATOR);
        tabto();
+       JSON_BEGIN_META_MODE;
        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(2, EVENT_RET | SEPARATOR, EVENT_ERRNO);
+               }
+               else {
                        tprintf("= %#lx", tcp->u_rval);
+                       json_event(1, EVENT_RET);
+               }
        }
        else if (!(sys_res & RVAL_NONE) && u_error) {
+               json_type_event second = EVENT_DESC;
                switch (u_error) {
                /* Blocked signals do not interrupt any syscalls.
                 * In this case syscalls don't return ERESTARTfoo codes.
@@ -2625,13 +2647,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 +2663,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 +2677,31 @@ 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 = EVENT_ERRNO;
+                       }
                        break;
                }
-               if ((sys_res & RVAL_STR) && tcp->auxstr)
+               json_event(3, EVENT_RET | SEPARATOR, second | SEPARATOR, 
EVENT_DESC_LONG);
+
+               if ((sys_res & RVAL_STR) && tcp->auxstr) {
+                       JSON_BEGIN_META_MODE;
                        tprintf(" (%s)", tcp->auxstr);
+                       json_event(1, BEF_SEPRATOR | EVENT_AUXSTR);
+               }
        }
        else {
-               if (sys_res & RVAL_NONE)
-                       tprints("= ?");
+               if (sys_res & RVAL_NONE) {
+                       tprintf("= %s", "?");
+               }
                else {
                        switch (sys_res & RVAL_MASK) {
                        case RVAL_HEX:
@@ -2691,7 +2719,7 @@ trace_syscall_exiting(struct tcb *tcp)
                        case RVAL_FD:
                                if (show_fd_path) {
                                        tprints("= ");
-                                       printfd(tcp, tcp->u_rval);
+                                       JSON_META( printfd(tcp, tcp->u_rval); );
                                }
                                else
                                        tprintf("= %ld", tcp->u_rval);
@@ -2715,13 +2743,16 @@ trace_syscall_exiting(struct tcb *tcp)
                        */
 #endif
                        default:
-                               fprintf(stderr,
-                                       "invalid rval format\n");
+                               fprintf(stderr, "invalid rval format\n");
                                break;
                        }
+                       json_event(1, EVENT_RET);
                }
-               if ((sys_res & RVAL_STR) && tcp->auxstr)
+               if ((sys_res & RVAL_STR) && tcp->auxstr) {
+                       JSON_BEGIN_META_MODE;
                        tprintf(" (%s)", tcp->auxstr);
+                       json_event(1, BEF_SEPRATOR | EVENT_AUXSTR);
+               }
        }
        if (Tflag) {
                tv_sub(&tv, &tv, &tcp->etime);
@@ -2729,6 +2760,7 @@ trace_syscall_exiting(struct tcb *tcp)
                        (long) tv.tv_sec, (long) tv.tv_usec);
        }
        tprints("\n");
+       json_event(1, EVENT_CALL_END | NEWLINE);
        dumpio(tcp);
        line_ended();
 
-- 
1.9.1


------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to