//--------------------------------------------------------------------------
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();
}
Example #2
0
//--------------------------------------------------------------------------
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, &notify);
  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);
}
Example #3
0
//--------------------------------------------------------------------------
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;
}
Example #4
0
//--------------------------------------------------------------------------
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;
}