X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fos_posix.cpp;h=5d6bffe5dcdab406a23624692b965e1d0730305b;hb=2a5696befce6be00fa655b751af5ce2924ea45ae;hp=3eebbd862d4a78448b062a11ba10ce1232d8fcb8;hpb=43ac1bff7374a572d3bb0a8341ab3d167e3ac07d;p=apitrace diff --git a/common/os_posix.cpp b/common/os_posix.cpp index 3eebbd8..5d6bffe 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -23,6 +23,7 @@ * **************************************************************************/ +#ifndef _WIN32 #include #include @@ -44,6 +45,10 @@ #include #endif +#ifdef ANDROID +#include +#endif + #ifndef PATH_MAX #warning PATH_MAX undefined #define PATH_MAX 4096 @@ -51,6 +56,7 @@ #include "os.hpp" #include "os_string.hpp" +#include "os_backtrace.hpp" namespace os { @@ -67,25 +73,33 @@ getProcessName(void) #ifdef __APPLE__ uint32_t len = size; if (_NSGetExecutablePath(buf, &len) != 0) { - *buf = 0; - return path; + // grow buf and retry + buf = path.buf(len); + _NSGetExecutablePath(buf, &len); } len = strlen(buf); #else ssize_t len; len = readlink("/proc/self/exe", buf, size - 1); - if (len == -1) { + if (len <= 0) { // /proc/self/exe is not available on setuid processes, so fallback to // /proc/self/cmdline. int fd = open("/proc/self/cmdline", O_RDONLY); if (fd >= 0) { - len = read(fd, buf, size - 1); + // buf already includes trailing zero + len = read(fd, buf, size); close(fd); + if (len >= 0) { + len = strlen(buf); + } } } if (len <= 0) { - snprintf(buf, size, "%i", (int)getpid()); - return path; + // fallback to process ID + len = snprintf(buf, size, "%i", (int)getpid()); + if (len >= size) { + len = size - 1; + } } #endif path.truncate(len); @@ -107,6 +121,12 @@ getCurrentDir(void) return path; } +bool +createDirectory(const String &path) +{ + return mkdir(path, 0777) == 0; +} + bool String::exists(void) const { @@ -118,9 +138,6 @@ String::exists(void) const return false; } - if (!S_ISREG(st.st_mode)) - return false; - return true; } @@ -130,7 +147,11 @@ int execute(char * const * args) if (pid == 0) { // child execvp(args[0], args); - fprintf(stderr, "error: failed to execute %s\n", args[0]); + fprintf(stderr, "error: failed to execute:"); + for (unsigned i = 0; args[i]; ++i) { + fprintf(stderr, " %s", args[i]); + } + fprintf(stderr, "\n"); exit(-1); } else { // parent @@ -139,8 +160,17 @@ int execute(char * const * args) return -1; } int status = -1; + int ret; waitpid(pid, &status, 0); - return status; + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + // match shell return code + ret = WTERMSIG(status) + 128; + } else { + ret = 128; + } + return ret; } } @@ -153,7 +183,20 @@ log(const char *format, ...) va_list ap; va_start(ap, format); fflush(stdout); - vfprintf(stderr, format, ap); +#ifdef ANDROID + __android_log_vprint(ANDROID_LOG_DEBUG, "apitrace", format, ap); +#else + static FILE *log = NULL; + if (!log) { + // Duplicate stderr file descriptor, to prevent applications from + // redirecting our debug messages to somewhere else. + // + // Another alternative would be to log to /dev/tty when available. + log = fdopen(dup(STDERR_FILENO), "at"); + } + vfprintf(log, format, ap); + fflush(log); +#endif va_end(ap); logging = false; } @@ -165,7 +208,7 @@ long long timeFrequency = 0LL; void abort(void) { - exit(0); + _exit(1); } @@ -201,11 +244,11 @@ signalHandler(int sig, siginfo_t *info, void *context) if (recursion_count) { log("apitrace: warning: recursion handling signal %i\n", sig); } else { - if (gCallback) { - ++recursion_count; + ++recursion_count; + if (gCallback) gCallback(); - --recursion_count; - } + os::dump_backtrace(); + --recursion_count; } struct sigaction *old_action; @@ -290,3 +333,4 @@ resetExceptionCallback(void) } /* namespace os */ +#endif // !defined(_WIN32)