static void term_sockdev ( void* arg ) { UNREFERENCED( arg ); if (!init_done) init_sockdev(); SIGNAL_SOCKDEV_THREAD(); join_thread ( sysblk.socktid, NULL ); detach_thread ( sysblk.socktid ); }
int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids) { #if !defined (NO_LIBUNWIND_PTRACE) int i, count, rc = 0; int *threads = NULL; count = get_threads(pid, &threads); if (!count || threads == NULL) return -1; if (tids != NULL) { if (adjust_threads(threads, count, tids, index, nr_tids) < 0) return -1; free(threads); count = nr_tids; threads = tids; } if (attach_process(pid) < 0) return -1; for (i = 0; i < count; ++i) { void *upt_info; printf("-------------------- thread %d (%d) --------------------\n", (index != NULL ? index[i] : i+1), threads[i]); if (threads[i] != pid && attach_thread(threads[i]) < 0) { rc = -1; break; } upt_info = _UPT_create(threads[i]); if (backtrace_thread(&_UPT_accessors, upt_info) < 0) rc = -1; _UPT_destroy(upt_info); if (threads[i] != pid && detach_thread(threads[i])) rc = -1; if (rc < 0) break; } free(threads); if (detach_process(pid) < 0) return -1; return rc; #else return -1; #endif /* NO_LIBUNWIND_PTRACE */ }
static void check_event (ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); struct gdbarch *gdbarch = get_regcache_arch (regcache); td_event_msg_t msg; td_thrinfo_t ti; td_err_e err; CORE_ADDR stop_pc; int loop = 0; /* Bail out early if we're not at a thread event breakpoint. */ stop_pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch); if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr) return; loop = 1; do { err = td_ta_event_getmsg_p (thread_agent, &msg); if (err != TD_OK) { if (err == TD_NOMSG) return; error ("Cannot get thread event message: %s", thread_db_err_str (err)); } err = td_thr_get_info_p ((void *)(uintptr_t)msg.th_p, &ti); if (err != TD_OK) error ("Cannot get thread info: %s", thread_db_err_str (err)); ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); switch (msg.event) { case TD_CREATE: /* We may already know about this thread, for instance when the user has issued the `info threads' command before the SIGTRAP for hitting the thread creation breakpoint was reported. */ attach_thread (ptid, (void *)(uintptr_t)msg.th_p, &ti, 1); break; case TD_DEATH: if (!in_thread_list (ptid)) error ("Spurious thread death event."); detach_thread (ptid, 1); break; default: error ("Spurious thread event."); } } while (loop); }
/** * Handle activity recognition events from HAL. */ static void activity_callback( const activity_recognition_callback_procs_t* procs, const activity_event_t* events, int count) { if (sOnActivityChanged == NULL) { ALOGE("Dropping activity_callback because onActivityChanged handler is null."); return; } if (events == NULL || count <= 0) { ALOGE("Invalid activity_callback. Count: %d, Events: %p", count, events); return; } JNIEnv* env = NULL; int result = attach_thread(&env); if (result != JNI_OK) { ALOGE("Unable to attach thread with JNI."); return; } jclass event_class = env->FindClass("android/hardware/location/ActivityRecognitionHardware$Event"); jmethodID event_ctor = env->GetMethodID(event_class, "<init>", "()V"); jfieldID activity_field = env->GetFieldID(event_class, "activity", "I"); jfieldID type_field = env->GetFieldID(event_class, "type", "I"); jfieldID timestamp_field = env->GetFieldID(event_class, "timestamp", "J"); jobjectArray events_array = env->NewObjectArray(count, event_class, NULL); for (int i = 0; i < count; ++i) { const activity_event_t* event = &events[i]; jobject event_object = env->NewObject(event_class, event_ctor); env->SetIntField(event_object, activity_field, event->activity); env->SetIntField(event_object, type_field, event->event_type); env->SetLongField(event_object, timestamp_field, event->timestamp); env->SetObjectArrayElement(events_array, i, event_object); env->DeleteLocalRef(event_object); } env->CallVoidMethod(sCallbacksObject, sOnActivityChanged, events_array); check_and_clear_exceptions(env, __FUNCTION__); // TODO: ideally we'd let the HAL register the callback thread only once detach_thread(); }
int CTCI_Close( DEVBLK* pDEVBLK ) { /* DEVBLK* pDEVBLK2; */ PCTCBLK pCTCBLK = (PCTCBLK)pDEVBLK->dev_data; // Close the device file (if not already closed) if( pCTCBLK->fd >= 0 ) { // PROGRAMMING NOTE: there's currently no way to interrupt // the "CTCI_ReadThread"s TUNTAP_Read of the adapter. Thus // we must simply wait for CTCI_ReadThread to eventually // notice that we're doing a close (via our setting of the // fCloseInProgress flag). Its TUNTAP_Read will eventually // timeout after a few seconds (currently 5, which is dif- // ferent than the CTC_READ_TIMEOUT_SECS timeout value the // CTCI_Read function uses) and will then do the close of // the adapter for us (TUNTAP_Close) so we don't have to. // All we need to do is ask it to exit (via our setting of // the fCloseInProgress flag) and then wait for it to exit // (which, as stated, could take up to a max of 5 seconds). // All of this is simply because it's poor form to close a // device from one thread while another thread is reading // from it. Attempting to do so could trip a race condition // wherein the internal i/o buffers used to process the // read request could have been freed (by the close call) // by the time the read request eventually gets serviced. TID tid = pCTCBLK->tid; pCTCBLK->fCloseInProgress = 1; // (ask read thread to exit) signal_thread( tid, SIGUSR2 ); // (for non-Win32 platforms) //FIXME signal_thread not working for non-MSVC platforms #if defined(_MSVC_) join_thread( tid, NULL ); // (wait for thread to end) #endif detach_thread( tid ); // (wait for thread to end) } pDEVBLK->fd = -1; // indicate we're now closed return 0; }
/*********************************************************************** * DllMain (URLMON.init) */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); URLMON_DllMain( hinstDLL, fdwReason, fImpLoad ); switch(fdwReason) { case DLL_PROCESS_ATTACH: init_session(TRUE); break; case DLL_PROCESS_DETACH: process_detach(); break; case DLL_THREAD_DETACH: detach_thread(); break; } return TRUE; }
/*********************************************************************** * DllMain (URLMON.init) */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); URLMON_DllMain( hinstDLL, fdwReason, fImpLoad ); switch(fdwReason) { case DLL_PROCESS_ATTACH: urlmon_instance = hinstDLL; init_session(); break; case DLL_PROCESS_DETACH: if (fImpLoad) break; process_detach(); DeleteCriticalSection(&tls_cs); break; case DLL_THREAD_DETACH: detach_thread(); break; } return TRUE; }
static void logger_term(void *arg) { char *lmsbuf = NULL; /* xxx */ int lmsnum = -1; /* xxx */ int lmscnt = -1; /* xxx */ char* term_msg = MSG(HHC02103, "I"); UNREFERENCED(arg); log_wakeup(NULL); usleep(1000); /* Flush all pending logger o/p before redirecting?? */ fflush(stdout); if(logger_active) { /* Redirect all output to stderr */ dup2(STDERR_FILENO, STDOUT_FILENO); /* Tell logger thread we want it to exit */ logger_active = 0; log_wakeup(NULL); usleep(1000); if ( logger_tid != 0 && !sysblk.shutdown ) { sleep(2); /* Logger is now terminating */ obtain_lock(&logger_lock); /* Wait for the logger to terminate */ join_thread( logger_tid, NULL ); detach_thread( logger_tid ); release_lock(&logger_lock); } if ( fwrite("\n",1,1,stderr) ) { perror(QLINE "fwrite failure/HHC02102 "); } /* Read and display any msgs still remaining in the system log */ lmsnum = log_line(-1); while((lmscnt = log_read(&lmsbuf, &lmsnum, LOG_BLOCK))) { char *p = NULL; char *strtok_str = NULL; lmsbuf[lmscnt-1] = '\0'; p = strtok_r( lmsbuf, "\n", &strtok_str ); while ( (p = strtok_r(NULL, "\n", &strtok_str ) ) != NULL ) { char* pLeft = p; int nLeft = (int)strlen(p); #if defined( OPTION_MSGCLR ) /* Remove "<pnl,..." color string if it exists */ if (1 && nLeft > 5 && strncasecmp( pLeft, "<pnl", 4 ) == 0 && (pLeft = memchr( pLeft+4, '>', nLeft-4 )) != NULL ) { pLeft++; nLeft -= (int)(pLeft - p); } #endif // defined( OPTION_MSGCLR ) if (nLeft) { if ( fwrite(pLeft,nLeft,1,stderr) ) { perror(QLINE "fwrite failure/HHC02102 "); } if ( fwrite("\n",1,1,stderr) ) { perror(QLINE "fwrite failure/HHC02102 "); } } } } if ( fwrite( term_msg, strlen(term_msg), 1, stderr ) ) { perror(QLINE "fwrite failure/HHC02102 "); } fflush(stderr); } }
/* * save process' memory maps, stack contents, thread identifiers and registers */ struct snapshot *get_snapshot(int pid, int *tids, int *index, int nr_tids) { struct snapshot *res; int attached_tid = 0; int i, n_frames; long page, label, rc; struct mem_data_chunk **stacks_cover = NULL; if ((page = sysconf(_SC_PAGESIZE)) < 0) { perror("get pagesize"); return NULL; } --page; res = calloc(1, sizeof(struct snapshot)); /* * create memory_map structure corresponding to process' maps */ res->map = create_maps(pid); if (res->map == NULL) goto get_snapshot_fail; /* * get process' threads */ res->num_threads = get_threads(pid, &res->tids); if (res->num_threads < 0 || res->tids == NULL) goto get_snapshot_fail; /* * user-provided list of threads */ if (tids != NULL) { if (adjust_threads(res->tids, res->num_threads, tids, index, nr_tids) < 0) goto get_snapshot_fail; free(res->tids); res->num_threads = nr_tids; res->tids = tids; } res->cur_thr = 0; res->regs = malloc(sizeof(res->regs[0])*res->num_threads); if (res->regs == NULL) { perror("malloc"); goto get_snapshot_fail; } /* FREEZE PROCESS */ if (attach_process(pid) < 0) goto get_snapshot_fail; for (i = 0; i < res->num_threads; ++i) { struct iovec iov; /* * we have already attached to main thread. call attach_thread() * for other ones */ attached_tid = res->tids[i]; if (res->tids[i] != pid && attach_thread(res->tids[i]) < 0) goto get_snapshot_fail_attached; /* * save thread's registers */ iov.iov_len = sizeof(res->regs[0]); iov.iov_base = &res->regs[i]; rc = ptrace(PTRACE_GETREGSET, res->tids[i], NT_PRSTATUS, &iov); if (rc < 0) { perror("PTRACE_GETREGSET"); goto get_snapshot_fail_attached; } /* * save label on memory region. it will indicate that memory contents * upper than this point (%rsp) will needed to unwind stacks */ label = SP_REG(&res->regs[i]) & ~page; rc = mem_map_add_label(res->map, (void *)label, res->num_threads); if (rc < 0) { fprintf(stderr, "failed to add label 0x%lx [rsp 0x%llx thread %d]\n", label, (long long unsigned int)SP_REG(&res->regs[i]), res->tids[i]); goto get_snapshot_fail_attached; } /* * detach from thread. it will still be frozen due to SIGSTOP */ if (res->tids[i] != pid && detach_thread(res->tids[i]) < 0) goto get_snapshot_fail_attached; } /* * arrange data chunks to copy memory contents. in most cases the chunks * will start from %rsp pointing somewhere in thread's stack * to the end of the stack region */ stacks_cover = malloc(sizeof(struct mem_data_chunk*) * res->num_threads); n_frames = mem_map_build_label_cover(res->map, stack_size, stacks_cover, page + 1); if (stacks_cover == NULL) { fprintf(stderr, "error: stacks cover == NULL, n_frames=%d\n", n_frames); goto get_snapshot_fail_attached; } /* * copy memory contents */ rc = copy_memory(pid, stacks_cover, n_frames); if (rc < 0) goto get_snapshot_fail_attached; /* UNFREEZE PROCESS */ if (detach_process(pid) < 0) goto get_snapshot_fail; if (opt_verbose) { for (i = 0; i < n_frames; ++i) { struct mem_data_chunk *chunk = stacks_cover[i]; printf("chunk #%d: 0x%lx-0x%lx length: %ldK\n", i, (size_t)chunk->start, (size_t)chunk->start + chunk->length, chunk->length >> 10); } } free(stacks_cover); return res; get_snapshot_fail_attached: if (attached_tid) detach_thread(attached_tid); detach_process(pid); get_snapshot_fail: if (opt_verbose) { fprintf(stderr, "maps of %d:\n", pid); print_proc_maps(pid); } free(stacks_cover); snapshot_destroy(res); return NULL; }
int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids) { #if !defined (NO_LIBUNWIND_PTRACE) int i, count, rc = 0; int *threads = NULL; count = get_threads(pid, &threads); if (!count || threads == NULL) return -1; if (tids != NULL) { if (adjust_threads(threads, count, tids, index, nr_tids) < 0) return -1; free(threads); count = nr_tids; threads = tids; } if (attach_process(pid) < 0) return -1; for (i = 0; i < count; ++i) { void *upt_info; int x; char comm[16]; char end_pad[25] = "------------------------"; x = get_thread_comm(threads[i], comm, sizeof(comm)); if (x > 0 && x <= sizeof(end_pad)) { end_pad[sizeof(end_pad) - x] = '\0'; printf("-------------- thread %d (%d) (%s) %s\n", (index != NULL ? index[i] : i + 1), threads[i], comm, end_pad); } if (threads[i] != pid && attach_thread(threads[i]) < 0) { rc = -1; break; } upt_info = _UPT_create(threads[i]); if (backtrace_thread(&_UPT_accessors, upt_info) < 0) rc = -1; _UPT_destroy(upt_info); if (threads[i] != pid && detach_thread(threads[i])) rc = -1; if (rc < 0) break; } free(threads); if (detach_process(pid) < 0) return -1; return rc; #else return -1; #endif /* NO_LIBUNWIND_PTRACE */ }
/* * save process' memory maps, stack contents, thread identifiers and registers */ struct snapshot *get_snapshot(int pid, int *tids, int *index, int nr_tids) { struct snapshot *res; int i, attached_tid, n_frames; long page, label, rc; struct mem_data_chunk **stacks_cover = NULL; int v_major, v_minor; int use_process_vm_readv = 0; if ((page = sysconf(_SC_PAGESIZE)) < 0) { perror("get pagesize"); return NULL; } --page; res = calloc(1, sizeof(struct snapshot)); /* * create memory_map structure corresponding to process' maps */ res->map = create_maps(pid); if (res->map == NULL) goto get_snapshot_fail; /* * get process' threads */ res->num_threads = get_threads(pid, &res->tids); if (res->num_threads < 0 || res->tids == NULL) goto get_snapshot_fail; /* * user-provided list of threads */ if (tids != NULL) { if (adjust_threads(res->tids, res->num_threads, tids, index, nr_tids) < 0) goto get_snapshot_fail; free(res->tids); res->num_threads = nr_tids; res->tids = tids; } res->cur_thr = 0; res->regs = malloc(sizeof(struct user_regs_struct)*res->num_threads); if (res->regs == NULL) { perror("malloc"); goto get_snapshot_fail; } /* * decide how to copy memory contents of the process. on newer kernels * proc_vm_readv() is used by default. on older kernels or when the option * --proc-mem is specified read the file /proc/<pid>/mem */ if (!opt_proc_mem) { if (get_kernel_version(&v_major, &v_minor) < 0) goto get_snapshot_fail; if (((v_major << 16) | v_minor) >= 0x30002) use_process_vm_readv = 1; } else { use_process_vm_readv = 0; } /* FREEZE PROCESS */ if (attach_process(pid) < 0) goto get_snapshot_fail; for (i = 0; i < res->num_threads; ++i) { /* * we have already attached to main thread. call attach_thread() * for other ones */ attached_tid = res->tids[i]; if (res->tids[i] != pid && attach_thread(res->tids[i]) < 0) goto get_snapshot_fail_attached; /* * save thread's registers */ rc = ptrace(PTRACE_GETREGS, res->tids[i], NULL, &res->regs[i]); if (rc < 0) { perror("PTRACE_GETREGS"); goto get_snapshot_fail_attached; } /* * save label on memory region. it will indicate that memory contents * upper than this point (%rsp) will needed to unwind stacks */ label = res->regs[i].rsp & ~page; rc = mem_map_add_label(res->map, (void *)label, res->num_threads); if (rc < 0) { fprintf(stderr, "failed to add label 0x%lx [rsp 0x%lx thread %d]\n", label, res->regs[i].rsp, res->tids[i]); goto get_snapshot_fail_attached; } /* * detach from thread. it will still be frozen due to SIGSTOP */ if (res->tids[i] != pid && detach_thread(res->tids[i]) < 0) goto get_snapshot_fail_attached; } /* * arrange data chunks to copy memory contents. in most cases the chunks * will start from %rsp pointing somewhere in thread's stack * to the end of the stack region */ stacks_cover = malloc(sizeof(struct mem_data_chunk*) * res->num_threads); n_frames = mem_map_build_label_cover(res->map, stack_size, stacks_cover, page + 1); if (stacks_cover == NULL) { fprintf(stderr, "error: stacks cover == NULL, n_frames=%d\n", n_frames); goto get_snapshot_fail_attached; } /* * copy memory contents */ rc = use_process_vm_readv ? copy_memory_process_vm_readv(pid, stacks_cover, n_frames) : copy_memory_proc_mem(pid, stacks_cover, n_frames); if (rc < 0) goto get_snapshot_fail_attached; /* UNFREEZE PROCESS */ if (detach_process(pid) < 0) goto get_snapshot_fail; if (opt_verbose) { for (i = 0; i < n_frames; ++i) { struct mem_data_chunk *chunk = stacks_cover[i]; printf("chunk #%d: 0x%lx-0x%lx length: %ldK\n", i, (size_t)chunk->start, (size_t)chunk->start + chunk->length, chunk->length >> 10); } } free(stacks_cover); return res; get_snapshot_fail_attached: if (attached_tid) detach_thread(attached_tid); detach_process(pid); get_snapshot_fail: if (opt_verbose) { fprintf(stderr, "maps of %d:\n", pid); print_proc_maps(pid); } free(stacks_cover); snapshot_destroy(res); return NULL; }