Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1340141 authored by Martijn Coenen's avatar Martijn Coenen Committed by android-build-merger
Browse files

Merge "Atrace: support streaming data to stdout." am: 83a98b10

am: 78d4fb8e

* commit '78d4fb8e':
  Atrace: support streaming data to stdout.
parents 8c0dbf91 78d4fb8e
Loading
Loading
Loading
Loading
+47 −3
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@
#include <string.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/sendfile.h>
#include <time.h>
#include <time.h>
#include <unistd.h>
#include <zlib.h>
#include <zlib.h>


#include <binder/IBinder.h>
#include <binder/IBinder.h>
@@ -211,6 +212,9 @@ static const char* k_tracingOnPath =
static const char* k_tracePath =
static const char* k_tracePath =
    "/sys/kernel/debug/tracing/trace";
    "/sys/kernel/debug/tracing/trace";


static const char* k_traceStreamPath =
    "/sys/kernel/debug/tracing/trace_pipe";

static const char* k_traceMarkerPath =
static const char* k_traceMarkerPath =
    "/sys/kernel/debug/tracing/trace_marker";
    "/sys/kernel/debug/tracing/trace_marker";


@@ -729,6 +733,31 @@ static void stopTrace()
    setTracingEnabled(false);
    setTracingEnabled(false);
}
}


// Read data from the tracing pipe and forward to stdout
static void streamTrace()
{
    char trace_data[4096];
    int traceFD = open(k_traceStreamPath, O_RDWR);
    if (traceFD == -1) {
        fprintf(stderr, "error opening %s: %s (%d)\n", k_traceStreamPath,
                strerror(errno), errno);
        return;
    }
    while (!g_traceAborted) {
        ssize_t bytes_read = read(traceFD, trace_data, 4096);
        if (bytes_read > 0) {
            write(STDOUT_FILENO, trace_data, bytes_read);
            fflush(stdout);
        } else {
            if (!g_traceAborted) {
                fprintf(stderr, "read returned %zd bytes err %d (%s)\n",
                        bytes_read, errno, strerror(errno));
            }
            break;
        }
    }
}

// Read the current kernel trace and write it to stdout.
// Read the current kernel trace and write it to stdout.
static void dumpTrace()
static void dumpTrace()
{
{
@@ -875,6 +904,10 @@ static void showHelp(const char *cmd)
                    "  --async_dump    dump the current contents of circular trace buffer\n"
                    "  --async_dump    dump the current contents of circular trace buffer\n"
                    "  --async_stop    stop tracing and dump the current contents of circular\n"
                    "  --async_stop    stop tracing and dump the current contents of circular\n"
                    "                    trace buffer\n"
                    "                    trace buffer\n"
                    "  --stream        stream trace to stdout as it enters the trace buffer\n"
                    "                    Note: this can take significant CPU time, and is best\n"
                    "                    used for measuring things that are not affected by\n"
                    "                    CPU performance, like pagecache usage.\n"
                    "  --list_categories\n"
                    "  --list_categories\n"
                    "                  list the available tracing categories\n"
                    "                  list the available tracing categories\n"
            );
            );
@@ -886,6 +919,7 @@ int main(int argc, char **argv)
    bool traceStart = true;
    bool traceStart = true;
    bool traceStop = true;
    bool traceStop = true;
    bool traceDump = true;
    bool traceDump = true;
    bool traceStream = false;


    if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
    if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
        showHelp(argv[0]);
        showHelp(argv[0]);
@@ -900,6 +934,7 @@ int main(int argc, char **argv)
            {"async_stop",      no_argument, 0,  0 },
            {"async_stop",      no_argument, 0,  0 },
            {"async_dump",      no_argument, 0,  0 },
            {"async_dump",      no_argument, 0,  0 },
            {"list_categories", no_argument, 0,  0 },
            {"list_categories", no_argument, 0,  0 },
            {"stream",          no_argument, 0,  0 },
            {           0,                0, 0,  0 }
            {           0,                0, 0,  0 }
        };
        };


@@ -966,6 +1001,9 @@ int main(int argc, char **argv)
                    async = true;
                    async = true;
                    traceStart = false;
                    traceStart = false;
                    traceStop = false;
                    traceStop = false;
                } else if (!strcmp(long_options[option_index].name, "stream")) {
                    traceStream = true;
                    traceDump = false;
                } else if (!strcmp(long_options[option_index].name, "list_categories")) {
                } else if (!strcmp(long_options[option_index].name, "list_categories")) {
                    listSupportedCategories();
                    listSupportedCategories();
                    exit(0);
                    exit(0);
@@ -991,8 +1029,10 @@ int main(int argc, char **argv)
    ok &= startTrace();
    ok &= startTrace();


    if (ok && traceStart) {
    if (ok && traceStart) {
        if (!traceStream) {
            printf("capturing trace...");
            printf("capturing trace...");
            fflush(stdout);
            fflush(stdout);
        }


        // We clear the trace after starting it because tracing gets enabled for
        // We clear the trace after starting it because tracing gets enabled for
        // each CPU individually in the kernel. Having the beginning of the trace
        // each CPU individually in the kernel. Having the beginning of the trace
@@ -1002,7 +1042,7 @@ int main(int argc, char **argv)
        ok = clearTrace();
        ok = clearTrace();


        writeClockSyncMarker();
        writeClockSyncMarker();
        if (ok && !async) {
        if (ok && !async && !traceStream) {
            // Sleep to allow the trace to be captured.
            // Sleep to allow the trace to be captured.
            struct timespec timeLeft;
            struct timespec timeLeft;
            timeLeft.tv_sec = g_traceDurationSeconds;
            timeLeft.tv_sec = g_traceDurationSeconds;
@@ -1013,6 +1053,10 @@ int main(int argc, char **argv)
                }
                }
            } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR);
            } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR);
        }
        }

        if (traceStream) {
            streamTrace();
        }
    }
    }


    // Stop the trace and restore the default settings.
    // Stop the trace and restore the default settings.