static void subproc_waiter_service(int fd, void *cookie) { pid_t pid = (pid_t)cookie; D("entered. fd=%d of pid=%d\n", fd, pid); for (;;) { int status; pid_t p = waitpid(-1/*pid*/, &status, 0); D("fd=%d, post waitpid(pid=%d) status=%04x %s errno(%d)\n", fd, p, status, strerror(errno), errno); //if (p == pid) { if (WIFSIGNALED(status)) { D("*** Killed by signal %d\n", WTERMSIG(status)); //break; } else if (!WIFEXITED(status)) { D("*** Didn't exit!!. status %d\n", status); //break; } else if (WEXITSTATUS(status) >= 0) { D("*** Exit code %d\n", WEXITSTATUS(status)); //break; } //} if ( p == -1 ) usleep(100000); // poll every 0.1 sec } D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); XLOGV("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); if (SHELL_EXIT_NOTIFY_FD >=0) { int res; res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", SHELL_EXIT_NOTIFY_FD, pid, res, errno); } }
static int create_subproc_thread(const char *name) { adb_thread_t t; int ret_fd; pid_t pid; long mem_free = 0; read_meminfo(&mem_free); D("read_meminfo() mem_free=%d\n", mem_free); XLOGV("read_meminfo() mem_free=%d\n", mem_free); if(name) { ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid); } else { ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid); } D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid); XLOGV("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid); if ( sti == 0 ) { sti = malloc(sizeof(stinfo)); if(sti == 0) fatal("cannot allocate stinfo"); sti->func = subproc_waiter_service; sti->cookie = (void*)pid; sti->fd = ret_fd; int nRet = adb_thread_create( &t, service_bootstrap_func, sti); if(nRet) { D("adb_thread_create() nRet=%d errno=%d\n", nRet, errno); XLOGW("adb_thread_create() nRet=%d errno=%d\n", nRet, errno); free(sti); sti = 0; adb_close(ret_fd); printf("cannot create service thread\n"); return -1; } } D("service thread started, fd=%d pid=%d\n",ret_fd, pid); return ret_fd; }
static void mpodecoder_close(JNIEnv* env, jobject mpodecoder) { if (NULL == mpoDecoder_nativeInstanceID) return; if (NULL == env || NULL == mpodecoder) return; if (! env->IsInstanceOf(mpodecoder, mpoDecoder_class)) return; MpoDecoder* mpoDecoder = (MpoDecoder*)env->GetIntField(mpodecoder, mpoDecoder_nativeInstanceID); XLOGV("MpoDecoder:mpodecoder_close()"); delete mpoDecoder; env->SetIntField(mpodecoder,mpoDecoder_nativeInstanceID,0); }
void SFWatchDog::unmarkStartTransactionTime(uint32_t index) { Mutex::Autolock _l(mLock); if (index >= mNodeList.size()) { XLOGE("[unmarkStartTransactionTime] index=%d > Node list size=%d", index, mNodeList.size()); return; } mNodeList[index]->mStartTransactionTime = 0; if (mShowLog) XLOGV("[%s] name=%s, index=%d, time = %" PRId64 "", __func__, mNodeList[index]->mName.string(), index, mNodeList[index]->mStartTransactionTime); }
int service_to_fd(const char *name) { int ret = -1; #if !ADB_HOST XLOGV("service_to_fd() name=%s\n", name); #endif if(!strncmp(name, "tcp:", 4)) { int port = atoi(name + 4); name = strchr(name + 4, ':'); if(name == 0) { ret = socket_loopback_client(port, SOCK_STREAM); if (ret >= 0) disable_tcp_nagle(ret); } else { #if ADB_HOST adb_mutex_lock(&dns_lock); ret = socket_network_client(name + 1, port, SOCK_STREAM); adb_mutex_unlock(&dns_lock); #else return -1; #endif } #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ } else if(!strncmp(name, "local:", 6)) { ret = socket_local_client(name + 6, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localreserved:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localabstract:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if(!strncmp(name, "localfilesystem:", 16)) { ret = socket_local_client(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); #endif #if ADB_HOST } else if(!strncmp("dns:", name, 4)){ char *n = strdup(name + 4); if(n == 0) return -1; ret = create_service_thread(dns_service, n); #else /* !ADB_HOST */ } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if(recovery_mode && !strncmp(name, "recover:", 8)) { ret = create_service_thread(recover_service, (void*) atoi(name + 8)); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if (!strncmp(name, "log:", 4)) { ret = create_service_thread(log_service, get_log_file_path(name + 4)); } else if(!HOST && !strncmp(name, "shell:", 6)) { if(name[6]) { ret = create_subproc_thread(name + 6); } else { ret = create_subproc_thread(0); } } else if(!strncmp(name, "sync:", 5)) { ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if(arg == 0) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { ret = create_service_thread(restart_root_service, NULL); } else if(!strncmp(name, "backup:", 7)) { char* arg = strdup(name+7); if (arg == NULL) return -1; ret = backup_service(BACKUP, arg); } else if(!strncmp(name, "restore:", 8)) { ret = backup_service(RESTORE, NULL); } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) == 0) { port = 0; } ret = create_service_thread(restart_tcp_service, (void *)port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); #endif #if 0 } else if(!strncmp(name, "echo:", 5)){ ret = create_service_thread(echo_service, 0); #endif } if (ret >= 0) { close_on_exec(ret); } return ret; }
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { #ifdef HAVE_WIN32_PROC D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ char *devname; int ptm; ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } fcntl(ptm, F_SETFD, FD_CLOEXEC); if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)){ printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); XLOGV("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); adb_close(ptm); return -1; } if(*pid == 0){ int pts; setsid(); pts = unix_open(devname, O_RDWR); if(pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); XLOGV("child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, 0); dup2(pts, 1); dup2(pts, 2); adb_close(pts); adb_close(ptm); // set OOM adjustment to zero char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to open %s\n", text); XLOGW("adb: unable to open %s\n", text); } timer_t timerid; struct sigevent sev; /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { D("adb: Call timer_create failed!\n"); XLOGV("adb: Call timer_create failed!\n"); exit(-1); } struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 3; its.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &its, NULL) == -1) { D("adb: Call timer_settime failed!\n"); XLOGV("adb: Call timer_settime failed!\n"); exit(-1); } sigset_t mask; struct sigaction sa; /* Establish handler for timer signal */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = catcher; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { D("adb: Call sigaction failed!\n"); XLOGV("adb: Call sigaction failed!\n"); exit(-1); } int nRet = execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); XLOGV("- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); exit(-1); } else { // Don't set child's OOM adjustment to zero. // Let the child do it itself, as sometimes the parent starts // running before the child has a /proc/pid/oom_adj. // """adb: unable to open /proc/644/oom_adj""" seen in some logs. return ptm; } #endif /* !HAVE_WIN32_PROC */ }
void catcher() { D("Enter catcher : wait too long in create_subprocess\n"); XLOGV("Enter catcher : wait too long in create_subprocess\n"); exit(-1); }
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); #ifdef HAVE_WIN32_PROC fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ int ptm; ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } char devname[64]; if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) { printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); XLOGW("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { init_subproc_child(); int pts = unix_open(devname, O_RDWR | O_CLOEXEC); if (pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); adb_close(pts); adb_close(ptm); timer_t timerid; struct sigevent sev; /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { D("adb: Call timer_create failed!\n"); XLOGV("adb: Call timer_create failed!\n"); exit(-1); } struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 3; its.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &its, NULL) == -1) { D("adb: Call timer_settime failed!\n"); XLOGV("adb: Call timer_settime failed!\n"); exit(-1); } sigset_t mask; struct sigaction sa; /* Establish handler for timer signal */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = catcher; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { D("adb: Call sigaction failed!\n"); XLOGV("adb: Call sigaction failed!\n"); exit(-1); } int nRet = execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); XLOGV("- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); exit(-1); } else { return ptm; } #endif /* !HAVE_WIN32_PROC */ }
// dump current using buffer in Layer void Layer::dumpActiveBuffer() const { XLOGV("[dumpActiveBuffer] + id=%p", this); if (mActiveBuffer != NULL) { char value[PROPERTY_VALUE_MAX]; bool raw; const void* identity; property_get("debug.sf.layerdump.raw", value, "0"); raw = (0 != atoi(value)); identity = this; char fname[128]; void* ptr; float bpp; SkBitmap b; SkBitmap::Config c; int inputFormat = mActiveBuffer->format; int dumpHeight = mActiveBuffer->height; #ifndef EMULATOR_SUPPORT // check private format if (inputFormat == HAL_PIXEL_FORMAT_YUV_PRIVATE) { gralloc_buffer_info_t buffInfo; GraphicBufferExtra::get().getBufInfo(mActiveBuffer->handle, &buffInfo); int fillFormat = (buffInfo.status & GRALLOC_EXTRA_MASK_CM); switch (fillFormat) { case GRALLOC_EXTRA_BIT_CM_YV12: inputFormat = HAL_PIXEL_FORMAT_YV12; break; case GRALLOC_EXTRA_BIT_CM_NV12_BLK: inputFormat = HAL_PIXEL_FORMAT_NV12_BLK; dumpHeight = ALIGN_CEIL(mActiveBuffer->height, 32); break; case GRALLOC_EXTRA_BIT_CM_NV12_BLK_FCM: inputFormat = HAL_PIXEL_FORMAT_NV12_BLK_FCM; dumpHeight = ALIGN_CEIL(mActiveBuffer->height, 32); break; default: XLOGD("unexpected format for dumpping clear motion: 0x%x", fillFormat); return; } } #endif bpp = 1.0f; c = SkBitmap::kNo_Config; switch (inputFormat) { case PIXEL_FORMAT_RGBA_8888: case PIXEL_FORMAT_RGBX_8888: if (false == raw) { c = SkBitmap::kARGB_8888_Config; sprintf(fname, "/data/SF_dump/%p.png", identity); } else { bpp = 4.0; sprintf(fname, "/data/SF_dump/%p.RGBA", identity); } break; case PIXEL_FORMAT_BGRA_8888: case 0x1ff: // tricky format for SGX_COLOR_FORMAT_BGRX_8888 in fact if (false == raw) { c = SkBitmap::kARGB_8888_Config; sprintf(fname, "/data/SF_dump/%p(RBswapped).png", identity); } else { bpp = 4.0; sprintf(fname, "/data/SF_dump/%p.BGRA", identity); } break; case PIXEL_FORMAT_RGB_565: if (false == raw) { c = SkBitmap::kRGB_565_Config; sprintf(fname, "/data/SF_dump/%p.png", identity); } else { bpp = 2.0; sprintf(fname, "/data/SF_dump/%p.RGB565", identity); } break; case HAL_PIXEL_FORMAT_I420: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.i420", identity); break; case HAL_PIXEL_FORMAT_NV12_BLK: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.nv12_blk", identity); break; case HAL_PIXEL_FORMAT_NV12_BLK_FCM: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.nv12_blk_fcm", identity); break; case HAL_PIXEL_FORMAT_YV12: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.yv12", identity); break; default: XLOGE("[%s] cannot dump format:%p for identity:%d", __func__, mActiveBuffer->format, identity); return; } { //Mutex::Autolock _l(mDumpLock); mActiveBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &ptr); { XLOGI("[%s] %s", __func__, getName().string()); XLOGI(" %s (config:%d, stride:%d, height:%d, ptr:%p)", fname, c, mActiveBuffer->stride, dumpHeight, ptr); if (SkBitmap::kNo_Config != c) { b.setConfig(c, mActiveBuffer->stride, dumpHeight); b.setPixels(ptr); SkImageEncoder::EncodeFile(fname, b, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality); } else { uint32_t size = mActiveBuffer->stride * dumpHeight * bpp; // correction for YV12 case, pending for VU planes should also pending to 16 if (HAL_PIXEL_FORMAT_YV12 == inputFormat) { uint32_t u_remainder = (mActiveBuffer->stride / 2) % 16; if (0 != u_remainder) { size += (16 - u_remainder) * dumpHeight; } } FILE *f = fopen(fname, "wb"); fwrite(ptr, size, 1, f); fclose(f); } } mActiveBuffer->unlock(); } } XLOGV("[dumpActiveBuffer] - id=%p", this); }
bool SFWatchDog::threadLoop() { XLOGV("[%s]", __func__); { Mutex::Autolock _l(mScreenLock); } nsecs_t stopTime = 1; if (isSFThreadHang(&stopTime)) { char cmds[256]; static uint32_t rtt_ct = SW_WATCHDOG_RTTCOUNT; if (rtt_ct > 0) { rtt_ct --; } else { XLOGD("[SF-WD] swap rtt dump file"); // swap rtt dump file snprintf(cmds, sizeof(cmds), "mv %s.txt %s_1.txt", RTT_DUMP, RTT_DUMP); system(cmds); rtt_ct = SW_WATCHDOG_RTTCOUNT; } // append SurfaceFlinger rtt information to rtt file char filename[100]; snprintf(filename, sizeof(filename), "%s.txt", RTT_DUMP); int fd = open(filename, O_CREAT | O_WRONLY | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ if (fd < 0) { ALOGE("Can't open %s: %s\n", filename, strerror(errno)); return true; } if (lseek(fd, 0, SEEK_END) < 0) { fprintf(stderr, "lseek: %s\n", strerror(errno)); } else { dump_backtrace_to_file(getpid(), fd); } close(fd); XLOGD("[SF-WD] dump rtt file: %s.txt", RTT_DUMP); XLOGW("[SF-WD] ============================================"); } else { stopTime = 1; } getProperty(); char value[PROPERTY_VALUE_MAX]; snprintf(value, sizeof(value), "%" PRId64 " ", stopTime); if (stopTime < 0 || stopTime >= 2147483247) { volatile nsecs_t tmpStopTime = stopTime; XLOGD("[SF-WD] tmpStopTime=(%" PRId64 ", %" PRId64 ")", tmpStopTime, stopTime); abort(); } uint32_t ret = property_set("service.sf.status", value); if (mUpdateCount) { if (mShowLog) XLOGV("[SF-WD] mUpdateCount: %d", mUpdateCount); #if 0 aee_ioctl_wdt_kick(WDT_SETBY_SF); #endif mUpdateCount = 0; } //else { // XLOGV("[SF-WD] mUpdateCount not update!!!!!: %d", mUpdateCount); // aee_ioctl_wdt_kick(WDT_SETBY_SF_NEED_NOT_UPDATE); //} usleep(mTimer * 1000); return true; }