From fdf4e4f1859771b95585cbc87f8cd038ea2815c6 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Fri, 18 Jan 2013 15:31:41 -0800 Subject: Add media.log service based on NBLog Change-Id: Ie45093df6ac9a739d05c8d408fab52a9a8a27e7f --- media/mediaserver/Android.mk | 5 ++ media/mediaserver/main_mediaserver.cpp | 105 ++++++++++++++++++++++++++++++--- 2 files changed, 101 insertions(+), 9 deletions(-) (limited to 'media/mediaserver') diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk index 8c3cc5e..0a0f4db 100644 --- a/media/mediaserver/Android.mk +++ b/media/mediaserver/Android.mk @@ -7,12 +7,17 @@ LOCAL_SRC_FILES:= \ LOCAL_SHARED_LIBRARIES := \ libaudioflinger \ libcameraservice \ + libmedialogservice \ + libcutils \ + libnbaio \ + libmedia \ libmediaplayerservice \ libutils \ libbinder LOCAL_C_INCLUDES := \ frameworks/av/media/libmediaplayerservice \ + frameworks/av/services/medialog \ frameworks/av/services/audioflinger \ frameworks/av/services/camera/libcameraservice diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp index ddd5b84..0862952 100644 --- a/media/mediaserver/main_mediaserver.cpp +++ b/media/mediaserver/main_mediaserver.cpp @@ -18,14 +18,19 @@ #define LOG_TAG "mediaserver" //#define LOG_NDEBUG 0 +#include +#include +#include #include #include #include +#include #include // from LOCAL_C_INCLUDES #include "AudioFlinger.h" #include "CameraService.h" +#include "MediaLogService.h" #include "MediaPlayerService.h" #include "AudioPolicyService.h" @@ -34,13 +39,95 @@ using namespace android; int main(int argc, char** argv) { signal(SIGPIPE, SIG_IGN); - sp proc(ProcessState::self()); - sp sm = defaultServiceManager(); - ALOGI("ServiceManager: %p", sm.get()); - AudioFlinger::instantiate(); - MediaPlayerService::instantiate(); - CameraService::instantiate(); - AudioPolicyService::instantiate(); - ProcessState::self()->startThreadPool(); - IPCThreadState::self()->joinThreadPool(); + char value[PROPERTY_VALUE_MAX]; + bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1); + pid_t childPid; + // FIXME The advantage of making the process containing media.log service the parent process of + // the process that contains all the other real services, is that it allows us to collect more + // detailed information such as signal numbers, stop and continue, resource usage, etc. + // But it is also more complex. Consider replacing this by independent processes, and using + // binder on death notification instead. + if (doLog && (childPid = fork()) != 0) { + // media.log service + //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0); + // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack + strcpy(argv[0], "media.log"); + sp proc(ProcessState::self()); + MediaLogService::instantiate(); + ProcessState::self()->startThreadPool(); + for (;;) { + siginfo_t info; + int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED); + if (ret == EINTR) { + continue; + } + if (ret < 0) { + break; + } + char buffer[32]; + const char *code; + switch (info.si_code) { + case CLD_EXITED: + code = "CLD_EXITED"; + break; + case CLD_KILLED: + code = "CLD_KILLED"; + break; + case CLD_DUMPED: + code = "CLD_DUMPED"; + break; + case CLD_STOPPED: + code = "CLD_STOPPED"; + break; + case CLD_TRAPPED: + code = "CLD_TRAPPED"; + break; + case CLD_CONTINUED: + code = "CLD_CONTINUED"; + break; + default: + snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code); + code = buffer; + break; + } + struct rusage usage; + getrusage(RUSAGE_CHILDREN, &usage); + ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds", + info.si_pid, info.si_status, code, + usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000, + usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000); + sp sm = defaultServiceManager(); + sp binder = sm->getService(String16("media.log")); + if (binder != 0) { + Vector args; + binder->dump(-1, args); + } + switch (info.si_code) { + case CLD_EXITED: + case CLD_KILLED: + case CLD_DUMPED: { + ALOG(LOG_INFO, "media.log", "exiting"); + _exit(0); + // not reached + } + default: + break; + } + } + } else { + // all other services + if (doLog) { + prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also + setpgid(0, 0); // but if I die first, don't kill my parent + } + sp proc(ProcessState::self()); + sp sm = defaultServiceManager(); + ALOGI("ServiceManager: %p", sm.get()); + AudioFlinger::instantiate(); + MediaPlayerService::instantiate(); + CameraService::instantiate(); + AudioPolicyService::instantiate(); + ProcessState::self()->startThreadPool(); + IPCThreadState::self()->joinThreadPool(); + } } -- cgit v1.1