proc: wait for full process stop before evaluating anything

This commit is contained in:
aarzilli
2016-01-07 19:33:15 +01:00
parent ab2b9ad1c6
commit 4da4aea89c
4 changed files with 65 additions and 6 deletions

View File

@ -127,7 +127,7 @@ mach_port_wait(mach_port_t port_set, int nonblocking) {
// Wait for mach msg.
kret = mach_msg(&msg.hdr, opts,
0, sizeof(msg.data), port_set, 0, MACH_PORT_NULL);
0, sizeof(msg.data), port_set, 10, MACH_PORT_NULL);
if (kret == MACH_RCV_INTERRUPTED) return kret;
if (kret != MACH_MSG_SUCCESS) return 0;

View File

@ -1,6 +1,7 @@
package proc
// #include "proc_darwin.h"
// #include "threads_darwin.h"
// #include "exec_darwin.h"
// #include <stdlib.h>
import "C"
@ -314,20 +315,42 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
}
}
func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
trapthread.SetCurrentBreakpoint()
func (dbp *Process) waitForStop() ([]int, error) {
ports := make([]int, 0, len(dbp.Threads))
count := 0
for {
port := C.mach_port_wait(dbp.os.portSet, C.int(1))
if port == 0 {
return nil
if port != 0 {
count = 0
ports = append(ports, int(port))
} else {
n := C.num_running_threads(C.task_t(dbp.os.task))
if n == 0 {
return ports, nil
} else if n < 0 {
return nil, fmt.Errorf("error waiting for thread stop %d", n)
} else if count > 16 {
return nil, fmt.Errorf("could not stop porcess %d", n)
}
}
if th, ok := dbp.Threads[int(port)]; ok {
}
}
func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
ports, err := dbp.waitForStop()
if err != nil {
return err
}
trapthread.SetCurrentBreakpoint()
for _, port := range ports {
if th, ok := dbp.Threads[port]; ok {
err := th.SetCurrentBreakpoint()
if err != nil {
return err
}
}
}
return nil
}
func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) {

View File

@ -135,3 +135,36 @@ thread_blocked(thread_act_t thread) {
return info.suspend_count;
}
int
num_running_threads(task_t task) {
kern_return_t kret;
thread_act_array_t list;
mach_msg_type_number_t count;
int i, n = 0;
kret = task_threads(task, &list, &count);
if (kret != KERN_SUCCESS) {
return -kret;
}
for (i = 0; i < count; ++i) {
thread_act_t thread = list[i];
struct thread_basic_info info;
unsigned int info_count = THREAD_BASIC_INFO_COUNT;
kret = thread_info((thread_t)thread, THREAD_BASIC_INFO, (thread_info_t)&info, &info_count);
if (kret == KERN_SUCCESS) {
if (info.suspend_count == 0) {
++n;
} else {
}
}
}
kret = vm_deallocate(mach_task_self(), (vm_address_t) list, count * sizeof(list[0]));
if (kret != KERN_SUCCESS) return -kret;
return n;
}

View File

@ -33,3 +33,6 @@ get_identity(mach_port_name_t, thread_identifier_info_data_t *);
int
thread_blocked(thread_act_t thread);
int
num_running_threads(task_t task);