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

Commit ef1081f9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Added support for 'bugreport -z'." into nyc-dev

parents 9b9fc471 2628e9e9
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,11 @@
// output. All of the dumpstate output is written to stdout, including
// output. All of the dumpstate output is written to stdout, including
// any errors encountered while reading/writing the output.
// any errors encountered while reading/writing the output.
int main() {
int main() {

  fprintf(stderr, "=============================================================================\n");
  fprintf(stderr, "WARNING: flat bugreports are deprecated, use adb bugreport <zip_file> instead\n");
  fprintf(stderr, "=============================================================================\n\n\n");

  // Start the dumpstate service.
  // Start the dumpstate service.
  property_set("ctl.start", "dumpstate");
  property_set("ctl.start", "dumpstate");


+12 −0
Original line number Original line Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= bugreportz.cpp

LOCAL_MODULE:= bugreportz

LOCAL_CFLAGS := -Wall

LOCAL_SHARED_LIBRARIES := libcutils

include $(BUILD_EXECUTABLE)
+93 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <cutils/properties.h>
#include <cutils/sockets.h>

// TODO: code below was copy-and-pasted from bugreport.cpp (except by the timeout value);
// should be reused instead.
int main() {

    // Start the dumpstatez service.
    property_set("ctl.start", "dumpstatez");

    // Socket will not be available until service starts.
    int s;
    for (int i = 0; i < 20; i++) {
        s = socket_local_client("dumpstate", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
        if (s >= 0)
            break;
        // Try again in 1 second.
        sleep(1);
    }

    if (s == -1) {
        printf("Failed to connect to dumpstatez service: %s\n", strerror(errno));
        return 1;
    }

    // Set a timeout so that if nothing is read in 10 minutes, we'll stop
    // reading and quit. No timeout in dumpstate is longer than 60 seconds,
    // so this gives lots of leeway in case of unforeseen time outs.
    struct timeval tv;
    tv.tv_sec = 10 * 60;
    tv.tv_usec = 0;
    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
        printf("WARNING: Cannot set socket timeout: %s\n", strerror(errno));
    }

    while (1) {
        char buffer[65536];
        ssize_t bytes_read = TEMP_FAILURE_RETRY(
                read(s, buffer, sizeof(buffer)));
        if (bytes_read == 0) {
            break;
        } else if (bytes_read == -1) {
            // EAGAIN really means time out, so change the errno.
            if (errno == EAGAIN) {
                errno = ETIMEDOUT;
            }
            printf("\nBugreport read terminated abnormally (%s).\n",
                    strerror(errno));
            break;
        }

        ssize_t bytes_to_send = bytes_read;
        ssize_t bytes_written;
        do {
            bytes_written = TEMP_FAILURE_RETRY(
                    write(STDOUT_FILENO, buffer + bytes_read - bytes_to_send,
                            bytes_to_send));
            if (bytes_written == -1) {
                printf(
                        "Failed to write data to stdout: read %zd, trying to send %zd (%s)\n",
                        bytes_read, bytes_to_send, strerror(errno));
                return 1;
            }
            bytes_to_send -= bytes_written;
        } while (bytes_written != 0 && bytes_to_send > 0);
    }

    close(s);
    return 0;

}
+32 −4
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ static std::set<std::string> mount_points;
void add_mountinfo();
void add_mountinfo();
static bool add_zip_entry(const std::string& entry_name, const std::string& entry_path);
static bool add_zip_entry(const std::string& entry_name, const std::string& entry_path);
static bool add_zip_entry_from_fd(const std::string& entry_name, int fd);
static bool add_zip_entry_from_fd(const std::string& entry_name, int fd);
static int control_socket_fd;


#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"


@@ -929,15 +930,17 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver


static void usage() {
static void usage() {
  fprintf(stderr,
  fprintf(stderr,
          "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] "
          "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] "
          "[-z]] [-s] [-q] [-B] [-P] [-R] [-V version]\n"
          "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n"
          "  -h: display this help message\n"
          "  -b: play sound file instead of vibrate, at beginning of job\n"
          "  -b: play sound file instead of vibrate, at beginning of job\n"
          "  -e: play sound file instead of vibrate, at end of job\n"
          "  -e: play sound file instead of vibrate, at end of job\n"
          "  -o: write to file (instead of stdout)\n"
          "  -o: write to file (instead of stdout)\n"
          "  -d: append date to filename (requires -o)\n"
          "  -d: append date to filename (requires -o)\n"
          "  -p: capture screenshot to filename.png (requires -o)\n"
          "  -p: capture screenshot to filename.png (requires -o)\n"
          "  -z: generates zipped file (requires -o)\n"
          "  -z: generate zipped file (requires -o)\n"
          "  -s: write output to control socket (for init)\n"
          "  -s: write output to control socket (for init)\n"
          "  -S: write file location to control socket (for init; requires -o and -z)"
          "  -q: disable vibrate\n"
          "  -q: disable vibrate\n"
          "  -B: send broadcast when finished (requires -o)\n"
          "  -B: send broadcast when finished (requires -o)\n"
          "  -P: send broadcast when started and update system properties on "
          "  -P: send broadcast when started and update system properties on "
@@ -1017,6 +1020,7 @@ int main(int argc, char *argv[]) {
    int do_vibrate = 1;
    int do_vibrate = 1;
    char* use_outfile = 0;
    char* use_outfile = 0;
    int use_socket = 0;
    int use_socket = 0;
    int use_control_socket = 0;
    int do_fb = 0;
    int do_fb = 0;
    int do_broadcast = 0;
    int do_broadcast = 0;
    int do_early_screenshot = 0;
    int do_early_screenshot = 0;
@@ -1053,12 +1057,13 @@ int main(int argc, char *argv[]) {
    format_args(argc, const_cast<const char **>(argv), &args);
    format_args(argc, const_cast<const char **>(argv), &args);
    MYLOGD("Dumpstate command line: %s\n", args.c_str());
    MYLOGD("Dumpstate command line: %s\n", args.c_str());
    int c;
    int c;
    while ((c = getopt(argc, argv, "dho:svqzpPBRV:")) != -1) {
    while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
        switch (c) {
        switch (c) {
            case 'd': do_add_date = 1;          break;
            case 'd': do_add_date = 1;          break;
            case 'z': do_zip_file = 1;          break;
            case 'z': do_zip_file = 1;          break;
            case 'o': use_outfile = optarg;     break;
            case 'o': use_outfile = optarg;     break;
            case 's': use_socket = 1;           break;
            case 's': use_socket = 1;           break;
            case 'S': use_control_socket = 1;   break;
            case 'v': break;  // compatibility no-op
            case 'v': break;  // compatibility no-op
            case 'q': do_vibrate = 0;           break;
            case 'q': do_vibrate = 0;           break;
            case 'p': do_fb = 1;                break;
            case 'p': do_fb = 1;                break;
@@ -1078,6 +1083,11 @@ int main(int argc, char *argv[]) {
        exit(1);
        exit(1);
    }
    }


    if (use_control_socket && !do_zip_file) {
        usage();
        exit(1);
    }

    if (do_update_progress && !do_broadcast) {
    if (do_update_progress && !do_broadcast) {
        usage();
        usage();
        exit(1);
        exit(1);
@@ -1103,6 +1113,11 @@ int main(int argc, char *argv[]) {
        redirect_to_socket(stdout, "dumpstate");
        redirect_to_socket(stdout, "dumpstate");
    }
    }


    if (use_control_socket) {
        MYLOGD("Opening control socket\n");
        control_socket_fd = open_socket("dumpstate");
    }

    /* full path of the directory where the bugreport files will be written */
    /* full path of the directory where the bugreport files will be written */
    std::string bugreport_dir;
    std::string bugreport_dir;


@@ -1342,6 +1357,14 @@ int main(int argc, char *argv[]) {
                path.clear();
                path.clear();
            }
            }
        }
        }
        if (use_control_socket) {
            if (do_text_file) {
                dprintf(control_socket_fd, "FAIL:could not create zip file, check %s "
                        "for more details\n", log_path.c_str());
            } else {
                dprintf(control_socket_fd, "OK:%s\n", path.c_str());
            }
        }
    }
    }


    /* vibrate a few but shortly times to let user know it's finished */
    /* vibrate a few but shortly times to let user know it's finished */
@@ -1389,5 +1412,10 @@ int main(int argc, char *argv[]) {
        fclose(stderr);
        fclose(stderr);
    }
    }


    if (use_control_socket && control_socket_fd >= 0) {
        MYLOGD("Closing control socket\n");
        close(control_socket_fd);
    }

    return 0;
    return 0;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -130,6 +130,9 @@ void update_progress(int weight);
/* prints all the system properties */
/* prints all the system properties */
void print_properties();
void print_properties();


/** opens a socket and returns its file descriptor */
int open_socket(const char *service);

/* redirect output to a service control socket */
/* redirect output to a service control socket */
void redirect_to_socket(FILE *redirect, const char *service);
void redirect_to_socket(FILE *redirect, const char *service);


Loading