Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Commit db665f4

Browse files
author
Simon Marchi
committed
darwin: Do not add a dummy thread
Starting a process on macOS/Darwin currently leads to this error: /Users/simark/src/binutils-gdb/gdb/darwin-nat.c:383: internal-error: void darwin_check_new_threads(struct inferior *): Assertion `tp' failed. with the corresponding partial backtrace (sorry, taken with lldb, because well, gdb is broken :)): frame #9: 0x000000010004605a gdb`darwin_check_new_threads(inf=0x0000000100edf670) at darwin-nat.c:383 frame #10: 0x0000000100045848 gdb`darwin_init_thread_list(inf=0x0000000100edf670) at darwin-nat.c:1710 frame #11: 0x00000001000452f8 gdb`darwin_ptrace_him(pid=8375) at darwin-nat.c:1792 frame #12: 0x0000000100041d95 gdb`fork_inferior(...) at fork-inferior.c:440 frame #13: 0x0000000100043f82 gdb`darwin_create_inferior(...) at darwin-nat.c:1841 frame #14: 0x000000010034ac32 gdb`run_command_1(args=0x0000000000000000, from_tty=1, tbreak_at_main=1) at infcmd.c:611 The issue was introduced by commit "Share fork_inferior et al with gdbserver" because it changed the place where the dummy thread (pid, 0, 0) is added, relative to the call to the init_trace_fun callback. In this callback, darwin checks for new threads in the program (there should be exactly one) in order to update this dummy thread with the right tid. Previously, things happened in this order: - fork_inferior calls fork() - fork_inferior adds dummy thread - fork_inferior calls init_trace_fun callback, which updates the dummy thread info Following the commit mentioned above, the new thread is added in the darwin-nat code, after having called fork_inferior (in darwin_create_inferior). So gdb tries to do things in this order: - fork_inferior calls fork() - fork_inferior calls init_trace_fun callback, which tries to update the dummy thread info - darwin_create_inferior adds the dummy thread The error happens while trying to update the dummy thread that has not been added yet. I don't think this dummy thread is necessary for darwin. Previously, it was fork_inferior that was adding this thread, for all targets, so darwin had to deal with it. Now that it's done by targets themselves, we can just skip that on darwin. darwin_check_new_threads called indirectly by init_trace_fun/darwin_ptrace_him will simply notice the new thread and add it with the right information. My level of testing was: try to start a process and try to attach to a process, and it seems to work somewhat like it did before. I tried to run the testsuite, but it leaves a huge amount of zombie processes that launchd doesn't seem to reap, leading to exhaustion of system resources (number of processes). gdb/ChangeLog: * darwin-nat.c (darwin_check_new_threads): Don't handle dummy thread. (darwin_init_thread_list): Don't update dummy thread. (darwin_create_inferior, darwin_attach): Don't add a dummy thread.
1 parent ea9aafc commit db665f4

File tree

2 files changed

+38
-47
lines changed

2 files changed

+38
-47
lines changed

gdb/ChangeLog

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2017-06-27 Simon Marchi <[email protected]>
2+
3+
* darwin-nat.c (darwin_check_new_threads): Don't handle dummy
4+
thread.
5+
(darwin_init_thread_list): Don't update dummy thread.
6+
(darwin_create_inferior, darwin_attach): Don't add a dummy thread.
7+
18
2017-06-26 Simon Marchi <[email protected]>
29

310
* record-full.c (netorder16): Remove.

gdb/darwin-nat.c

