//-------------------------------------------------------------------------- int idaapi macbase_debmod_t::get_process_list(procvec_t *list) { list->clear(); int mypid = getpid(); int sysControl[4]; sysControl[0] = CTL_KERN; sysControl[1] = KERN_PROC; sysControl[2] = KERN_PROC_ALL; qvector<struct kinfo_proc> info; size_t length; int count = 0; int rc = -1; for ( int tries=0; rc != 0 && tries < 5; ++tries ) { // the first call of sysctl() is used to determine the size of the buffer // will be passed to the second call length = 0; sysctl(sysControl, 3, NULL, &length, NULL, 0); // If the number of processes is greater than the size of the buffer // sysctl() supplies as much data as fits in the buffer and returns ENOMEM. // We reserve 100 extra elements for processes started after 1st sysctl // In case even this number is not sufficient we turn to the next attempt count = (length / sizeof (info[0])) + 100; if ( count <= 0 ) return 0; if ( info.size() < count ) info.resize(count); length = sizeof(info[0]) * info.size(); rc = sysctl(sysControl, 3, info.begin(), &length, NULL, 0); if ( rc != 0 && errno != ENOMEM ) return 0; } count = (length / sizeof (info[0])); // exact number of processes for ( int i=0; i < count; i++ ) { extern_proc &ep = info[i].kp_proc; pid_t _pid = ep.p_pid; if ( _pid == mypid ) continue; mach_port_t port; kern_return_t result = task_for_pid(mach_task_self(), _pid, &port); if ( result == KERN_SUCCESS ) { ext_process_info_t &pi = list->push_back(); qstrncpy(pi.name, ep.p_comm, sizeof(pi.name)); pi.pid = _pid; pi.addrsize = get_process_bitness(_pid); build_process_ext_name(&pi); } else { debdeb("%d: %s is unavailable for debugging\n", _pid, info[i].kp_proc.p_comm); } } return list->size(); }
//-------------------------------------------------------------------------- void linux_debmod_t::tdb_enable_event(td_event_e event, internal_bpt *bp) { td_notify_t notify; td_err_e err = td_ta_event_addr(ta, event, ¬ify); DIE_IF_FAILED("td_ta_event_addr", err); bool ok = add_internal_bp(*bp, size_t(notify.u.bptaddr)); debdeb("%a: added BP for thread event %s\n", bp->bpt_addr, event == TD_CREATE ? "TD_CREATE" : "TD_DEATH"); QASSERT(ok); }
//-------------------------------------------------------------------------- bool debmod_t::evaluate_and_handle_lowcnd(debug_event_t *event) { bool resume = false; if ( event->eid == BREAKPOINT && !handling_lowcnd ) { ea_t ea = event->bpt.kea != BADADDR ? event->bpt.kea : event->bpt.hea != BADADDR ? event->bpt.hea : event->ea; lowcnd_t *lc = get_failed_lowcnd(event->tid, ea); if ( lc != NULL ) { // condition is not satisfied, just make a single step and resume debdeb("%a: bptcnd yielded false\n", ea); event->handled = true; resume = handle_lowcnd(lc, event); } } return resume; }
//-------------------------------------------------------------------------- gdecode_t idaapi dosbox_debmod_t::dbg_get_debug_event(debug_event_t *event, int timeout_ms) { if ( event == NULL ) return GDE_NO_EVENT; while ( true ) { // are there any pending events? if ( events.retrieve(event) ) { debdeb("GDE: %s\n", debug_event_str(event)); return GDE_ONE_EVENT; } // no pending events, check the target // trk.poll_for_event(ida_is_idle ? TIMEOUT : 0); if ( events.empty() ) break; } return GDE_NO_EVENT; }