Loading cmds/dumpstate/dumpstate.cpp +15 −4 Original line number Original line Diff line number Diff line Loading @@ -1746,7 +1746,9 @@ bool Dumpstate::FinishZipFile() { } } // TODO: Should truncate the existing file. // TODO: Should truncate the existing file. // ... and re-open it for further logging. // ... and re-open it for further logging. redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str())); if (!redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()))) { return false; } fprintf(stderr, "\n"); fprintf(stderr, "\n"); int32_t err = zip_writer_->Finish(); int32_t err = zip_writer_->Finish(); Loading Loading @@ -2366,12 +2368,17 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // If we are going to use a socket, do it as early as possible // If we are going to use a socket, do it as early as possible // to avoid timeouts from bugreport. // to avoid timeouts from bugreport. if (options_->use_socket) { if (options_->use_socket) { redirect_to_socket(stdout, "dumpstate"); if (!redirect_to_socket(stdout, "dumpstate")) { return ERROR; } } } if (options_->use_control_socket) { if (options_->use_control_socket) { MYLOGD("Opening control socket\n"); MYLOGD("Opening control socket\n"); control_socket_fd_ = open_socket("dumpstate"); control_socket_fd_ = open_socket("dumpstate"); if (control_socket_fd_ == -1) { return ERROR; } options_->do_progress_updates = 1; options_->do_progress_updates = 1; } } Loading Loading @@ -2430,7 +2437,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, if (is_redirecting) { if (is_redirecting) { // Redirect stderr to log_path_ for debugging. // Redirect stderr to log_path_ for debugging. TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr))); TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr))); redirect_to_file(stderr, const_cast<char*>(log_path_.c_str())); if (!redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()))) { return ERROR; } if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) { if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) { MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(), MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(), strerror(errno)); strerror(errno)); Loading @@ -2443,7 +2452,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, /* TODO: rather than generating a text file now and zipping it later, /* TODO: rather than generating a text file now and zipping it later, it would be more efficient to redirect stdout to the zip entry it would be more efficient to redirect stdout to the zip entry directly, but the libziparchive doesn't support that option yet. */ directly, but the libziparchive doesn't support that option yet. */ redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str())); if (!redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str()))) { return ERROR; } if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) { if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) { MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n", MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n", tmp_path_.c_str(), strerror(errno)); tmp_path_.c_str(), strerror(errno)); Loading cmds/dumpstate/dumpstate.h +18 −6 Original line number Original line Diff line number Diff line Loading @@ -519,14 +519,26 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha /** opens a socket and returns its file descriptor */ /** opens a socket and returns its file descriptor */ int open_socket(const char *service); int open_socket(const char *service); /* redirect output to a service control socket */ /* void redirect_to_socket(FILE *redirect, const char *service); * Redirects 'redirect' to a service control socket. * * Returns true if redirect succeeds. */ bool redirect_to_socket(FILE* redirect, const char* service); /* redirect output to a new file */ /* void redirect_to_file(FILE *redirect, char *path); * Redirects 'redirect' to a file indicated by 'path', truncating it. * * Returns true if redirect succeeds. */ bool redirect_to_file(FILE* redirect, char* path); /* redirect output to an existing file */ /* void redirect_to_existing_file(FILE *redirect, char *path); * Redirects 'redirect' to an existing file indicated by 'path', appending it. * * Returns true if redirect succeeds. */ bool redirect_to_existing_file(FILE* redirect, char* path); /* create leading directories, if necessary */ /* create leading directories, if necessary */ void create_parent_dirs(const char *path); void create_parent_dirs(const char *path); Loading cmds/dumpstate/utils.cpp +17 −11 Original line number Original line Diff line number Diff line Loading @@ -712,12 +712,12 @@ int open_socket(const char *service) { int s = android_get_control_socket(service); int s = android_get_control_socket(service); if (s < 0) { if (s < 0) { MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno)); MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno)); exit(1); return -1; } } fcntl(s, F_SETFD, FD_CLOEXEC); fcntl(s, F_SETFD, FD_CLOEXEC); if (listen(s, 4) < 0) { if (listen(s, 4) < 0) { MYLOGE("listen(control socket): %s\n", strerror(errno)); MYLOGE("listen(control socket): %s\n", strerror(errno)); exit(1); return -1; } } struct sockaddr addr; struct sockaddr addr; Loading @@ -725,18 +725,23 @@ int open_socket(const char *service) { int fd = accept(s, &addr, &alen); int fd = accept(s, &addr, &alen); if (fd < 0) { if (fd < 0) { MYLOGE("accept(control socket): %s\n", strerror(errno)); MYLOGE("accept(control socket): %s\n", strerror(errno)); exit(1); return -1; } } return fd; return fd; } } /* redirect output to a service control socket */ /* redirect output to a service control socket */ void redirect_to_socket(FILE *redirect, const char *service) { bool redirect_to_socket(FILE* redirect, const char* service) { int fd = open_socket(service); int fd = open_socket(service); if (fd == -1) { return false; } fflush(redirect); fflush(redirect); dup2(fd, fileno(redirect)); // TODO: handle dup2 failure TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); close(fd); close(fd); return true; } } // TODO: should call is_valid_output_file and/or be merged into it. // TODO: should call is_valid_output_file and/or be merged into it. Loading Loading @@ -766,7 +771,7 @@ void create_parent_dirs(const char *path) { } } } } void _redirect_to_file(FILE *redirect, char *path, int truncate_flag) { bool _redirect_to_file(FILE* redirect, char* path, int truncate_flag) { create_parent_dirs(path); create_parent_dirs(path); int fd = TEMP_FAILURE_RETRY(open(path, int fd = TEMP_FAILURE_RETRY(open(path, Loading @@ -774,19 +779,20 @@ void _redirect_to_file(FILE *redirect, char *path, int truncate_flag) { S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if (fd < 0) { if (fd < 0) { MYLOGE("%s: %s\n", path, strerror(errno)); MYLOGE("%s: %s\n", path, strerror(errno)); exit(1); return false; } } TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); close(fd); close(fd); return true; } } void redirect_to_file(FILE *redirect, char *path) { bool redirect_to_file(FILE* redirect, char* path) { _redirect_to_file(redirect, path, O_TRUNC); return _redirect_to_file(redirect, path, O_TRUNC); } } void redirect_to_existing_file(FILE *redirect, char *path) { bool redirect_to_existing_file(FILE* redirect, char* path) { _redirect_to_file(redirect, path, O_APPEND); return _redirect_to_file(redirect, path, O_APPEND); } } // Dump Dalvik and native stack traces, return the trace file location (nullptr if none). // Dump Dalvik and native stack traces, return the trace file location (nullptr if none). Loading Loading
cmds/dumpstate/dumpstate.cpp +15 −4 Original line number Original line Diff line number Diff line Loading @@ -1746,7 +1746,9 @@ bool Dumpstate::FinishZipFile() { } } // TODO: Should truncate the existing file. // TODO: Should truncate the existing file. // ... and re-open it for further logging. // ... and re-open it for further logging. redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str())); if (!redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()))) { return false; } fprintf(stderr, "\n"); fprintf(stderr, "\n"); int32_t err = zip_writer_->Finish(); int32_t err = zip_writer_->Finish(); Loading Loading @@ -2366,12 +2368,17 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // If we are going to use a socket, do it as early as possible // If we are going to use a socket, do it as early as possible // to avoid timeouts from bugreport. // to avoid timeouts from bugreport. if (options_->use_socket) { if (options_->use_socket) { redirect_to_socket(stdout, "dumpstate"); if (!redirect_to_socket(stdout, "dumpstate")) { return ERROR; } } } if (options_->use_control_socket) { if (options_->use_control_socket) { MYLOGD("Opening control socket\n"); MYLOGD("Opening control socket\n"); control_socket_fd_ = open_socket("dumpstate"); control_socket_fd_ = open_socket("dumpstate"); if (control_socket_fd_ == -1) { return ERROR; } options_->do_progress_updates = 1; options_->do_progress_updates = 1; } } Loading Loading @@ -2430,7 +2437,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, if (is_redirecting) { if (is_redirecting) { // Redirect stderr to log_path_ for debugging. // Redirect stderr to log_path_ for debugging. TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr))); TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr))); redirect_to_file(stderr, const_cast<char*>(log_path_.c_str())); if (!redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()))) { return ERROR; } if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) { if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) { MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(), MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(), strerror(errno)); strerror(errno)); Loading @@ -2443,7 +2452,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, /* TODO: rather than generating a text file now and zipping it later, /* TODO: rather than generating a text file now and zipping it later, it would be more efficient to redirect stdout to the zip entry it would be more efficient to redirect stdout to the zip entry directly, but the libziparchive doesn't support that option yet. */ directly, but the libziparchive doesn't support that option yet. */ redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str())); if (!redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str()))) { return ERROR; } if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) { if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) { MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n", MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n", tmp_path_.c_str(), strerror(errno)); tmp_path_.c_str(), strerror(errno)); Loading
cmds/dumpstate/dumpstate.h +18 −6 Original line number Original line Diff line number Diff line Loading @@ -519,14 +519,26 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha /** opens a socket and returns its file descriptor */ /** opens a socket and returns its file descriptor */ int open_socket(const char *service); int open_socket(const char *service); /* redirect output to a service control socket */ /* void redirect_to_socket(FILE *redirect, const char *service); * Redirects 'redirect' to a service control socket. * * Returns true if redirect succeeds. */ bool redirect_to_socket(FILE* redirect, const char* service); /* redirect output to a new file */ /* void redirect_to_file(FILE *redirect, char *path); * Redirects 'redirect' to a file indicated by 'path', truncating it. * * Returns true if redirect succeeds. */ bool redirect_to_file(FILE* redirect, char* path); /* redirect output to an existing file */ /* void redirect_to_existing_file(FILE *redirect, char *path); * Redirects 'redirect' to an existing file indicated by 'path', appending it. * * Returns true if redirect succeeds. */ bool redirect_to_existing_file(FILE* redirect, char* path); /* create leading directories, if necessary */ /* create leading directories, if necessary */ void create_parent_dirs(const char *path); void create_parent_dirs(const char *path); Loading
cmds/dumpstate/utils.cpp +17 −11 Original line number Original line Diff line number Diff line Loading @@ -712,12 +712,12 @@ int open_socket(const char *service) { int s = android_get_control_socket(service); int s = android_get_control_socket(service); if (s < 0) { if (s < 0) { MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno)); MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno)); exit(1); return -1; } } fcntl(s, F_SETFD, FD_CLOEXEC); fcntl(s, F_SETFD, FD_CLOEXEC); if (listen(s, 4) < 0) { if (listen(s, 4) < 0) { MYLOGE("listen(control socket): %s\n", strerror(errno)); MYLOGE("listen(control socket): %s\n", strerror(errno)); exit(1); return -1; } } struct sockaddr addr; struct sockaddr addr; Loading @@ -725,18 +725,23 @@ int open_socket(const char *service) { int fd = accept(s, &addr, &alen); int fd = accept(s, &addr, &alen); if (fd < 0) { if (fd < 0) { MYLOGE("accept(control socket): %s\n", strerror(errno)); MYLOGE("accept(control socket): %s\n", strerror(errno)); exit(1); return -1; } } return fd; return fd; } } /* redirect output to a service control socket */ /* redirect output to a service control socket */ void redirect_to_socket(FILE *redirect, const char *service) { bool redirect_to_socket(FILE* redirect, const char* service) { int fd = open_socket(service); int fd = open_socket(service); if (fd == -1) { return false; } fflush(redirect); fflush(redirect); dup2(fd, fileno(redirect)); // TODO: handle dup2 failure TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); close(fd); close(fd); return true; } } // TODO: should call is_valid_output_file and/or be merged into it. // TODO: should call is_valid_output_file and/or be merged into it. Loading Loading @@ -766,7 +771,7 @@ void create_parent_dirs(const char *path) { } } } } void _redirect_to_file(FILE *redirect, char *path, int truncate_flag) { bool _redirect_to_file(FILE* redirect, char* path, int truncate_flag) { create_parent_dirs(path); create_parent_dirs(path); int fd = TEMP_FAILURE_RETRY(open(path, int fd = TEMP_FAILURE_RETRY(open(path, Loading @@ -774,19 +779,20 @@ void _redirect_to_file(FILE *redirect, char *path, int truncate_flag) { S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if (fd < 0) { if (fd < 0) { MYLOGE("%s: %s\n", path, strerror(errno)); MYLOGE("%s: %s\n", path, strerror(errno)); exit(1); return false; } } TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect))); close(fd); close(fd); return true; } } void redirect_to_file(FILE *redirect, char *path) { bool redirect_to_file(FILE* redirect, char* path) { _redirect_to_file(redirect, path, O_TRUNC); return _redirect_to_file(redirect, path, O_TRUNC); } } void redirect_to_existing_file(FILE *redirect, char *path) { bool redirect_to_existing_file(FILE* redirect, char* path) { _redirect_to_file(redirect, path, O_APPEND); return _redirect_to_file(redirect, path, O_APPEND); } } // Dump Dalvik and native stack traces, return the trace file location (nullptr if none). // Dump Dalvik and native stack traces, return the trace file location (nullptr if none). Loading