mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +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
	 aarzilli
					aarzilli