darwin: fix thinko (free thread port after threads are discovered).
Due to a thinko, a message could be not understood and ignored. The result was a dead-lock (gdb is waiting for an event that never happen). The port of the thread was deallocated before new threads are discovered. As a consequence, the origin of the message was unknown (instead of being linked to the newly created thread). gdb/ * darwin-nat.c (darwin_check_new_threads): Fix port leak, add comments. (darwin_decode_exception_message): Free port only after use.
This commit is contained in:
parent
19e1c431f7
commit
15a9128a96
|
@ -1,3 +1,9 @@
|
|||
2014-04-09 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* darwin-nat.c (darwin_check_new_threads): Fix port leak, add
|
||||
comments.
|
||||
(darwin_decode_exception_message): Free port only after use.
|
||||
|
||||
2014-04-08 Pierre Langlois <pierre.langlois@embecosm.com>
|
||||
|
||||
* avr-tdep.c (struct gdbarch_tdep): Mention avrxmega in the comment.
|
||||
|
|
|
@ -303,9 +303,18 @@ darwin_check_new_threads (struct inferior *inf)
|
|||
break;
|
||||
if (i == new_nbr)
|
||||
{
|
||||
/* Deallocate ports. */
|
||||
for (i = 0; i < new_nbr; i++)
|
||||
{
|
||||
kret = mach_port_deallocate (mach_task_self (), thread_list[i]);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
}
|
||||
|
||||
/* Deallocate the buffer. */
|
||||
kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
|
||||
new_nbr * sizeof (int));
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -331,8 +340,10 @@ darwin_check_new_threads (struct inferior *inf)
|
|||
new_ix++;
|
||||
old_ix++;
|
||||
|
||||
kret = mach_port_deallocate (gdb_task, old_id);
|
||||
/* Deallocate the port. */
|
||||
kret = mach_port_deallocate (gdb_task, new_id);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (new_ix < new_nbr && new_id == MACH_PORT_DEAD)
|
||||
|
@ -382,6 +393,7 @@ darwin_check_new_threads (struct inferior *inf)
|
|||
VEC_free (darwin_thread_t, darwin_inf->threads);
|
||||
darwin_inf->threads = thread_vec;
|
||||
|
||||
/* Deallocate the buffer. */
|
||||
kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
|
||||
new_nbr * sizeof (int));
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
@ -594,11 +606,10 @@ darwin_decode_exception_message (mach_msg_header_t *hdr,
|
|||
task_port = desc[1].name;
|
||||
thread_port = desc[0].name;
|
||||
|
||||
/* We got new rights to the task and the thread. Get rid of them. */
|
||||
/* We got new rights to the task, get rid of it. Do not get rid of thread
|
||||
right, as we will need it to find the thread. */
|
||||
kret = mach_port_deallocate (mach_task_self (), task_port);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
kret = mach_port_deallocate (mach_task_self (), thread_port);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
||||
/* Find process by port. */
|
||||
inf = darwin_find_inferior_by_task (task_port);
|
||||
|
@ -611,6 +622,10 @@ darwin_decode_exception_message (mach_msg_header_t *hdr,
|
|||
kern_return_t kret;
|
||||
mig_reply_error_t reply;
|
||||
|
||||
/* Free thread port (we don't know it). */
|
||||
kret = mach_port_deallocate (mach_task_self (), thread_port);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
||||
darwin_encode_reply (&reply, hdr, KERN_SUCCESS);
|
||||
|
||||
kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
|
||||
|
@ -627,6 +642,11 @@ darwin_decode_exception_message (mach_msg_header_t *hdr,
|
|||
message can be deallocated. */
|
||||
darwin_check_new_threads (inf);
|
||||
|
||||
/* Free the thread port (as gdb knows the thread, it has already has a right
|
||||
for it, so this just decrement a reference counter). */
|
||||
kret = mach_port_deallocate (mach_task_self (), thread_port);
|
||||
MACH_CHECK_ERROR (kret);
|
||||
|
||||
thread = darwin_find_thread (inf, thread_port);
|
||||
if (thread == NULL)
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue