mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 17:56:45 +08:00
proc: wait for full process stop before evaluating anything
This commit is contained in:
@ -127,7 +127,7 @@ mach_port_wait(mach_port_t port_set, int nonblocking) {
|
|||||||
|
|
||||||
// Wait for mach msg.
|
// Wait for mach msg.
|
||||||
kret = mach_msg(&msg.hdr, opts,
|
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_RCV_INTERRUPTED) return kret;
|
||||||
if (kret != MACH_MSG_SUCCESS) return 0;
|
if (kret != MACH_MSG_SUCCESS) return 0;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package proc
|
package proc
|
||||||
|
|
||||||
// #include "proc_darwin.h"
|
// #include "proc_darwin.h"
|
||||||
|
// #include "threads_darwin.h"
|
||||||
// #include "exec_darwin.h"
|
// #include "exec_darwin.h"
|
||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
import "C"
|
import "C"
|
||||||
@ -314,20 +315,42 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
|
func (dbp *Process) waitForStop() ([]int, error) {
|
||||||
trapthread.SetCurrentBreakpoint()
|
ports := make([]int, 0, len(dbp.Threads))
|
||||||
|
count := 0
|
||||||
for {
|
for {
|
||||||
port := C.mach_port_wait(dbp.os.portSet, C.int(1))
|
port := C.mach_port_wait(dbp.os.portSet, C.int(1))
|
||||||
if port == 0 {
|
if port != 0 {
|
||||||
return nil
|
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()
|
err := th.SetCurrentBreakpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) {
|
func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) {
|
||||||
|
|||||||
@ -135,3 +135,36 @@ thread_blocked(thread_act_t thread) {
|
|||||||
|
|
||||||
return info.suspend_count;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -33,3 +33,6 @@ get_identity(mach_port_name_t, thread_identifier_info_data_t *);
|
|||||||
|
|
||||||
int
|
int
|
||||||
thread_blocked(thread_act_t thread);
|
thread_blocked(thread_act_t thread);
|
||||||
|
|
||||||
|
int
|
||||||
|
num_running_threads(task_t task);
|
||||||
|
|||||||
Reference in New Issue
Block a user