|
69 | 69 | //---------------------------------------------------------------------- |
70 | 70 | MachTask::MachTask(MachProcess *process) |
71 | 71 | : m_process(process), m_task(TASK_NULL), m_vm_memory(), |
72 | | - m_exception_thread(0), m_exception_port(MACH_PORT_NULL) { |
| 72 | + m_exception_thread(0), m_exception_port(MACH_PORT_NULL), |
| 73 | + m_exec_will_be_suspended(false), m_do_double_resume(false) { |
73 | 74 | memset(&m_exc_port_info, 0, sizeof(m_exc_port_info)); |
74 | 75 | } |
75 | 76 |
|
|
103 | 104 | err = BasicInfo(task, &task_info); |
104 | 105 |
|
105 | 106 | if (err.Success()) { |
| 107 | + if (m_do_double_resume && task_info.suspend_count == 2) { |
| 108 | + err = ::task_resume(task); |
| 109 | + if (DNBLogCheckLogBit(LOG_TASK) || err.Fail()) |
| 110 | + err.LogThreaded("::task_resume double-resume after exec-start-stopped " |
| 111 | + "( target_task = 0x%4.4x )", task); |
| 112 | + } |
| 113 | + m_do_double_resume = false; |
| 114 | + |
106 | 115 | // task_resume isn't counted like task_suspend calls are, are, so if the |
107 | 116 | // task is not suspended, don't try and resume it since it is already |
108 | 117 | // running |
|
135 | 144 | m_task = TASK_NULL; |
136 | 145 | m_exception_thread = 0; |
137 | 146 | m_exception_port = MACH_PORT_NULL; |
| 147 | + m_exec_will_be_suspended = false; |
| 148 | + m_do_double_resume = false; |
138 | 149 | } |
139 | 150 |
|
140 | 151 | //---------------------------------------------------------------------- |
@@ -651,6 +662,9 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType, |
651 | 662 | err.LogThreaded("::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )", |
652 | 663 | task_self, exception_port); |
653 | 664 |
|
| 665 | + m_exec_will_be_suspended = false; |
| 666 | + m_do_double_resume = false; |
| 667 | + |
654 | 668 | return err.Status(); |
655 | 669 | } |
656 | 670 |
|
@@ -960,4 +974,14 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType, |
960 | 974 | void MachTask::TaskPortChanged(task_t task) |
961 | 975 | { |
962 | 976 | m_task = task; |
| 977 | + |
| 978 | + // If we've just exec'd to a new process, and it |
| 979 | + // is started suspended, we'll need to do two |
| 980 | + // task_resume's to get the inferior process to |
| 981 | + // continue. |
| 982 | + if (m_exec_will_be_suspended) |
| 983 | + m_do_double_resume = true; |
| 984 | + else |
| 985 | + m_do_double_resume = false; |
| 986 | + m_exec_will_be_suspended = false; |
963 | 987 | } |
0 commit comments