+31-47
Original file line numberDiff line numberDiff line change
@@ -367,29 +367,14 @@ darwin_check_new_threads (struct inferior *inf)
367367
if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
368368
{
369369
/* A thread was created. */
370-
struct thread_info *tp;
371370
struct private_thread_info *pti;
372371

373372
pti = XCNEW (struct private_thread_info);
374373
pti->gdb_port = new_id;
375374
pti->msg_state = DARWIN_RUNNING;
376375

377-
if (old_nbr == 0 && new_ix == 0)
378-
{
379-
/* A ptid is create when the inferior is started (see
380-
fork-child.c) with lwp=tid=0. This ptid will be renamed
381-
later by darwin_init_thread_list (). */
382-
tp = find_thread_ptid (ptid_build (inf->pid, 0, 0));
383-
gdb_assert (tp);
384-
gdb_assert (tp->priv == NULL);
385-
tp->priv = pti;
386-
}
387-
else
388-
{
389-
/* Add the new thread. */
390-
tp = add_thread_with_info
391-
(ptid_build (inf->pid, 0, new_id), pti);
392-
}
376+
/* Add the new thread. */
377+
add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti);
393378
VEC_safe_push (darwin_thread_t, thread_vec, pti);
394379
new_ix++;
395380
continue;
@@ -1701,23 +1686,38 @@ darwin_attach_pid (struct inferior *inf)
17011686
push_target (darwin_ops);
17021687
}
17031688

1689+
/* Get the thread_info object corresponding to this private_thread_info. */
1690+
1691+
static struct thread_info *
1692+
thread_info_from_private_thread_info (private_thread_info *pti)
1693+
{
1694+
struct thread_info *it;
1695+
1696+
ALL_THREADS (it)
1697+
{
1698+
if (it->priv->gdb_port == pti->gdb_port)
1699+
break;
1700+
}
1701+
1702+
gdb_assert (it != NULL);
1703+
1704+
return it;
1705+
}
1706+
17041707
static void
17051708
darwin_init_thread_list (struct inferior *inf)
17061709
{
1707-
darwin_thread_t *thread;
1708-
ptid_t new_ptid;
1709-
17101710
darwin_check_new_threads (inf);
17111711

1712-
gdb_assert (inf->priv->threads
1713-
&& VEC_length (darwin_thread_t, inf->priv->threads) > 0);
1714-
thread = VEC_index (darwin_thread_t, inf->priv->threads, 0);
1712+
gdb_assert (inf->priv->threads != NULL);
1713+
gdb_assert (VEC_length (darwin_thread_t, inf->priv->threads) > 0);
17151714

1716-
/* Note: fork_inferior automatically add a thead but it uses a wrong ptid.
1717-
Fix up. */
1718-
new_ptid = ptid_build (inf->pid, 0, thread->gdb_port);
1719-
thread_change_ptid (inferior_ptid, new_ptid);
1720-
inferior_ptid = new_ptid;
1715+
private_thread_info *first_pti
1716+
= VEC_index (darwin_thread_t, inf->priv->threads, 0);
1717+
struct thread_info *first_thread
1718+
= thread_info_from_private_thread_info (first_pti);
1719+
1720+
inferior_ptid = first_thread->ptid;
17211721
}
17221722

17231723
/* The child must synchronize with gdb: gdb must set the exception port
@@ -1834,23 +1834,10 @@ darwin_create_inferior (struct target_ops *ops,
18341834
const std::string &allargs,
18351835
char **env, int from_tty)
18361836
{
1837-
pid_t pid;
1838-
ptid_t ptid;
1839-
18401837
/* Do the hard work. */
1841-
pid = fork_inferior (exec_file, allargs, env, darwin_ptrace_me,
1842-
darwin_ptrace_him, darwin_pre_ptrace, NULL,
1843-
darwin_execvp);
1844-
1845-
ptid = pid_to_ptid (pid);
1846-
/* Return now in case of error. */
1847-
if (ptid_equal (inferior_ptid, null_ptid))
1848-
return;
1849-
1850-
/* We have something that executes now. We'll be running through
1851-
the shell at this point (if startup-with-shell is true), but the
1852-
pid shouldn't change. */
1853-
add_thread_silent (ptid);
1838+
fork_inferior (exec_file, allargs, env, darwin_ptrace_me,
1839+
darwin_ptrace_him, darwin_pre_ptrace, NULL,
1840+
darwin_execvp);
18541841
}
18551842

18561843

@@ -1920,9 +1907,6 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty)
19201907
inferior_appeared (inf, pid);
19211908
inf->attach_flag = 1;
19221909

1923-
/* Always add a main thread. */
1924-
add_thread_silent (inferior_ptid);
1925-
19261910
darwin_attach_pid (inf);
19271911

19281912
darwin_suspend_inferior (inf);

0 commit comments

Comments
 (0)