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

Commit 45177732 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

logcat: allow comma-separate list of buffers

- Add parsing to support comma+ separated list of buffers.
- Move get_size test into a standalone get_groups function
- add some additional tests for this feature, leveraging
  get_groups to confirm buffer selection.

Bug: 28120456
Change-Id: I0b42736c08cf4b2a435cb74cda540dc163a26bd1
parent 378f4745
Loading
Loading
Loading
Loading
+43 −91
Original line number Diff line number Diff line
@@ -315,8 +315,8 @@ static void show_help(const char *cmd)
                    // kernel (userdebug and eng) buffers undocumented.
                    "  -b <buffer>, --buffer=<buffer>         Request alternate ring buffer, 'main',\n"
                    "                  'system', 'radio', 'events', 'crash', 'default' or 'all'.\n"
                    "                  Multiple -b parameters are allowed. Buffers interleaved.\n"
                    "                  Default -b main -b system -b crash.\n"
                    "                  Multiple -b parameters or comma separated list of buffers are\n"
                    "                  allowed. Buffers interleaved. Default -b main,system,crash.\n"
                    "  -B, --binary    Output the log in binary.\n"
                    "  -S, --statistics                       Output statistics.\n"
                    "  -p, --prune     Print prune white and ~black list. Service is specified as\n"
@@ -762,55 +762,26 @@ int main(int argc, char **argv)
            break;

            case 'b': {
                unsigned idMask = 0;
                while ((optarg = strtok(optarg, ",:; \t\n\r\f")) != NULL) {
                    if (strcmp(optarg, "default") == 0) {
                    for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
                        switch (i) {
                        case LOG_ID_SECURITY:
                        case LOG_ID_EVENTS:
                            continue;
                        case LOG_ID_MAIN:
                        case LOG_ID_SYSTEM:
                        case LOG_ID_CRASH:
                            break;
                        default:
                            continue;
                        }

                        const char *name = android_log_id_to_name((log_id_t)i);
                        log_id_t log_id = android_name_to_log_id(name);

                        if (log_id != (log_id_t)i) {
                            continue;
                        }

                        bool found = false;
                        for (dev = devices; dev; dev = dev->next) {
                            if (!strcmp(optarg, dev->device)) {
                                found = true;
                                break;
                            }
                            if (!dev->next) {
                                break;
                            }
                        }
                        if (found) {
                            break;
                        }

                        log_device_t* d = new log_device_t(name, false);

                        if (dev) {
                            dev->next = d;
                            dev = d;
                        idMask |= (1 << LOG_ID_MAIN) |
                                  (1 << LOG_ID_SYSTEM) |
                                  (1 << LOG_ID_CRASH);
                    } else if (strcmp(optarg, "all") == 0) {
                        idMask = (unsigned)-1;
                    } else {
                            devices = dev = d;
                        log_id_t log_id = android_name_to_log_id(optarg);
                        const char *name = android_log_id_to_name(log_id);

                        if (strcmp(name, optarg) != 0) {
                            logcat_panic(true, "unknown buffer %s\n", optarg);
                        }
                        g_devCount++;
                        idMask |= (1 << log_id);
                    }
                    break;
                    optarg = NULL;
                }

                if (strcmp(optarg, "all") == 0) {
                for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
                    const char *name = android_log_id_to_name((log_id_t)i);
                    log_id_t log_id = android_name_to_log_id(name);
@@ -818,10 +789,13 @@ int main(int argc, char **argv)
                    if (log_id != (log_id_t)i) {
                        continue;
                    }
                    if ((idMask & (1 << i)) == 0) {
                        continue;
                    }

                    bool found = false;
                    for (dev = devices; dev; dev = dev->next) {
                            if (!strcmp(optarg, dev->device)) {
                        if (!strcmp(name, dev->device)) {
                            found = true;
                            break;
                        }
@@ -830,7 +804,7 @@ int main(int argc, char **argv)
                        }
                    }
                    if (found) {
                            break;
                        continue;
                    }

                    bool binary = !strcmp(name, "events") ||
@@ -845,28 +819,6 @@ int main(int argc, char **argv)
                    }
                    g_devCount++;
                }
                    break;
                }

                bool binary = !(strcmp(optarg, "events") &&
                                strcmp(optarg, "security"));

                if (devices) {
                    dev = devices;
                    while (dev->next) {
                        if (!strcmp(optarg, dev->device)) {
                            dev = NULL;
                            break;
                        }
                        dev = dev->next;
                    }
                    if (dev) {
                        dev->next = new log_device_t(optarg, binary);
                    }
                } else {
                    devices = new log_device_t(optarg, binary);
                }
                g_devCount++;
            }
            break;

+42 −22
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#include <log/logger.h>
#include <log/log_read.h>

#define BIG_BUFFER (5 * 1024)

// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
// non-syscall libs. Since we are only using this in the emergency of
// a signal to stuff a terminating code into the logs, we will spin rather
@@ -54,7 +56,7 @@ TEST(logcat, buckets) {
      "logcat -b radio -b events -b system -b main -d 2>/dev/null",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int ids = 0;
    int count = 0;
@@ -102,7 +104,7 @@ TEST(logcat, year) {
      "logcat -v long -v year -b all -t 3 2>/dev/null",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -165,7 +167,7 @@ TEST(logcat, tz) {
          "logcat -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
          "r")));

        char buffer[5120];
        char buffer[BIG_BUFFER];

        count = 0;

@@ -189,7 +191,7 @@ TEST(logcat, ntz) {
      "logcat -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -209,7 +211,7 @@ void do_tail(int num) {
    int count;

    do {
        char buffer[5120];
        char buffer[BIG_BUFFER];

        snprintf(buffer, sizeof(buffer),
          "logcat -v long -b radio -b events -b system -b main -t %d 2>/dev/null",
@@ -252,7 +254,7 @@ TEST(logcat, tail_time) {

    ASSERT_TRUE(NULL != (fp = popen("logcat -v long -b all -t 10 2>&1", "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];
    char *last_timestamp = NULL;
    char *first_timestamp = NULL;
    int count = 0;
@@ -315,7 +317,7 @@ TEST(logcat, End_to_End) {
      "logcat -v brief -b events -t 100 2>/dev/null",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -339,15 +341,17 @@ TEST(logcat, End_to_End) {
    ASSERT_EQ(1, count);
}

TEST(logcat, get_size) {
int get_groups(const char *cmd) {
    FILE *fp;

    // NB: crash log only available in user space
    ASSERT_TRUE(NULL != (fp = popen(
      "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null",
      "r")));
    EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));

    if (fp == NULL) {
        return 0;
    }

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -407,7 +411,23 @@ TEST(logcat, get_size) {

    pclose(fp);

    ASSERT_EQ(4, count);
    return count;
}

TEST(logcat, get_size) {
    ASSERT_EQ(4, get_groups(
      "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null"));
}

// duplicate test for get_size, but use comma-separated list of buffers
TEST(logcat, multiple_buffer) {
    ASSERT_EQ(4, get_groups(
      "logcat -v brief -b radio,events,system,main -g 2>/dev/null"));
}

TEST(logcat, bad_buffer) {
    ASSERT_EQ(0, get_groups(
      "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
}

static void caught_blocking(int /*signum*/)
@@ -436,7 +456,7 @@ TEST(logcat, blocking) {
      " logcat -v brief -b events 2>&1",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -505,7 +525,7 @@ TEST(logcat, blocking_tail) {
      " logcat -v brief -b events -T 5 2>&1",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -568,7 +588,7 @@ TEST(logcat, logrotate) {
        FILE *fp;
        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
        if (fp) {
            char buffer[5120];
            char buffer[BIG_BUFFER];
            int count = 0;

            while (fgets(buffer, sizeof(buffer), fp)) {
@@ -611,7 +631,7 @@ TEST(logcat, logrotate_suffix) {

        FILE *fp;
        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
        char buffer[5120];
        char buffer[BIG_BUFFER];
        int log_file_count = 0;

        while (fgets(buffer, sizeof(buffer), fp)) {
@@ -784,7 +804,7 @@ TEST(logcat, blocking_clear) {
      " logcat -v brief -b events 2>&1",
      "r")));

    char buffer[5120];
    char buffer[BIG_BUFFER];

    int count = 0;

@@ -845,7 +865,7 @@ static bool get_white_black(char **list) {
        return false;
    }

    char buffer[5120];
    char buffer[BIG_BUFFER];

    while (fgets(buffer, sizeof(buffer), fp)) {
        char *hold = *list;
@@ -874,7 +894,7 @@ static bool get_white_black(char **list) {
static bool set_white_black(const char *list) {
    FILE *fp;

    char buffer[5120];
    char buffer[BIG_BUFFER];

    snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
    fp = popen(buffer, "r");
@@ -936,7 +956,7 @@ TEST(logcat, regex) {
    FILE *fp;
    int count = 0;

    char buffer[5120];
    char buffer[BIG_BUFFER];

    snprintf(buffer, sizeof(buffer), "logcat --pid %d -d -e logcat_test_a+b", getpid());

@@ -969,7 +989,7 @@ TEST(logcat, maxcount) {
    FILE *fp;
    int count = 0;

    char buffer[5120];
    char buffer[BIG_BUFFER];

    snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3", getpid());