From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16336 invoked by alias); 15 Jun 2008 21:05:46 -0000 Received: (qmail 16327 invoked by uid 22791); 15 Jun 2008 21:05:43 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 15 Jun 2008 21:05:15 +0000 Received: (qmail 3719 invoked from network); 15 Jun 2008 21:05:13 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 15 Jun 2008 21:05:13 -0000 From: Pedro Alves Subject: [non-stop] 07/10 non-stop inferior control Date: Sun, 15 Jun 2008 21:06:00 -0000 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Content-Disposition: inline To: gdb-patches@sourceware.org Content-Type: Multipart/Mixed; boundary="Boundary-00=_MQYVIKXPTJ/Sa5F" Message-Id: <200806152205.16824.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-06/txt/msg00285.txt.bz2 --Boundary-00=_MQYVIKXPTJ/Sa5F Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Content-length: 1138 This patch adds the base inferior control support for non-stop mode. In non-stop mode, each thread is handled individually. =C2=A0It should behave close to having a separate debugger attached to each thread. To accomplish that, as soon as we have an event, we context switch to it, and go on handling it. =C2=A0The cases of hiting a breakpoint in another thread while we're stepping don't need to be handled specially, as each thread will have its own stepping state. Another difference in non-stop mode, is that exec commands apply only to the selected thread; the target is never told to resume all threads -- much like with scheduler locking on. It is also needed to have support to interrupt/suspend a simple thread so a new target_stop_ptid method was added to request the target to interrupt a single thread. Several checks have been added so GDB doesn't try to do things with running threads, which don't make sense, like asking for the current PC of an executing thread. "info threads" now shows "(running)" instead of info on the selected frame, on running threads. =C2=A0MI support will be added on top. --=20 Pedro Alves --Boundary-00=_MQYVIKXPTJ/Sa5F Content-Type: text/x-diff; charset="utf-8"; name="007-non_stop_core.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="007-non_stop_core.diff" Content-length: 22929 2008-06-15 Pedro Alves * infrun.c (resume): In non-stop mode, always resume just one thread. (proceed): Don't call prepare_to_proceed in non-stop mode. (fetch_inferior_event): In non-stop mode, switch context before handling the event. (error_is_running, ensure_not_running): New. (handle_inferior_event): In non-stop mode: Mark only the event thread as stopped. Require that the target module manages adding threads to the thread list. Don't switch to infwait_thread_hop_state. (normal_stop): Only mark not-running if inferior hasn't exited. In non-stop mode, only mark the event thread. * thread.c:Include "cli/cli-decode.h". (print_thread_info): Don't read from a running thread. Output "(running)" if thread is running. (switch_to_thread): Don't read stop_pc if thread is executing. (do_restore_current_thread_cleanup): Don't write to a running thread. (thread_apply_all_command): Don't read from a running thread. In non-stop mode, do a full context-switch instead of just switching threads. (thread_apply_command): In non-stop mode, do a full context-switch instead of just switching threads. (do_captured_thread_select): Likewise. Inform user if selected thread is running. (_initialize_thread): Mark "info threads" and "thread" and async_ok. * inf-loop.c (inferior_event_handler): In non-stop mode, don't unregister the target from the event loop. * infcmd.c (continue_command, step_1, jump_command) (signal_command): Ensure the selected thread isn't running. (interrupt_target_command): In non-stop mode, interrupt only the selected thread. * inferior.h (error_is_running, ensure_not_running): Declare. * target.h (struct target_ops): Add to_stop_ptid member. (target_stop_ptid): Define. * target.c (update_current_target): Inherit to_stop_ptid. Default to_stop_ptid to target_ignore. (debug_to_stop_ptid): New. (debug_to_rcmd): Set to_stop_ptid. * Makefile.in (thread.o): Update. --- gdb/Makefile.in | 2 gdb/inf-loop.c | 14 ++++-- gdb/infcmd.c | 10 ++++ gdb/inferior.h | 6 ++ gdb/infrun.c | 126 ++++++++++++++++++++++++++++++++++++++++++-------------- gdb/target.c | 13 +++++ gdb/target.h | 7 +++ gdb/thread.c | 97 +++++++++++++++++++++++++++++++------------ 8 files changed, 212 insertions(+), 63 deletions(-) Index: src/gdb/infrun.c =================================================================== --- src.orig/gdb/infrun.c 2008-06-15 20:06:41.000000000 +0100 +++ src/gdb/infrun.c 2008-06-15 20:26:51.000000000 +0100 @@ -1052,9 +1052,15 @@ a command like `return' or `jump' to con resume_ptid = inferior_ptid; } - if ((scheduler_mode == schedlock_on) - || (scheduler_mode == schedlock_step - && (step || singlestep_breakpoints_inserted_p))) + if (non_stop) + { + /* With non-stop mode on, threads are always handled + individually. */ + resume_ptid = inferior_ptid; + } + else if ((scheduler_mode == schedlock_on) + || (scheduler_mode == schedlock_step + && (step || singlestep_breakpoints_inserted_p))) { /* User-settable 'scheduler' mode requires solo thread resume. */ resume_ptid = inferior_ptid; @@ -1215,19 +1221,27 @@ proceed (CORE_ADDR addr, enum target_sig "infrun: proceed (addr=0x%s, signal=%d, step=%d)\n", paddr_nz (addr), siggnal, step); - /* In a multi-threaded task we may select another thread - and then continue or step. + if (non_stop) + /* In non-stop, each thread is handled individually. The context + must already be set to the right thread here. */ + ; + else + { + /* In a multi-threaded task we may select another thread and + then continue or step. - But if the old thread was stopped at a breakpoint, it - will immediately cause another breakpoint stop without - any execution (i.e. it will report a breakpoint hit - incorrectly). So we must step over it first. - - prepare_to_proceed checks the current thread against the thread - that reported the most recent event. If a step-over is required - it returns TRUE and sets the current thread to the old thread. */ - if (prepare_to_proceed (step)) - oneproc = 1; + But if the old thread was stopped at a breakpoint, it will + immediately cause another breakpoint stop without any + execution (i.e. it will report a breakpoint hit incorrectly). + So we must step over it first. + + prepare_to_proceed checks the current thread against the + thread that reported the most recent event. If a step-over + is required it returns TRUE and sets the current thread to + the old thread. */ + if (prepare_to_proceed (step)) + oneproc = 1; + } if (oneproc) { @@ -1529,6 +1543,15 @@ fetch_inferior_event (void *client_data) else ecs->ptid = target_wait (waiton_ptid, &ecs->ws); + if (non_stop + && ecs->ws.kind != TARGET_WAITKIND_IGNORE + && ecs->ws.kind != TARGET_WAITKIND_EXITED + && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) + /* In non-stop mode, each thread is handled individually. Switch + early, so the global state is set correctly for this + thread. */ + context_switch (ecs->ptid); + /* Now figure out what to do with the result of the result. */ handle_inferior_event (ecs); @@ -1739,6 +1762,20 @@ init_infwait_state (void) infwait_state = infwait_normal_state; } +void +error_is_running (void) +{ + error (_("\ +Cannot execute this command while the selected thread is running.")); +} + +void +ensure_not_running (void) +{ + if (is_running (inferior_ptid)) + error_is_running (); +} + /* Given an execution control state that has been freshly filled in by an event from the inferior, figure out what it means and take appropriate action. */ @@ -1810,11 +1847,16 @@ handle_inferior_event (struct execution_ && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event) add_thread (ecs->ptid); - /* Mark all threads as not-executing. In non-stop, this should be - adjusted to only mark ecs->ptid. */ - if (ecs->ws.kind != TARGET_WAITKIND_IGNORE - && stop_soon != STOP_QUIETLY) - set_executing (pid_to_ptid (-1), 0); + if (ecs->ws.kind != TARGET_WAITKIND_IGNORE) + { + /* Mark the stopped threads accordingly. */ + if (!non_stop + || ecs->ws.kind == TARGET_WAITKIND_EXITED + || ecs->ws.kind == TARGET_WAITKIND_SIGNALLED) + set_executing (pid_to_ptid (-1), 0); + else + set_executing (ecs->ptid, 0); + } switch (ecs->ws.kind) { @@ -2052,15 +2094,22 @@ handle_inferior_event (struct execution_ return; } - /* We may want to consider not doing a resume here in order to give - the user a chance to play with the new thread. It might be good - to make that a user-settable option. */ - - /* At this point, all threads are stopped (happens automatically in - either the OS or the native code). Therefore we need to continue - all threads in order to make progress. */ if (ecs->new_thread_event) { + if (non_stop) + /* Non-stop assumes that the target handles adding new threads + to the thread list. */ + internal_error (__FILE__, __LINE__, "\ +targets should add new threads to the thread list themselves in non-stop mode."); + + /* We may want to consider not doing a resume here in order to + give the user a chance to play with the new thread. It might + be good to make that a user-settable option. */ + + /* At this point, all threads are stopped (happens automatically + in either the OS or the native code). Therefore we need to + continue all threads in order to make progress. */ + target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0); prepare_to_wait (ecs); return; @@ -2127,6 +2176,9 @@ handle_inferior_event (struct execution_ if (!ptid_equal (deferred_step_ptid, null_ptid)) { + /* In non-stop mode, there's never a deferred_step_ptid set. */ + gdb_assert (!non_stop); + /* If we stopped for some other reason than single-stepping, ignore the fact that we were supposed to switch back. */ if (stop_signal == TARGET_SIGNAL_TRAP) @@ -2275,8 +2327,13 @@ handle_inferior_event (struct execution_ if (!ptid_equal (inferior_ptid, ecs->ptid)) context_switch (ecs->ptid); - waiton_ptid = ecs->ptid; - infwait_state = infwait_thread_hop_state; + if (!non_stop) + { + /* Only need to require the next event from this + thread in all-stop mode. */ + waiton_ptid = ecs->ptid; + infwait_state = infwait_thread_hop_state; + } tss->stepping_over_breakpoint = 1; keep_going (ecs); @@ -3831,7 +3888,16 @@ done: /* Delete the breakpoint we stopped at, if it wants to be deleted. Delete any breakpoint that is to be deleted at the next stop. */ breakpoint_auto_delete (stop_bpstat); - set_running (pid_to_ptid (-1), 0); + + if (target_has_execution + && last.kind != TARGET_WAITKIND_SIGNALLED + && last.kind != TARGET_WAITKIND_EXITED) + { + if (!non_stop) + set_running (pid_to_ptid (-1), 0); + else + set_running (inferior_ptid, 0); + } } static int Index: src/gdb/thread.c =================================================================== --- src.orig/gdb/thread.c 2008-06-15 19:40:21.000000000 +0100 +++ src/gdb/thread.c 2008-06-15 20:25:39.000000000 +0100 @@ -42,6 +42,8 @@ #include "observer.h" #include "annotate.h" +#include "cli/cli-decode.h" + /* Definition of struct thread_info exported to gdbthread.h */ /* Prototypes for exported functions. */ @@ -613,9 +615,12 @@ print_thread_info (struct ui_out *uiout, int current_thread = -1; /* Backup current thread and selected frame. */ - saved_frame_id = get_frame_id (get_selected_frame (NULL)); - old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; + old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); make_cleanup_ui_out_list_begin_end (uiout, "threads"); prune_threads (); @@ -650,12 +655,18 @@ print_thread_info (struct ui_out *uiout, ui_out_text (uiout, ")"); } ui_out_text (uiout, " "); - /* That switch put us at the top of the stack (leaf frame). */ - switch_to_thread (tp->ptid); - print_stack_frame (get_selected_frame (NULL), - /* For MI output, print frame level. */ - ui_out_is_mi_like_p (uiout), - LOCATION); + if (tp->running_) + ui_out_text (uiout, "(running)\n"); + else + { + /* The switch below puts us at the top of the stack (leaf + frame). */ + switch_to_thread (tp->ptid); + print_stack_frame (get_selected_frame (NULL), + /* For MI output, print frame level. */ + ui_out_is_mi_like_p (uiout), + LOCATION); + } do_cleanups (chain2); } @@ -671,6 +682,9 @@ print_thread_info (struct ui_out *uiout, ui_out_field_int (uiout, "current-thread-id", current_thread); } + if (is_running (inferior_ptid)) + return; + /* If case we were not able to find the original frame, print the new selected frame. */ if (frame_find_by_id (saved_frame_id) == NULL) @@ -709,7 +723,11 @@ switch_to_thread (ptid_t ptid) inferior_ptid = ptid; reinit_frame_cache (); registers_changed (); - stop_pc = read_pc (); + + if (!is_executing (ptid)) + stop_pc = read_pc (); + else + stop_pc = ~(CORE_ADDR) 0; } static void @@ -746,7 +764,12 @@ do_restore_current_thread_cleanup (void { struct current_thread_cleanup *old = arg; restore_current_thread (old->inferior_ptid); - restore_selected_frame (old->selected_frame_id); + + /* A command like 'thread apply all $exec_command&' may change the + running state of the originally selected thread, so we have to + recheck it here. */ + if (!is_running (old->inferior_ptid)) + restore_selected_frame (old->selected_frame_id); xfree (old); } @@ -774,8 +797,7 @@ static void thread_apply_all_command (char *cmd, int from_tty) { struct thread_info *tp; - struct cleanup *old_chain; - struct cleanup *saved_cmd_cleanup_chain; + struct cleanup *old_chain = make_cleanup (null_cleanup, 0); char *saved_cmd; struct frame_id saved_frame_id; ptid_t current_ptid; @@ -785,8 +807,12 @@ thread_apply_all_command (char *cmd, int error (_("Please specify a command following the thread ID list")); current_ptid = inferior_ptid; - saved_frame_id = get_frame_id (get_selected_frame (NULL)); - old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); + + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; + make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); /* It is safe to update the thread list now, before traversing it for "thread apply all". MVS */ @@ -795,11 +821,15 @@ thread_apply_all_command (char *cmd, int /* Save a copy of the command in case it is clobbered by execute_command */ saved_cmd = xstrdup (cmd); - saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd); + make_cleanup (xfree, saved_cmd); for (tp = thread_list; tp; tp = tp->next) if (thread_alive (tp)) { - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); + printf_filtered (_("\nThread %d (%s):\n"), tp->num, target_tid_to_str (inferior_ptid)); execute_command (cmd, from_tty); @@ -809,12 +839,10 @@ thread_apply_all_command (char *cmd, int if (!ptid_equal (current_ptid, inferior_ptid)) thread_has_changed = 1; - do_cleanups (saved_cmd_cleanup_chain); do_cleanups (old_chain); /* Print stack frame only if we changed thread. */ - if (thread_has_changed) + if (thread_has_changed && !is_running (inferior_ptid)) print_stack_frame (get_current_frame (), 1, SRC_LINE); - } static void @@ -838,7 +866,11 @@ thread_apply_command (char *tidlist, int error (_("Please specify a command following the thread ID list")); current_ptid = inferior_ptid; - saved_frame_id = get_frame_id (get_selected_frame (NULL)); + + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); /* Save a copy of the command in case it is clobbered by @@ -882,7 +914,10 @@ thread_apply_command (char *tidlist, int warning (_("Thread %d has terminated."), start); else { - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); printf_filtered (_("\nThread %d (%s):\n"), tp->num, target_tid_to_str (inferior_ptid)); execute_command (cmd, from_tty); @@ -950,7 +985,10 @@ do_captured_thread_select (struct ui_out if (!thread_alive (tp)) error (_("Thread ID %d has terminated."), num); - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); ui_out_text (uiout, "[Switching to thread "); ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid)); @@ -958,7 +996,11 @@ do_captured_thread_select (struct ui_out ui_out_text (uiout, target_tid_to_str (inferior_ptid)); ui_out_text (uiout, ")]"); - print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); + if (!tp->running_) + print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); + else + ui_out_text (uiout, "(running)\n"); + return GDB_RC_OK; } @@ -978,14 +1020,17 @@ void _initialize_thread (void) { static struct cmd_list_element *thread_apply_list = NULL; + struct cmd_list_element *c; - add_info ("threads", info_threads_command, - _("IDs of currently known threads.")); + c = add_info ("threads", info_threads_command, + _("IDs of currently known threads.")); + set_cmd_async_ok (c); - add_prefix_cmd ("thread", class_run, thread_command, _("\ + c = add_prefix_cmd ("thread", class_run, thread_command, _("\ Use this command to switch between threads.\n\ The new thread ID must be currently known."), &thread_cmd_list, "thread ", 1, &cmdlist); + set_cmd_async_ok (c); add_prefix_cmd ("apply", class_run, thread_apply_command, _("Apply a command to a list of threads."), Index: src/gdb/inf-loop.c =================================================================== --- src.orig/gdb/inf-loop.c 2008-06-15 17:57:52.000000000 +0100 +++ src/gdb/inf-loop.c 2008-06-15 20:06:52.000000000 +0100 @@ -73,11 +73,15 @@ inferior_event_handler (enum inferior_ev break; case INF_EXEC_COMPLETE: - /* Unregister the inferior from the event loop. This is done so that - when the inferior is not running we don't get distracted by - spurious inferior output. */ - if (target_has_execution) - target_async (NULL, 0); + + if (!non_stop) + { + /* Unregister the inferior from the event loop. This is done + so that when the inferior is not running we don't get + distracted by spurious inferior output. */ + if (target_has_execution) + target_async (NULL, 0); + } /* The call to async_enable_stdin below resets 'sync_execution'. However, if sync_execution is 1 now, we also need to show the Index: src/gdb/infcmd.c =================================================================== --- src.orig/gdb/infcmd.c 2008-06-15 17:57:46.000000000 +0100 +++ src/gdb/infcmd.c 2008-06-15 20:25:41.000000000 +0100 @@ -613,6 +613,7 @@ continue_command (char *proc_count_exp, { int async_exec = 0; ERROR_NO_INFERIOR; + ensure_not_running (); /* Find out whether we must run in the background. */ if (proc_count_exp != NULL) @@ -714,6 +715,7 @@ step_1 (int skip_subroutines, int single int thread = -1; ERROR_NO_INFERIOR; + ensure_not_running (); if (count_string) async_exec = strip_bg_char (&count_string); @@ -936,6 +938,7 @@ jump_command (char *arg, int from_tty) int async_exec = 0; ERROR_NO_INFERIOR; + ensure_not_running (); /* Find out whether we must run in the background. */ if (arg != NULL) @@ -1036,6 +1039,7 @@ signal_command (char *signum_exp, int fr dont_repeat (); /* Too dangerous. */ ERROR_NO_INFERIOR; + ensure_not_running (); /* Find out whether we must run in the background. */ if (signum_exp != NULL) @@ -2100,7 +2104,11 @@ interrupt_target_command (char *args, in if (target_can_async_p ()) { dont_repeat (); /* Not for the faint of heart */ - target_stop (); + + if (non_stop) + target_stop_ptid (inferior_ptid); + else + target_stop (); } } Index: src/gdb/inferior.h =================================================================== --- src.orig/gdb/inferior.h 2008-06-15 20:01:30.000000000 +0100 +++ src/gdb/inferior.h 2008-06-15 20:25:40.000000000 +0100 @@ -245,6 +245,12 @@ extern void get_last_target_status(ptid_ extern void follow_inferior_reset_breakpoints (void); +/* Throw an error indicating the current thread is running. */ +extern void error_is_running (void); + +/* Calls error_is_running if the current thread is running. */ +extern void ensure_not_running (void); + /* From infcmd.c */ extern void tty_command (char *, int); Index: src/gdb/target.h =================================================================== --- src.orig/gdb/target.h 2008-06-15 19:40:17.000000000 +0100 +++ src/gdb/target.h 2008-06-15 20:06:52.000000000 +0100 @@ -397,6 +397,7 @@ struct target_ops char *(*to_pid_to_str) (ptid_t); char *(*to_extra_thread_info) (struct thread_info *); void (*to_stop) (void); + void (*to_stop_ptid) (ptid_t ptid); void (*to_rcmd) (char *command, struct ui_file *output); char *(*to_pid_to_exec_file) (int pid); void (*to_log_command) (const char *); @@ -895,6 +896,12 @@ int target_follow_fork (int follow_child #define target_stop current_target.to_stop +/* Same as target_stop, but apply to PTID. Used in non-stop mode to + stop a single thread without affecting the running state of the + others. */ +#define target_stop_ptid(ptid) \ + (*current_target.to_stop_ptid) (ptid) + /* Send the specified COMMAND to the target's monitor (shell,interpreter) for execution. The result of the query is placed in OUTBUF. */ Index: src/gdb/target.c =================================================================== --- src.orig/gdb/target.c 2008-06-15 17:57:52.000000000 +0100 +++ src/gdb/target.c 2008-06-15 20:25:40.000000000 +0100 @@ -456,6 +456,7 @@ update_current_target (void) INHERIT (to_pid_to_str, t); INHERIT (to_extra_thread_info, t); INHERIT (to_stop, t); + INHERIT (to_stop_ptid, t); /* Do not inherit to_xfer_partial. */ INHERIT (to_rcmd, t); INHERIT (to_pid_to_exec_file, t); @@ -632,6 +633,9 @@ update_current_target (void) de_fault (to_stop, (void (*) (void)) target_ignore); + de_fault (to_stop_ptid, + (void (*) (ptid_t)) + target_ignore); current_target.to_xfer_partial = current_xfer_partial; de_fault (to_rcmd, (void (*) (char *, struct ui_file *)) @@ -2939,6 +2943,14 @@ debug_to_stop (void) } static void +debug_to_stop_ptid (ptid_t ptid) +{ + debug_target.to_stop_ptid (ptid); + + fprintf_unfiltered (gdb_stdlog, "target_stop_pid\n"); +} + +static void debug_to_rcmd (char *command, struct ui_file *outbuf) { @@ -3012,6 +3024,7 @@ setup_target_debug (void) current_target.to_thread_alive = debug_to_thread_alive; current_target.to_find_new_threads = debug_to_find_new_threads; current_target.to_stop = debug_to_stop; + current_target.to_stop_ptid = debug_to_stop_ptid; current_target.to_rcmd = debug_to_rcmd; current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file; } Index: src/gdb/Makefile.in =================================================================== --- src.orig/gdb/Makefile.in 2008-06-15 19:40:21.000000000 +0100 +++ src/gdb/Makefile.in 2008-06-15 20:06:52.000000000 +0100 @@ -2934,7 +2934,7 @@ target-memory.o: target-memory.c $(defs_ thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \ $(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(exceptions_h) \ $(command_h) $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) \ - $(ui_out_h) $(observer_h) $(annotate_h) + $(ui_out_h) $(observer_h) $(annotate_h) $(cli_decode_h) top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \ $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \ $(inferior_h) $(exceptions_h) $(target_h) $(breakpoint_h) \ --Boundary-00=_MQYVIKXPTJ/Sa5F--