Use thread_info and inferior pointers more throughout

This is more preparation bits for multi-target support.

In a multi-target scenario, we need to address the case of different
processes/threads running on different targets that happen to have the
same PID/PTID.  E.g., we can have both process 123 in target 1, and
process 123 in target 2, while they're in reality different processes
running on different machines.  Or maybe we've loaded multiple
instances of the same core file.  Etc.

To address this, in my WIP multi-target branch, threads and processes
are uniquely identified by the (process_stratum target_ops *, ptid_t)
and (process_stratum target_ops *, pid) tuples respectively.  I.e.,
each process_stratum instance has its own thread/process number space.

As you can imagine, that requires passing around target_ops * pointers
in a number of functions where we're currently passing only a ptid_t
or an int.  E.g., when we look up a thread_info object by ptid_t in
find_thread_ptid, the ptid_t alone isn't sufficient.

In many cases though, we already have the thread_info or inferior
pointer handy, but we "lose" it somewhere along the call stack, only
to look it up again by ptid_t/pid.  Since thread_info or inferior
objects know their parent target, if we pass around thread_info or
inferior pointers when possible, we avoid having to add extra
target_ops parameters to many functions, and also, we eliminate a
number of by ptid_t/int lookups.

So that's what this patch does.  In a bit more detail:

- Changes a number of functions and methods to take a thread_info or
  inferior pointer instead of a ptid_t or int parameter.

- Changes a number of structure fields from ptid_t/int to inferior or
  thread_info pointers.

- Uses the inferior_thread() function whenever possible instead of
  inferior_ptid.

- Uses thread_info pointers directly when possible instead of the
  is_running/is_stopped etc. routines that require a lookup.

- A number of functions are eliminated along the way, such as:

  int valid_gdb_inferior_id (int num);
  int pid_to_gdb_inferior_id (int pid);
  int gdb_inferior_id_to_pid (int num);
  int in_inferior_list (int pid);

- A few structures and places hold a thread_info pointer across
  inferior execution, so now they take a strong reference to the
  (refcounted) thread_info object to avoid the thread_info pointer
  getting stale.  This is done in enable_thread_stack_temporaries and
  in the infcall.c code.

- Related, there's a spot in infcall.c where using a RAII object to
  handle the refcount would be handy, so a gdb::ref_ptr specialization
  for thread_info is added (thread_info_ref, in gdbthread.h), along
  with a gdb_ref_ptr policy that works for all refcounted_object types
  (in common/refcounted-object.h).

gdb/ChangeLog:
2018-06-21  Pedro Alves  <palves@redhat.com>

	* ada-lang.h (ada_get_task_number): Take a thread_info pointer
	instead of a ptid_t.  All callers adjusted.
	* ada-tasks.c (ada_get_task_number): Likewise.  All callers
	adjusted.
	(print_ada_task_info, display_current_task_id, task_command_1):
	Adjust.
	* breakpoint.c (watchpoint_in_thread_scope): Adjust to use
	inferior_thread.
	(breakpoint_kind): Adjust.
	(remove_breakpoints_pid): Rename to ...
	(remove_breakpoints_inf): ... this.  Adjust to take an inferior
	pointer.  All callers adjusted.
	(bpstat_clear_actions): Use inferior_thread.
	(get_bpstat_thread): New.
	(bpstat_do_actions): Use it.
	(bpstat_check_breakpoint_conditions, bpstat_stop_status): Adjust
	to take a thread_info pointer.  All callers adjusted.
	(set_longjmp_breakpoint_for_call_dummy, set_momentary_breakpoint)
	(breakpoint_re_set_thread): Use inferior_thread.
	* breakpoint.h (struct inferior): Forward declare.
	(bpstat_stop_status): Update.
	(remove_breakpoints_pid): Delete.
	(remove_breakpoints_inf): New.
	* bsd-uthread.c (bsd_uthread_target::wait)
	(bsd_uthread_target::update_thread_list): Use find_thread_ptid.
	* btrace.c (btrace_add_pc, btrace_enable, btrace_fetch)
	(maint_btrace_packet_history_cmd)
	(maint_btrace_clear_packet_history_cmd): Adjust.
	(maint_btrace_clear_cmd, maint_info_btrace_cmd): Adjust to use
	inferior_thread.
	* cli/cli-interp.c: Include "inferior.h".
	* common/refcounted-object.h (struct
	refcounted_object_ref_policy): New.
	* compile/compile-object-load.c: Include gdbthread.h.
	(store_regs): Use inferior_thread.
	* corelow.c (core_target::close): Use current_inferior.
	(core_target_open): Adjust to use first_thread_of_inferior and use
	the current inferior.
	* ctf.c (ctf_target::close): Adjust to use current_inferior.
	* dummy-frame.c (dummy_frame_id) <ptid>: Delete, replaced by ...
	<thread>: ... this new field.  All references adjusted.
	(dummy_frame_pop, dummy_frame_discard, register_dummy_frame_dtor):
	Take a thread_info pointer instead of a ptid_t.
	* dummy-frame.h (dummy_frame_push, dummy_frame_pop)
	(dummy_frame_discard, register_dummy_frame_dtor): Take a
	thread_info pointer instead of a ptid_t.
	* elfread.c: Include "inferior.h".
	(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop):
	Use inferior_thread.
	* eval.c (evaluate_subexp): Likewise.
	* frame.c (frame_pop, has_stack_frames, find_frame_sal): Use
	inferior_thread.
	* gdb_proc_service.h (struct thread_info): Forward declare.
	(struct ps_prochandle) <ptid>: Delete, replaced by ...
	<thread>: ... this new field.  All references adjusted.
	* gdbarch.h, gdbarch.c: Regenerate.
	* gdbarch.sh (get_syscall_number): Replace 'ptid' parameter with a
	'thread' parameter.  All implementations and callers adjusted.
	* gdbthread.h (thread_info) <set_running>: New method.
	(delete_thread, delete_thread_silent): Take a thread_info pointer
	instead of a ptid.
	(global_thread_id_to_ptid, ptid_to_global_thread_id): Delete.
	(first_thread_of_process): Delete, replaced by ...
	(first_thread_of_inferior): ... this new function.  All callers
	adjusted.
	(any_live_thread_of_process): Delete, replaced by ...
	(any_live_thread_of_inferior): ... this new function.  All callers
	adjusted.
	(switch_to_thread, switch_to_no_thread): Declare.
	(is_executing): Delete.
	(enable_thread_stack_temporaries): Update comment.
	<enable_thread_stack_temporaries>: Take a thread_info pointer
	instead of a ptid_t.  Incref the thread.
	<~enable_thread_stack_temporaries>: Decref the thread.
	<m_ptid>: Delete
	<m_thr>: New.
	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
	(get_last_thread_stack_temporary)
	(value_in_thread_stack_temporaries, can_access_registers_thread):
	Take a thread_info pointer instead of a ptid_t.  All callers
	adjusted.
	* infcall.c (get_call_return_value): Use inferior_thread.
	(run_inferior_call): Work with thread pointers instead of ptid_t.
	(call_function_by_hand_dummy): Work with thread pointers instead
	of ptid_t.  Use thread_info_ref.
	* infcmd.c (proceed_thread_callback): Access thread's state
	directly.
	(ensure_valid_thread, ensure_not_running): Use inferior_thread,
	access thread's state directly.
	(continue_command): Use inferior_thread.
	(info_program_command): Use find_thread_ptid and access thread
	state directly.
	(proceed_after_attach_callback): Use thread state directly.
	(notice_new_inferior): Take a thread_info pointer instead of a
	ptid_t.  All callers adjusted.
	(exit_inferior): Take an inferior pointer instead of a pid.  All
	callers adjusted.
	(exit_inferior_silent): New.
	(detach_inferior): Delete.
	(valid_gdb_inferior_id, pid_to_gdb_inferior_id)
	(gdb_inferior_id_to_pid, in_inferior_list): Delete.
	(detach_inferior_command, kill_inferior_command): Use
	find_inferior_id instead of valid_gdb_inferior_id and
	gdb_inferior_id_to_pid.
	(inferior_command): Use inferior and thread pointers.
	* inferior.h (struct thread_info): Forward declare.
	(notice_new_inferior): Take a thread_info pointer instead of a
	ptid_t.  All callers adjusted.
	(detach_inferior): Delete declaration.
	(exit_inferior, exit_inferior_silent): Take an inferior pointer
	instead of a pid.  All callers adjusted.
	(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
	(valid_gdb_inferior_id): Delete.
	* infrun.c (follow_fork_inferior, proceed_after_vfork_done)
	(handle_vfork_child_exec_or_exit, follow_exec): Adjust.
	(struct displaced_step_inferior_state) <pid>: Delete, replaced by
	...
	<inf>: ... this new field.
	<step_ptid>: Delete, replaced by ...
	<step_thread>: ... this new field.
	(get_displaced_stepping_state): Take an inferior pointer instead
	of a pid.  All callers adjusted.
	(displaced_step_in_progress_any_inferior): Adjust.
	(displaced_step_in_progress_thread): Take a thread pointer instead
	of a ptid_t.  All callers adjusted.
	(displaced_step_in_progress, add_displaced_stepping_state): Take
	an inferior pointer instead of a pid.  All callers adjusted.
	(get_displaced_step_closure_by_addr): Adjust.
	(remove_displaced_stepping_state): Take an inferior pointer
	instead of a pid.  All callers adjusted.
	(displaced_step_prepare_throw, displaced_step_prepare)
	(displaced_step_fixup): Take a thread pointer instead of a ptid_t.
	All callers adjusted.
	(start_step_over): Adjust.
	(infrun_thread_ptid_changed): Remove bit updating ptids in the
	displaced step queue.
	(do_target_resume): Adjust.
	(fetch_inferior_event): Use inferior_thread.
	(context_switch, get_inferior_stop_soon): Take an
	execution_control_state pointer instead of a ptid_t.  All callers
	adjusted.
	(switch_to_thread_cleanup): Delete.
	(stop_all_threads): Use scoped_restore_current_thread.
	* inline-frame.c: Include "gdbthread.h".
	(inline_state) <inline_state>: Take a thread pointer instead of a
	ptid_t.  All callers adjusted.
	<ptid>: Delete, replaced by ...
	<thread>: ... this new field.
	(find_inline_frame_state): Take a thread pointer instead of a
	ptid_t.  All callers adjusted.
	(skip_inline_frames, step_into_inline_frame)
	(inline_skipped_frames, inline_skipped_symbol): Take a thread
	pointer instead of a ptid_t.  All callers adjusted.
	* inline-frame.h (skip_inline_frames, step_into_inline_frame)
	(inline_skipped_frames, inline_skipped_symbol): Likewise.
	* linux-fork.c (delete_checkpoint_command): Adjust to use thread
	pointers directly.
	* linux-nat.c (get_detach_signal): Likewise.
	* linux-thread-db.c (thread_from_lwp): New 'stopped' parameter.
	(thread_db_notice_clone): Adjust.
	(thread_db_find_new_threads_silently)
	(thread_db_find_new_threads_2, thread_db_find_new_threads_1): Take
	a thread pointer instead of a ptid_t.  All callers adjusted.
	* mi/mi-cmd-var.c: Include "inferior.h".
	(mi_cmd_var_update_iter): Update to use thread pointers.
	* mi/mi-interp.c (mi_new_thread): Update to use the thread's
	inferior directly.
	(mi_output_running_pid, mi_inferior_count): Delete, bits factored
	out to ...
	(mi_output_running): ... this new function.
	(mi_on_resume_1): Adjust to use it.
	(mi_user_selected_context_changed): Adjust to use inferior_thread.
	* mi/mi-main.c (proceed_thread): Adjust to use thread pointers
	directly.
	(interrupt_thread_callback): : Adjust to use thread and inferior
	pointers.
	* proc-service.c: Include "gdbthread.h".
	(ps_pglobal_lookup): Adjust to use the thread's inferior directly.
	* progspace-and-thread.c: Include "inferior.h".
	* progspace.c: Include "inferior.h".
	* python/py-exitedevent.c (create_exited_event_object): Adjust to
	hold a reference to an inferior_object.
	* python/py-finishbreakpoint.c (bpfinishpy_init): Adjust to use
	inferior_thread.
	* python/py-inferior.c (struct inferior_object): Give the type a
	tag name instead of a typedef.
	(python_on_normal_stop): No need to check if the current thread is
	listed.
	(inferior_to_inferior_object): Change return type to
	inferior_object.  All callers adjusted.
	(find_thread_object): Delete, bits factored out to ...
	(thread_to_thread_object): ... this new function.
	* python/py-infthread.c (create_thread_object): Use
	inferior_to_inferior_object.
	(thpy_is_stopped): Use thread pointer directly.
	(gdbpy_selected_thread): Use inferior_thread.
	* python/py-record-btrace.c (btpy_list_object) <ptid>: Delete
	field, replaced with ...
	<thread>: ... this new field.  All users adjusted.
	(btpy_insn_or_gap_new): Drop const.
	(btpy_list_new): Take a thread pointer instead of a ptid_t.  All
	callers adjusted.
	* python/py-record.c: Include "gdbthread.h".
	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
	a ptid_t.  All callers adjusted.
	(gdbpy_current_recording): Use inferior_thread.
	* python/py-record.h (recpy_record_object) <ptid>: Delete
	field, replaced with ...
	<thread>: ... this new field.  All users adjusted.
	(recpy_element_object) <ptid>: Delete
	field, replaced with ...
	<thread>: ... this new field.  All users adjusted.
	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
	a ptid_t.  All callers adjusted.
	* python/py-threadevent.c: Include "gdbthread.h".
	(get_event_thread): Use thread_to_thread_object.
	* python/python-internal.h (struct inferior_object): Forward
	declare.
	(find_thread_object, find_inferior_object): Delete declarations.
	(thread_to_thread_object, inferior_to_inferior_object): New
	declarations.
	* record-btrace.c: Include "inferior.h".
	(require_btrace_thread): Use inferior_thread.
	(record_btrace_frame_sniffer)
	(record_btrace_tailcall_frame_sniffer): Use inferior_thread.
	(get_thread_current_frame): Use scoped_restore_current_thread and
	switch_to_thread.
	(get_thread_current_frame): Use thread pointer directly.
	(record_btrace_replay_at_breakpoint): Use thread's inferior
	pointer directly.
	* record-full.c: Include "inferior.h".
	* regcache.c: Include "gdbthread.h".
	(get_thread_arch_regcache): Use the inferior's address space
	directly.
	(get_thread_regcache, registers_changed_thread): New.
	* regcache.h (get_thread_regcache(thread_info *thread)): New
	overload.
	(registers_changed_thread): New.
	(remote_target) <remote_detach_1>: Swap order of parameters.
	(remote_add_thread): <remote_add_thread>: Return the new thread.
	(get_remote_thread_info(ptid_t)): New overload.
	(remote_target::remote_notice_new_inferior): Use thread pointers
	directly.
	(remote_target::process_initial_stop_replies): Use
	thread_info::set_running.
	(remote_target::remote_detach_1, remote_target::detach)
	(extended_remote_target::detach): Adjust.
	* stack.c (frame_show_address): Use inferior_thread.
	* target-debug.h (target_debug_print_thread_info_pp): New.
	* target-delegates.c: Regenerate.
	* target.c (default_thread_address_space): Delete.
	(memory_xfer_partial_1): Use current_inferior.
	(target_detach): Use current_inferior.
	(target_thread_address_space): Delete.
	(generic_mourn_inferior): Use current_inferior.
	* target.h (struct target_ops) <thread_address_space>: Delete.
	(target_thread_address_space): Delete.
	* thread.c (init_thread_list): Use ALL_THREADS_SAFE.  Use thread
	pointers directly.
	(delete_thread_1, delete_thread, delete_thread_silent): Take a
	thread pointer instead of a ptid_t.  Adjust all callers.
	(ptid_to_global_thread_id, global_thread_id_to_ptid): Delete.
	(first_thread_of_process): Delete, replaced by ...
	(first_thread_of_inferior): ... this new function.  All callers
	adjusted.
	(any_thread_of_process): Rename to ...
	(any_thread_of_inferior): ... this, and take an inferior pointer.
	(any_live_thread_of_process): Rename to ...
	(any_live_thread_of_inferior): ... this, and take an inferior
	pointer.
	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
	(value_in_thread_stack_temporaries)
	(get_last_thread_stack_temporary): Take a thread pointer instead
	of a ptid_t.  Adjust all callers.
	(thread_info::set_running): New.
	(validate_registers_access): Use inferior_thread.
	(can_access_registers_ptid): Rename to ...
	(can_access_registers_thread): ... this, and take a thread
	pointer.
	(print_thread_info_1): Adjust to compare thread pointers instead
	of ptids.
	(switch_to_no_thread, switch_to_thread): Make extern.
	(scoped_restore_current_thread::~scoped_restore_current_thread):
	Use m_thread pointer directly.
	(scoped_restore_current_thread::scoped_restore_current_thread):
	Use inferior_thread.
	(thread_command): Use thread pointer directly.
	(thread_num_make_value_helper): Use inferior_thread.
	* top.c (execute_command): Use inferior_thread.
	* tui/tui-interp.c: Include "inferior.h".
	* varobj.c (varobj_create): Use inferior_thread.
	(value_of_root_1): Use find_thread_global_id instead of
	global_thread_id_to_ptid.
This commit is contained in:
Pedro Alves 2018-06-21 17:09:31 +01:00
parent 33bab475a6
commit 00431a78b2
71 changed files with 1198 additions and 993 deletions

View file

@ -1,3 +1,299 @@
2018-06-21 Pedro Alves <palves@redhat.com>
* ada-lang.h (ada_get_task_number): Take a thread_info pointer
instead of a ptid_t. All callers adjusted.
* ada-tasks.c (ada_get_task_number): Likewise. All callers
adjusted.
(print_ada_task_info, display_current_task_id, task_command_1):
Adjust.
* breakpoint.c (watchpoint_in_thread_scope): Adjust to use
inferior_thread.
(breakpoint_kind): Adjust.
(remove_breakpoints_pid): Rename to ...
(remove_breakpoints_inf): ... this. Adjust to take an inferior
pointer. All callers adjusted.
(bpstat_clear_actions): Use inferior_thread.
(get_bpstat_thread): New.
(bpstat_do_actions): Use it.
(bpstat_check_breakpoint_conditions, bpstat_stop_status): Adjust
to take a thread_info pointer. All callers adjusted.
(set_longjmp_breakpoint_for_call_dummy, set_momentary_breakpoint)
(breakpoint_re_set_thread): Use inferior_thread.
* breakpoint.h (struct inferior): Forward declare.
(bpstat_stop_status): Update.
(remove_breakpoints_pid): Delete.
(remove_breakpoints_inf): New.
* bsd-uthread.c (bsd_uthread_target::wait)
(bsd_uthread_target::update_thread_list): Use find_thread_ptid.
* btrace.c (btrace_add_pc, btrace_enable, btrace_fetch)
(maint_btrace_packet_history_cmd)
(maint_btrace_clear_packet_history_cmd): Adjust.
(maint_btrace_clear_cmd, maint_info_btrace_cmd): Adjust to use
inferior_thread.
* cli/cli-interp.c: Include "inferior.h".
* common/refcounted-object.h (struct
refcounted_object_ref_policy): New.
* compile/compile-object-load.c: Include gdbthread.h.
(store_regs): Use inferior_thread.
* corelow.c (core_target::close): Use current_inferior.
(core_target_open): Adjust to use first_thread_of_inferior and use
the current inferior.
* ctf.c (ctf_target::close): Adjust to use current_inferior.
* dummy-frame.c (dummy_frame_id) <ptid>: Delete, replaced by ...
<thread>: ... this new field. All references adjusted.
(dummy_frame_pop, dummy_frame_discard, register_dummy_frame_dtor):
Take a thread_info pointer instead of a ptid_t.
* dummy-frame.h (dummy_frame_push, dummy_frame_pop)
(dummy_frame_discard, register_dummy_frame_dtor): Take a
thread_info pointer instead of a ptid_t.
* elfread.c: Include "inferior.h".
(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop):
Use inferior_thread.
* eval.c (evaluate_subexp): Likewise.
* frame.c (frame_pop, has_stack_frames, find_frame_sal): Use
inferior_thread.
* gdb_proc_service.h (struct thread_info): Forward declare.
(struct ps_prochandle) <ptid>: Delete, replaced by ...
<thread>: ... this new field. All references adjusted.
* gdbarch.h, gdbarch.c: Regenerate.
* gdbarch.sh (get_syscall_number): Replace 'ptid' parameter with a
'thread' parameter. All implementations and callers adjusted.
* gdbthread.h (thread_info) <set_running>: New method.
(delete_thread, delete_thread_silent): Take a thread_info pointer
instead of a ptid.
(global_thread_id_to_ptid, ptid_to_global_thread_id): Delete.
(first_thread_of_process): Delete, replaced by ...
(first_thread_of_inferior): ... this new function. All callers
adjusted.
(any_live_thread_of_process): Delete, replaced by ...
(any_live_thread_of_inferior): ... this new function. All callers
adjusted.
(switch_to_thread, switch_to_no_thread): Declare.
(is_executing): Delete.
(enable_thread_stack_temporaries): Update comment.
<enable_thread_stack_temporaries>: Take a thread_info pointer
instead of a ptid_t. Incref the thread.
<~enable_thread_stack_temporaries>: Decref the thread.
<m_ptid>: Delete
<m_thr>: New.
(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
(get_last_thread_stack_temporary)
(value_in_thread_stack_temporaries, can_access_registers_thread):
Take a thread_info pointer instead of a ptid_t. All callers
adjusted.
* infcall.c (get_call_return_value): Use inferior_thread.
(run_inferior_call): Work with thread pointers instead of ptid_t.
(call_function_by_hand_dummy): Work with thread pointers instead
of ptid_t. Use thread_info_ref.
* infcmd.c (proceed_thread_callback): Access thread's state
directly.
(ensure_valid_thread, ensure_not_running): Use inferior_thread,
access thread's state directly.
(continue_command): Use inferior_thread.
(info_program_command): Use find_thread_ptid and access thread
state directly.
(proceed_after_attach_callback): Use thread state directly.
(notice_new_inferior): Take a thread_info pointer instead of a
ptid_t. All callers adjusted.
(exit_inferior): Take an inferior pointer instead of a pid. All
callers adjusted.
(exit_inferior_silent): New.
(detach_inferior): Delete.
(valid_gdb_inferior_id, pid_to_gdb_inferior_id)
(gdb_inferior_id_to_pid, in_inferior_list): Delete.
(detach_inferior_command, kill_inferior_command): Use
find_inferior_id instead of valid_gdb_inferior_id and
gdb_inferior_id_to_pid.
(inferior_command): Use inferior and thread pointers.
* inferior.h (struct thread_info): Forward declare.
(notice_new_inferior): Take a thread_info pointer instead of a
ptid_t. All callers adjusted.
(detach_inferior): Delete declaration.
(exit_inferior, exit_inferior_silent): Take an inferior pointer
instead of a pid. All callers adjusted.
(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
(valid_gdb_inferior_id): Delete.
* infrun.c (follow_fork_inferior, proceed_after_vfork_done)
(handle_vfork_child_exec_or_exit, follow_exec): Adjust.
(struct displaced_step_inferior_state) <pid>: Delete, replaced by
...
<inf>: ... this new field.
<step_ptid>: Delete, replaced by ...
<step_thread>: ... this new field.
(get_displaced_stepping_state): Take an inferior pointer instead
of a pid. All callers adjusted.
(displaced_step_in_progress_any_inferior): Adjust.
(displaced_step_in_progress_thread): Take a thread pointer instead
of a ptid_t. All callers adjusted.
(displaced_step_in_progress, add_displaced_stepping_state): Take
an inferior pointer instead of a pid. All callers adjusted.
(get_displaced_step_closure_by_addr): Adjust.
(remove_displaced_stepping_state): Take an inferior pointer
instead of a pid. All callers adjusted.
(displaced_step_prepare_throw, displaced_step_prepare)
(displaced_step_fixup): Take a thread pointer instead of a ptid_t.
All callers adjusted.
(start_step_over): Adjust.
(infrun_thread_ptid_changed): Remove bit updating ptids in the
displaced step queue.
(do_target_resume): Adjust.
(fetch_inferior_event): Use inferior_thread.
(context_switch, get_inferior_stop_soon): Take an
execution_control_state pointer instead of a ptid_t. All callers
adjusted.
(switch_to_thread_cleanup): Delete.
(stop_all_threads): Use scoped_restore_current_thread.
* inline-frame.c: Include "gdbthread.h".
(inline_state) <inline_state>: Take a thread pointer instead of a
ptid_t. All callers adjusted.
<ptid>: Delete, replaced by ...
<thread>: ... this new field.
(find_inline_frame_state): Take a thread pointer instead of a
ptid_t. All callers adjusted.
(skip_inline_frames, step_into_inline_frame)
(inline_skipped_frames, inline_skipped_symbol): Take a thread
pointer instead of a ptid_t. All callers adjusted.
* inline-frame.h (skip_inline_frames, step_into_inline_frame)
(inline_skipped_frames, inline_skipped_symbol): Likewise.
* linux-fork.c (delete_checkpoint_command): Adjust to use thread
pointers directly.
* linux-nat.c (get_detach_signal): Likewise.
* linux-thread-db.c (thread_from_lwp): New 'stopped' parameter.
(thread_db_notice_clone): Adjust.
(thread_db_find_new_threads_silently)
(thread_db_find_new_threads_2, thread_db_find_new_threads_1): Take
a thread pointer instead of a ptid_t. All callers adjusted.
* mi/mi-cmd-var.c: Include "inferior.h".
(mi_cmd_var_update_iter): Update to use thread pointers.
* mi/mi-interp.c (mi_new_thread): Update to use the thread's
inferior directly.
(mi_output_running_pid, mi_inferior_count): Delete, bits factored
out to ...
(mi_output_running): ... this new function.
(mi_on_resume_1): Adjust to use it.
(mi_user_selected_context_changed): Adjust to use inferior_thread.
* mi/mi-main.c (proceed_thread): Adjust to use thread pointers
directly.
(interrupt_thread_callback): : Adjust to use thread and inferior
pointers.
* proc-service.c: Include "gdbthread.h".
(ps_pglobal_lookup): Adjust to use the thread's inferior directly.
* progspace-and-thread.c: Include "inferior.h".
* progspace.c: Include "inferior.h".
* python/py-exitedevent.c (create_exited_event_object): Adjust to
hold a reference to an inferior_object.
* python/py-finishbreakpoint.c (bpfinishpy_init): Adjust to use
inferior_thread.
* python/py-inferior.c (struct inferior_object): Give the type a
tag name instead of a typedef.
(python_on_normal_stop): No need to check if the current thread is
listed.
(inferior_to_inferior_object): Change return type to
inferior_object. All callers adjusted.
(find_thread_object): Delete, bits factored out to ...
(thread_to_thread_object): ... this new function.
* python/py-infthread.c (create_thread_object): Use
inferior_to_inferior_object.
(thpy_is_stopped): Use thread pointer directly.
(gdbpy_selected_thread): Use inferior_thread.
* python/py-record-btrace.c (btpy_list_object) <ptid>: Delete
field, replaced with ...
<thread>: ... this new field. All users adjusted.
(btpy_insn_or_gap_new): Drop const.
(btpy_list_new): Take a thread pointer instead of a ptid_t. All
callers adjusted.
* python/py-record.c: Include "gdbthread.h".
(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
a ptid_t. All callers adjusted.
(gdbpy_current_recording): Use inferior_thread.
* python/py-record.h (recpy_record_object) <ptid>: Delete
field, replaced with ...
<thread>: ... this new field. All users adjusted.
(recpy_element_object) <ptid>: Delete
field, replaced with ...
<thread>: ... this new field. All users adjusted.
(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
a ptid_t. All callers adjusted.
* python/py-threadevent.c: Include "gdbthread.h".
(get_event_thread): Use thread_to_thread_object.
* python/python-internal.h (struct inferior_object): Forward
declare.
(find_thread_object, find_inferior_object): Delete declarations.
(thread_to_thread_object, inferior_to_inferior_object): New
declarations.
* record-btrace.c: Include "inferior.h".
(require_btrace_thread): Use inferior_thread.
(record_btrace_frame_sniffer)
(record_btrace_tailcall_frame_sniffer): Use inferior_thread.
(get_thread_current_frame): Use scoped_restore_current_thread and
switch_to_thread.
(get_thread_current_frame): Use thread pointer directly.
(record_btrace_replay_at_breakpoint): Use thread's inferior
pointer directly.
* record-full.c: Include "inferior.h".
* regcache.c: Include "gdbthread.h".
(get_thread_arch_regcache): Use the inferior's address space
directly.
(get_thread_regcache, registers_changed_thread): New.
* regcache.h (get_thread_regcache(thread_info *thread)): New
overload.
(registers_changed_thread): New.
(remote_target) <remote_detach_1>: Swap order of parameters.
(remote_add_thread): <remote_add_thread>: Return the new thread.
(get_remote_thread_info(ptid_t)): New overload.
(remote_target::remote_notice_new_inferior): Use thread pointers
directly.
(remote_target::process_initial_stop_replies): Use
thread_info::set_running.
(remote_target::remote_detach_1, remote_target::detach)
(extended_remote_target::detach): Adjust.
* stack.c (frame_show_address): Use inferior_thread.
* target-debug.h (target_debug_print_thread_info_pp): New.
* target-delegates.c: Regenerate.
* target.c (default_thread_address_space): Delete.
(memory_xfer_partial_1): Use current_inferior.
(target_detach): Use current_inferior.
(target_thread_address_space): Delete.
(generic_mourn_inferior): Use current_inferior.
* target.h (struct target_ops) <thread_address_space>: Delete.
(target_thread_address_space): Delete.
* thread.c (init_thread_list): Use ALL_THREADS_SAFE. Use thread
pointers directly.
(delete_thread_1, delete_thread, delete_thread_silent): Take a
thread pointer instead of a ptid_t. Adjust all callers.
(ptid_to_global_thread_id, global_thread_id_to_ptid): Delete.
(first_thread_of_process): Delete, replaced by ...
(first_thread_of_inferior): ... this new function. All callers
adjusted.
(any_thread_of_process): Rename to ...
(any_thread_of_inferior): ... this, and take an inferior pointer.
(any_live_thread_of_process): Rename to ...
(any_live_thread_of_inferior): ... this, and take an inferior
pointer.
(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
(value_in_thread_stack_temporaries)
(get_last_thread_stack_temporary): Take a thread pointer instead
of a ptid_t. Adjust all callers.
(thread_info::set_running): New.
(validate_registers_access): Use inferior_thread.
(can_access_registers_ptid): Rename to ...
(can_access_registers_thread): ... this, and take a thread
pointer.
(print_thread_info_1): Adjust to compare thread pointers instead
of ptids.
(switch_to_no_thread, switch_to_thread): Make extern.
(scoped_restore_current_thread::~scoped_restore_current_thread):
Use m_thread pointer directly.
(scoped_restore_current_thread::scoped_restore_current_thread):
Use inferior_thread.
(thread_command): Use thread pointer directly.
(thread_num_make_value_helper): Use inferior_thread.
* top.c (execute_command): Use inferior_thread.
* tui/tui-interp.c: Include "inferior.h".
* varobj.c (varobj_create): Use inferior_thread.
(value_of_root_1): Use find_thread_global_id instead of
global_thread_id_to_ptid.
2018-06-21 Alan Hayward <alan.hayward@arm.com> 2018-06-21 Alan Hayward <alan.hayward@arm.com>
* regcache.c (readable_regcache::read_part): Avoid memcpy when * regcache.c (readable_regcache::read_part): Avoid memcpy when

View file

@ -366,9 +366,9 @@ aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
static LONGEST static LONGEST
aarch64_linux_get_syscall_number (struct gdbarch *gdbarch, aarch64_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regs = get_thread_regcache (ptid); struct regcache *regs = get_thread_regcache (thread);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The content of register x8. */ /* The content of register x8. */

View file

@ -401,7 +401,7 @@ extern int valid_task_id (int);
extern struct ada_task_info *ada_get_task_info_from_ptid (ptid_t ptid); extern struct ada_task_info *ada_get_task_info_from_ptid (ptid_t ptid);
extern int ada_get_task_number (ptid_t); extern int ada_get_task_number (thread_info *thread);
typedef void (ada_task_list_iterator_ftype) (struct ada_task_info *task); typedef void (ada_task_list_iterator_ftype) (struct ada_task_info *task);
extern void iterate_over_live_ada_tasks extern void iterate_over_live_ada_tasks

View file

@ -288,14 +288,14 @@ get_ada_tasks_inferior_data (struct inferior *inf)
return data; return data;
} }
/* Return the task number of the task whose ptid is PTID, or zero /* Return the task number of the task whose thread is THREAD, or zero
if the task could not be found. */ if the task could not be found. */
int int
ada_get_task_number (ptid_t ptid) ada_get_task_number (thread_info *thread)
{ {
int i; int i;
struct inferior *inf = find_inferior_ptid (ptid); struct inferior *inf = thread->inf;
struct ada_tasks_inferior_data *data; struct ada_tasks_inferior_data *data;
gdb_assert (inf != NULL); gdb_assert (inf != NULL);
@ -303,7 +303,7 @@ ada_get_task_number (ptid_t ptid)
for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++) for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
if (ptid_equal (VEC_index (ada_task_info_s, data->task_list, i)->ptid, if (ptid_equal (VEC_index (ada_task_info_s, data->task_list, i)->ptid,
ptid)) thread->ptid))
return i + 1; return i + 1;
return 0; /* No matching task found. */ return 0; /* No matching task found. */
@ -1125,10 +1125,10 @@ print_ada_task_info (struct ui_out *uiout,
/* Print the associated Thread ID. */ /* Print the associated Thread ID. */
if (uiout->is_mi_like_p ()) if (uiout->is_mi_like_p ())
{ {
const int thread_id = ptid_to_global_thread_id (task_info->ptid); thread_info *thread = find_thread_ptid (task_info->ptid);
if (thread_id != 0) if (thread != NULL)
uiout->field_int ("thread-id", thread_id); uiout->field_int ("thread-id", thread->global_num);
else else
/* This should never happen unless there is a bug somewhere, /* This should never happen unless there is a bug somewhere,
but be resilient when that happens. */ but be resilient when that happens. */
@ -1284,7 +1284,7 @@ info_tasks_command (const char *arg, int from_tty)
static void static void
display_current_task_id (void) display_current_task_id (void)
{ {
const int current_task = ada_get_task_number (inferior_ptid); const int current_task = ada_get_task_number (inferior_thread ());
if (current_task == 0) if (current_task == 0)
printf_filtered (_("[Current task is unknown]\n")); printf_filtered (_("[Current task is unknown]\n"));
@ -1327,12 +1327,13 @@ task_command_1 (const char *taskno_str, int from_tty, struct inferior *inf)
computed if target_get_ada_task_ptid has not been implemented for computed if target_get_ada_task_ptid has not been implemented for
our target (yet). Rather than cause an assertion error in that case, our target (yet). Rather than cause an assertion error in that case,
it's nicer for the user to just refuse to perform the task switch. */ it's nicer for the user to just refuse to perform the task switch. */
if (!find_thread_ptid (task_info->ptid)) thread_info *tp = find_thread_ptid (task_info->ptid);
if (tp == NULL)
error (_("Unable to compute thread ID for task %d.\n" error (_("Unable to compute thread ID for task %d.\n"
"Cannot switch to this task."), "Cannot switch to this task."),
taskno); taskno);
switch_to_thread (task_info->ptid); switch_to_thread (tp);
ada_find_printable_frame (get_selected_frame (NULL)); ada_find_printable_frame (get_selected_frame (NULL));
printf_filtered (_("[Switching to task %d]\n"), taskno); printf_filtered (_("[Switching to task %d]\n"), taskno);
print_stack_frame (get_selected_frame (NULL), print_stack_frame (get_selected_frame (NULL),

View file

@ -222,9 +222,9 @@ amd64_linux_sigcontext_addr (struct frame_info *this_frame)
static LONGEST static LONGEST
amd64_linux_get_syscall_number (struct gdbarch *gdbarch, amd64_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The content of a register. */ /* The content of a register. */
gdb_byte buf[8]; gdb_byte buf[8];

View file

@ -819,9 +819,9 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache,
static LONGEST static LONGEST
arm_linux_get_syscall_number (struct gdbarch *gdbarch, arm_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regs = get_thread_regcache (ptid); struct regcache *regs = get_thread_regcache (thread);
ULONGEST pc; ULONGEST pc;
ULONGEST cpsr; ULONGEST cpsr;

View file

@ -128,9 +128,9 @@ static const struct tramp_frame bfin_linux_sigframe =
static LONGEST static LONGEST
bfin_linux_get_syscall_number (struct gdbarch *gdbarch, bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The content of a register. */ /* The content of a register. */
gdb_byte buf[4]; gdb_byte buf[4];

View file

@ -1548,7 +1548,7 @@ watchpoint_in_thread_scope (struct watchpoint *b)
return (b->pspace == current_program_space return (b->pspace == current_program_space
&& (ptid_equal (b->watchpoint_thread, null_ptid) && (ptid_equal (b->watchpoint_thread, null_ptid)
|| (ptid_equal (inferior_ptid, b->watchpoint_thread) || (ptid_equal (inferior_ptid, b->watchpoint_thread)
&& !is_executing (inferior_ptid)))); && !inferior_thread ()->executing)));
} }
/* Set watchpoint B to disp_del_at_next_stop, even including its possible /* Set watchpoint B to disp_del_at_next_stop, even including its possible
@ -2408,7 +2408,7 @@ breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
struct thread_info *thr = find_thread_global_id (bl->owner->thread); struct thread_info *thr = find_thread_global_id (bl->owner->thread);
struct regcache *regcache; struct regcache *regcache;
regcache = get_thread_regcache (thr->ptid); regcache = get_thread_regcache (thr);
return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch, return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
regcache, addr); regcache, addr);
@ -3061,14 +3061,13 @@ Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\
} }
} }
/* Remove breakpoints of process PID. */ /* Remove breakpoints of inferior INF. */
int int
remove_breakpoints_pid (int pid) remove_breakpoints_inf (inferior *inf)
{ {
struct bp_location *bl, **blp_tmp; struct bp_location *bl, **blp_tmp;
int val; int val;
struct inferior *inf = find_inferior_pid (pid);
ALL_BP_LOCATIONS (bl, blp_tmp) ALL_BP_LOCATIONS (bl, blp_tmp)
{ {
@ -4329,16 +4328,12 @@ bpstat_num (bpstat *bsp, int *num)
void void
bpstat_clear_actions (void) bpstat_clear_actions (void)
{ {
struct thread_info *tp;
bpstat bs; bpstat bs;
if (ptid_equal (inferior_ptid, null_ptid)) if (inferior_ptid == null_ptid)
return;
tp = find_thread_ptid (inferior_ptid);
if (tp == NULL)
return; return;
thread_info *tp = inferior_thread ();
for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next) for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{ {
bs->commands = NULL; bs->commands = NULL;
@ -4466,22 +4461,37 @@ bpstat_do_actions_1 (bpstat *bsp)
return again; return again;
} }
/* Helper for bpstat_do_actions. Get the current thread, if there's
one, is alive and has execution. Return NULL otherwise. */
static thread_info *
get_bpstat_thread ()
{
if (inferior_ptid == null_ptid || !target_has_execution)
return NULL;
thread_info *tp = inferior_thread ();
if (tp->state == THREAD_EXITED || tp->executing)
return NULL;
return tp;
}
void void
bpstat_do_actions (void) bpstat_do_actions (void)
{ {
struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup (); struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
thread_info *tp;
/* Do any commands attached to breakpoint we are stopped at. */ /* Do any commands attached to breakpoint we are stopped at. */
while (!ptid_equal (inferior_ptid, null_ptid) while ((tp = get_bpstat_thread ()) != NULL)
&& target_has_execution {
&& !is_exited (inferior_ptid) /* Since in sync mode, bpstat_do_actions may resume the
&& !is_executing (inferior_ptid)) inferior, and only return when it is stopped at the next
/* Since in sync mode, bpstat_do_actions may resume the inferior, breakpoint, we keep doing breakpoint actions until it returns
and only return when it is stopped at the next breakpoint, we false to indicate the inferior was not resumed. */
keep doing breakpoint actions until it returns false to if (!bpstat_do_actions_1 (&tp->control.stop_bpstat))
indicate the inferior was not resumed. */ break;
if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat)) }
break;
discard_cleanups (cleanup_if_error); discard_cleanups (cleanup_if_error);
} }
@ -5154,7 +5164,7 @@ bpstat_check_watchpoint (bpstat bs)
breakpoint, set BS->stop to 0. */ breakpoint, set BS->stop to 0. */
static void static void
bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
{ {
const struct bp_location *bl; const struct bp_location *bl;
struct breakpoint *b; struct breakpoint *b;
@ -5184,9 +5194,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
/* If this is a thread/task-specific breakpoint, don't waste cpu /* If this is a thread/task-specific breakpoint, don't waste cpu
evaluating the condition if this isn't the specified evaluating the condition if this isn't the specified
thread/task. */ thread/task. */
if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid)) if ((b->thread != -1 && b->thread != thread->global_num)
|| (b->task != 0 && b->task != ada_get_task_number (ptid))) || (b->task != 0 && b->task != ada_get_task_number (thread)))
{ {
bs->stop = 0; bs->stop = 0;
return; return;
@ -5387,7 +5396,7 @@ build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
bpstat bpstat
bpstat_stop_status (const address_space *aspace, bpstat_stop_status (const address_space *aspace,
CORE_ADDR bp_addr, ptid_t ptid, CORE_ADDR bp_addr, thread_info *thread,
const struct target_waitstatus *ws, const struct target_waitstatus *ws,
bpstat stop_chain) bpstat stop_chain)
{ {
@ -5435,7 +5444,7 @@ bpstat_stop_status (const address_space *aspace,
b->ops->check_status (bs); b->ops->check_status (bs);
if (bs->stop) if (bs->stop)
{ {
bpstat_check_breakpoint_conditions (bs, ptid); bpstat_check_breakpoint_conditions (bs, thread);
if (bs->stop) if (bs->stop)
{ {
@ -7316,7 +7325,7 @@ set_longjmp_breakpoint_for_call_dummy (void)
new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy, new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
&momentary_breakpoint_ops, &momentary_breakpoint_ops,
1); 1);
new_b->thread = ptid_to_global_thread_id (inferior_ptid); new_b->thread = inferior_thread ()->global_num;
/* Link NEW_B into the chain of RETVAL breakpoints. */ /* Link NEW_B into the chain of RETVAL breakpoints. */
@ -7356,7 +7365,7 @@ check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
|| frame_find_by_id (dummy_b->frame_id) != NULL) || frame_find_by_id (dummy_b->frame_id) != NULL)
continue; continue;
dummy_frame_discard (dummy_b->frame_id, tp->ptid); dummy_frame_discard (dummy_b->frame_id, tp);
while (b->related_breakpoint != b) while (b->related_breakpoint != b)
{ {
@ -8497,11 +8506,7 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
b->disposition = disp_donttouch; b->disposition = disp_donttouch;
b->frame_id = frame_id; b->frame_id = frame_id;
/* If we're debugging a multi-threaded program, then we want b->thread = inferior_thread ()->global_num;
momentary breakpoints to be active in only a single thread of
control. */
if (in_thread_list (inferior_ptid))
b->thread = ptid_to_global_thread_id (inferior_ptid);
update_global_location_list_nothrow (UGLL_MAY_INSERT); update_global_location_list_nothrow (UGLL_MAY_INSERT);
@ -13923,8 +13928,7 @@ breakpoint_re_set_thread (struct breakpoint *b)
{ {
if (b->thread != -1) if (b->thread != -1)
{ {
if (in_thread_list (inferior_ptid)) b->thread = inferior_thread ()->global_num;
b->thread = ptid_to_global_thread_id (inferior_ptid);
/* We're being called after following a fork. The new fork is /* We're being called after following a fork. The new fork is
selected as current, and unless this was a vfork will have a selected as current, and unless this was a vfork will have a

View file

@ -40,6 +40,7 @@ struct bpstats;
struct bp_location; struct bp_location;
struct linespec_result; struct linespec_result;
struct linespec_sals; struct linespec_sals;
struct inferior;
/* Why are we removing the breakpoint from the target? */ /* Why are we removing the breakpoint from the target? */
@ -948,7 +949,7 @@ extern bpstat build_bpstat_chain (const address_space *aspace,
commands, FIXME??? fields. */ commands, FIXME??? fields. */
extern bpstat bpstat_stop_status (const address_space *aspace, extern bpstat bpstat_stop_status (const address_space *aspace,
CORE_ADDR pc, ptid_t ptid, CORE_ADDR pc, thread_info *thread,
const struct target_waitstatus *ws, const struct target_waitstatus *ws,
bpstat stop_chain = NULL); bpstat stop_chain = NULL);
@ -1396,7 +1397,7 @@ extern void insert_breakpoints (void);
extern int remove_breakpoints (void); extern int remove_breakpoints (void);
extern int remove_breakpoints_pid (int pid); extern int remove_breakpoints_inf (inferior *inf);
/* This function can be used to update the breakpoint package's state /* This function can be used to update the breakpoint package's state
after an exec() system call has been executed. after an exec() system call has been executed.

View file

@ -419,7 +419,8 @@ bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
thread_change_ptid (inferior_ptid, ptid); thread_change_ptid (inferior_ptid, ptid);
/* Don't let the core see a ptid without a corresponding thread. */ /* Don't let the core see a ptid without a corresponding thread. */
if (!in_thread_list (ptid) || is_exited (ptid)) thread_info *thread = find_thread_ptid (ptid);
if (thread == NULL || thread->state == THREAD_EXITED)
add_thread (ptid); add_thread (ptid);
return ptid; return ptid;
@ -467,7 +468,8 @@ bsd_uthread_target::update_thread_list ()
{ {
ptid_t ptid = ptid_build (pid, 0, addr); ptid_t ptid = ptid_build (pid, 0, addr);
if (!in_thread_list (ptid) || is_exited (ptid)) thread_info *thread = find_thread_ptid (ptid);
if (thread == nullptr || thread->state == THREAD_EXITED)
{ {
/* If INFERIOR_PTID doesn't have a tid member yet, then ptid /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
is still the initial thread of the process. Notify GDB is still the initial thread of the process. Notify GDB

View file

@ -1567,7 +1567,7 @@ btrace_add_pc (struct thread_info *tp)
struct regcache *regcache; struct regcache *regcache;
CORE_ADDR pc; CORE_ADDR pc;
regcache = get_thread_regcache (tp->ptid); regcache = get_thread_regcache (tp);
pc = regcache_read_pc (regcache); pc = regcache_read_pc (regcache);
btrace.format = BTRACE_FORMAT_BTS; btrace.format = BTRACE_FORMAT_BTS;
@ -1615,7 +1615,7 @@ btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
This is not relevant for BTRACE_FORMAT_PT since the trace will already This is not relevant for BTRACE_FORMAT_PT since the trace will already
start at the PC at which tracing was enabled. */ start at the PC at which tracing was enabled. */
if (conf->format != BTRACE_FORMAT_PT if (conf->format != BTRACE_FORMAT_PT
&& can_access_registers_ptid (tp->ptid)) && can_access_registers_thread (tp))
btrace_add_pc (tp); btrace_add_pc (tp);
} }
CATCH (exception, RETURN_MASK_ALL) CATCH (exception, RETURN_MASK_ALL)
@ -1911,7 +1911,7 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
inferior_ptid = tp->ptid; inferior_ptid = tp->ptid;
/* We should not be called on running or exited threads. */ /* We should not be called on running or exited threads. */
gdb_assert (can_access_registers_ptid (tp->ptid)); gdb_assert (can_access_registers_thread (tp));
/* Let's first try to extend the trace we already have. */ /* Let's first try to extend the trace we already have. */
if (!btinfo->functions.empty ()) if (!btinfo->functions.empty ())
@ -3231,10 +3231,9 @@ static void
maint_btrace_packet_history_cmd (const char *arg, int from_tty) maint_btrace_packet_history_cmd (const char *arg, int from_tty)
{ {
struct btrace_thread_info *btinfo; struct btrace_thread_info *btinfo;
struct thread_info *tp;
unsigned int size, begin, end, from, to; unsigned int size, begin, end, from, to;
tp = find_thread_ptid (inferior_ptid); thread_info *tp = find_thread_ptid (inferior_ptid);
if (tp == NULL) if (tp == NULL)
error (_("No thread.")); error (_("No thread."));
@ -3335,17 +3334,14 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
static void static void
maint_btrace_clear_packet_history_cmd (const char *args, int from_tty) maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
{ {
struct btrace_thread_info *btinfo;
struct thread_info *tp;
if (args != NULL && *args != 0) if (args != NULL && *args != 0)
error (_("Invalid argument.")); error (_("Invalid argument."));
tp = find_thread_ptid (inferior_ptid); if (inferior_ptid == null_ptid)
if (tp == NULL)
error (_("No thread.")); error (_("No thread."));
btinfo = &tp->btrace; thread_info *tp = inferior_thread ();
btrace_thread_info *btinfo = &tp->btrace;
/* Must clear the maint data before - it depends on BTINFO->DATA. */ /* Must clear the maint data before - it depends on BTINFO->DATA. */
btrace_maint_clear (btinfo); btrace_maint_clear (btinfo);
@ -3357,15 +3353,13 @@ maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
static void static void
maint_btrace_clear_cmd (const char *args, int from_tty) maint_btrace_clear_cmd (const char *args, int from_tty)
{ {
struct thread_info *tp;
if (args != NULL && *args != 0) if (args != NULL && *args != 0)
error (_("Invalid argument.")); error (_("Invalid argument."));
tp = find_thread_ptid (inferior_ptid); if (inferior_ptid == null_ptid)
if (tp == NULL)
error (_("No thread.")); error (_("No thread."));
thread_info *tp = inferior_thread ();
btrace_clear (tp); btrace_clear (tp);
} }
@ -3420,16 +3414,16 @@ static void
maint_info_btrace_cmd (const char *args, int from_tty) maint_info_btrace_cmd (const char *args, int from_tty)
{ {
struct btrace_thread_info *btinfo; struct btrace_thread_info *btinfo;
struct thread_info *tp;
const struct btrace_config *conf; const struct btrace_config *conf;
if (args != NULL && *args != 0) if (args != NULL && *args != 0)
error (_("Invalid argument.")); error (_("Invalid argument."));
tp = find_thread_ptid (inferior_ptid); if (inferior_ptid == null_ptid)
if (tp == NULL)
error (_("No thread.")); error (_("No thread."));
thread_info *tp = inferior_thread ();
btinfo = &tp->btrace; btinfo = &tp->btrace;
conf = btrace_conf (btinfo); conf = btrace_conf (btinfo);

View file

@ -29,6 +29,7 @@
#include "observable.h" #include "observable.h"
#include "gdbthread.h" #include "gdbthread.h"
#include "thread-fsm.h" #include "thread-fsm.h"
#include "inferior.h"
cli_interp_base::cli_interp_base (const char *name) cli_interp_base::cli_interp_base (const char *name)
: interp (name) : interp (name)

View file

@ -51,4 +51,20 @@ private:
int m_refcount = 0; int m_refcount = 0;
}; };
/* A policy class to interface gdb::ref_ptr with a
refcounted_object. */
struct refcounted_object_ref_policy
{
static void incref (refcounted_object *ptr)
{
ptr->incref ();
}
static void decref (refcounted_object *ptr)
{
ptr->decref ();
}
};
#endif /* REFCOUNTED_OBJECT_H */ #endif /* REFCOUNTED_OBJECT_H */

View file

@ -28,6 +28,7 @@
#include "gdbcmd.h" #include "gdbcmd.h"
#include "regcache.h" #include "regcache.h"
#include "inferior.h" #include "inferior.h"
#include "gdbthread.h"
#include "compile.h" #include "compile.h"
#include "block.h" #include "block.h"
#include "arch-utils.h" #include "arch-utils.h"
@ -554,8 +555,9 @@ get_regs_type (struct symbol *func_sym, struct objfile *objfile)
static void static void
store_regs (struct type *regs_type, CORE_ADDR regs_base) store_regs (struct type *regs_type, CORE_ADDR regs_base)
{ {
thread_info *thread = inferior_thread ();
struct gdbarch *gdbarch = target_gdbarch (); struct gdbarch *gdbarch = target_gdbarch ();
struct regcache *regcache = get_thread_regcache (inferior_ptid); struct regcache *regcache = get_thread_regcache (thread);
int fieldno; int fieldno;
for (fieldno = 0; fieldno < TYPE_NFIELDS (regs_type); fieldno++) for (fieldno = 0; fieldno < TYPE_NFIELDS (regs_type); fieldno++)

View file

@ -260,11 +260,9 @@ core_target::close ()
{ {
if (core_bfd) if (core_bfd)
{ {
int pid = ptid_get_pid (inferior_ptid);
inferior_ptid = null_ptid; /* Avoid confusion from thread inferior_ptid = null_ptid; /* Avoid confusion from thread
stuff. */ stuff. */
if (pid != 0) exit_inferior_silent (current_inferior ());
exit_inferior_silent (pid);
/* Clear out solib state while the bfd is still open. See /* Clear out solib state while the bfd is still open. See
comments in clear_solib in solib.c. */ comments in clear_solib in solib.c. */
@ -454,7 +452,7 @@ core_target_open (const char *arg, int from_tty)
which was the "main" thread. The latter case shouldn't which was the "main" thread. The latter case shouldn't
usually happen, but we're dealing with input here, which can usually happen, but we're dealing with input here, which can
always be broken in different ways. */ always be broken in different ways. */
struct thread_info *thread = first_thread_of_process (-1); thread_info *thread = first_thread_of_inferior (current_inferior ());
if (thread == NULL) if (thread == NULL)
{ {
@ -463,7 +461,7 @@ core_target_open (const char *arg, int from_tty)
add_thread_silent (inferior_ptid); add_thread_silent (inferior_ptid);
} }
else else
switch_to_thread (thread->ptid); switch_to_thread (thread);
} }
post_create_inferior (target, from_tty); post_create_inferior (target, from_tty);

View file

@ -1175,15 +1175,12 @@ ctf_target_open (const char *dirname, int from_tty)
void void
ctf_target::close () ctf_target::close ()
{ {
int pid;
ctf_destroy (); ctf_destroy ();
xfree (trace_dirname); xfree (trace_dirname);
trace_dirname = NULL; trace_dirname = NULL;
pid = ptid_get_pid (inferior_ptid);
inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
exit_inferior_silent (pid); exit_inferior_silent (current_inferior ());
trace_reset_local_state (); trace_reset_local_state ();
} }

View file

@ -37,7 +37,7 @@ struct dummy_frame_id
struct frame_id id; struct frame_id id;
/* The thread this dummy_frame relates to. */ /* The thread this dummy_frame relates to. */
ptid_t ptid; thread_info *thread;
}; };
/* Return whether dummy_frame_id *ID1 and *ID2 are equal. */ /* Return whether dummy_frame_id *ID1 and *ID2 are equal. */
@ -46,7 +46,7 @@ static int
dummy_frame_id_eq (struct dummy_frame_id *id1, dummy_frame_id_eq (struct dummy_frame_id *id1,
struct dummy_frame_id *id2) struct dummy_frame_id *id2)
{ {
return frame_id_eq (id1->id, id2->id) && ptid_equal (id1->ptid, id2->ptid); return frame_id_eq (id1->id, id2->id) && id1->thread == id2->thread;
} }
/* List of dummy_frame destructors. */ /* List of dummy_frame destructors. */
@ -89,14 +89,14 @@ static struct dummy_frame *dummy_frame_stack = NULL;
void void
dummy_frame_push (struct infcall_suspend_state *caller_state, dummy_frame_push (struct infcall_suspend_state *caller_state,
const struct frame_id *dummy_id, ptid_t ptid) const frame_id *dummy_id, thread_info *thread)
{ {
struct dummy_frame *dummy_frame; struct dummy_frame *dummy_frame;
dummy_frame = XCNEW (struct dummy_frame); dummy_frame = XCNEW (struct dummy_frame);
dummy_frame->caller_state = caller_state; dummy_frame->caller_state = caller_state;
dummy_frame->id.id = (*dummy_id); dummy_frame->id.id = (*dummy_id);
dummy_frame->id.ptid = ptid; dummy_frame->id.thread = thread;
dummy_frame->next = dummy_frame_stack; dummy_frame->next = dummy_frame_stack;
dummy_frame_stack = dummy_frame; dummy_frame_stack = dummy_frame;
} }
@ -130,7 +130,7 @@ pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp)
{ {
struct dummy_frame *dummy = (struct dummy_frame *) dummy_voidp; struct dummy_frame *dummy = (struct dummy_frame *) dummy_voidp;
if (b->thread == ptid_to_global_thread_id (dummy->id.ptid) if (b->thread == dummy->id.thread->global_num
&& b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id)) && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id))
{ {
while (b->related_breakpoint != b) while (b->related_breakpoint != b)
@ -154,7 +154,7 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr)
{ {
struct dummy_frame *dummy = *dummy_ptr; struct dummy_frame *dummy = *dummy_ptr;
gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid)); gdb_assert (dummy->id.thread == inferior_thread ());
while (dummy->dtor_list != NULL) while (dummy->dtor_list != NULL)
{ {
@ -196,16 +196,16 @@ lookup_dummy_frame (struct dummy_frame_id *dummy_id)
return NULL; return NULL;
} }
/* Find the dummy frame by DUMMY_ID and PTID, and pop it, restoring /* Find the dummy frame by DUMMY_ID and THREAD, and pop it, restoring
program state to that before the frame was created. program state to that before the frame was created.
On return reinit_frame_cache has been called. On return reinit_frame_cache has been called.
If the frame isn't found, flag an internal error. */ If the frame isn't found, flag an internal error. */
void void
dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid) dummy_frame_pop (frame_id dummy_id, thread_info *thread)
{ {
struct dummy_frame **dp; struct dummy_frame **dp;
struct dummy_frame_id id = { dummy_id, ptid }; struct dummy_frame_id id = { dummy_id, thread };
dp = lookup_dummy_frame (&id); dp = lookup_dummy_frame (&id);
gdb_assert (dp != NULL); gdb_assert (dp != NULL);
@ -218,10 +218,10 @@ dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid)
free its memory. */ free its memory. */
void void
dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid) dummy_frame_discard (struct frame_id dummy_id, thread_info *thread)
{ {
struct dummy_frame **dp; struct dummy_frame **dp;
struct dummy_frame_id id = { dummy_id, ptid }; struct dummy_frame_id id = { dummy_id, thread };
dp = lookup_dummy_frame (&id); dp = lookup_dummy_frame (&id);
if (dp) if (dp)
@ -231,10 +231,10 @@ dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid)
/* See dummy-frame.h. */ /* See dummy-frame.h. */
void void
register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid, register_dummy_frame_dtor (frame_id dummy_id, thread_info *thread,
dummy_frame_dtor_ftype *dtor, void *dtor_data) dummy_frame_dtor_ftype *dtor, void *dtor_data)
{ {
struct dummy_frame_id id = { dummy_id, ptid }; struct dummy_frame_id id = { dummy_id, thread };
struct dummy_frame **dp, *d; struct dummy_frame **dp, *d;
struct dummy_frame_dtor_list *list; struct dummy_frame_dtor_list *list;
@ -306,7 +306,7 @@ dummy_frame_sniffer (const struct frame_unwind *self,
dummy ID, assuming it is a dummy frame. */ dummy ID, assuming it is a dummy frame. */
struct frame_id this_id struct frame_id this_id
= gdbarch_dummy_id (get_frame_arch (this_frame), this_frame); = gdbarch_dummy_id (get_frame_arch (this_frame), this_frame);
struct dummy_frame_id dummy_id = { this_id, inferior_ptid }; struct dummy_frame_id dummy_id = { this_id, inferior_thread () };
/* Use that ID to find the corresponding cache entry. */ /* Use that ID to find the corresponding cache entry. */
for (dummyframe = dummy_frame_stack; for (dummyframe = dummy_frame_stack;
@ -397,7 +397,7 @@ fprint_dummy_frames (struct ui_file *file)
fprintf_unfiltered (file, " id="); fprintf_unfiltered (file, " id=");
fprint_frame_id (file, s->id.id); fprint_frame_id (file, s->id.id);
fprintf_unfiltered (file, ", ptid=%s", fprintf_unfiltered (file, ", ptid=%s",
target_pid_to_str (s->id.ptid)); target_pid_to_str (s->id.thread->ptid));
fprintf_unfiltered (file, "\n"); fprintf_unfiltered (file, "\n");
} }
} }

View file

@ -33,8 +33,9 @@ struct frame_unwind;
be expanded so that it knowns the lower/upper extent of the dummy be expanded so that it knowns the lower/upper extent of the dummy
frame's code. */ frame's code. */
extern void dummy_frame_push (struct infcall_suspend_state *caller_state, extern void dummy_frame_push (infcall_suspend_state *caller_state,
const struct frame_id *dummy_id, ptid_t ptid); const frame_id *dummy_id,
thread_info *thread);
/* Pop the dummy frame DUMMY_ID, restoring program state to that before the /* Pop the dummy frame DUMMY_ID, restoring program state to that before the
frame was created. frame was created.
@ -45,9 +46,9 @@ extern void dummy_frame_push (struct infcall_suspend_state *caller_state,
stack, because the other frames may be for different threads, and there's stack, because the other frames may be for different threads, and there's
currently no way to tell which stack frame is for which thread. */ currently no way to tell which stack frame is for which thread. */
extern void dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid); extern void dummy_frame_pop (frame_id dummy_id, thread_info *thread);
extern void dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid); extern void dummy_frame_discard (frame_id dummy_id, thread_info *thread);
/* If the PC falls in a dummy frame, return a dummy frame /* If the PC falls in a dummy frame, return a dummy frame
unwinder. */ unwinder. */
@ -58,11 +59,12 @@ extern const struct frame_unwind dummy_frame_unwind;
REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */ REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */
typedef void (dummy_frame_dtor_ftype) (void *data, int registers_valid); typedef void (dummy_frame_dtor_ftype) (void *data, int registers_valid);
/* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread PTID gets discarded. /* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread THREAD gets
Dummy frame with DUMMY_ID must exist. Multiple destructors may be discarded. Dummy frame with DUMMY_ID must exist. Multiple
registered, they will be called in the reverse order of registrations destructors may be registered, they will be called in the reverse
(LIFO). */ order of registrations (LIFO). */
extern void register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid, extern void register_dummy_frame_dtor (frame_id dummy_id,
thread_info *thread,
dummy_frame_dtor_ftype *dtor, dummy_frame_dtor_ftype *dtor,
void *dtor_data); void *dtor_data);

View file

@ -41,6 +41,7 @@
#include "value.h" #include "value.h"
#include "infcall.h" #include "infcall.h"
#include "gdbthread.h" #include "gdbthread.h"
#include "inferior.h"
#include "regcache.h" #include "regcache.h"
#include "bcache.h" #include "bcache.h"
#include "gdb_bfd.h" #include "gdb_bfd.h"
@ -924,7 +925,7 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
struct frame_info *prev_frame = get_prev_frame (get_current_frame ()); struct frame_info *prev_frame = get_prev_frame (get_current_frame ());
struct frame_id prev_frame_id = get_stack_frame_id (prev_frame); struct frame_id prev_frame_id = get_stack_frame_id (prev_frame);
CORE_ADDR prev_pc = get_frame_pc (prev_frame); CORE_ADDR prev_pc = get_frame_pc (prev_frame);
int thread_id = ptid_to_global_thread_id (inferior_ptid); int thread_id = inferior_thread ()->global_num;
gdb_assert (b->type == bp_gnu_ifunc_resolver); gdb_assert (b->type == bp_gnu_ifunc_resolver);
@ -971,10 +972,11 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
static void static void
elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
{ {
thread_info *thread = inferior_thread ();
struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func; struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
struct type *value_type = TYPE_TARGET_TYPE (func_func_type); struct type *value_type = TYPE_TARGET_TYPE (func_func_type);
struct regcache *regcache = get_thread_regcache (inferior_ptid); struct regcache *regcache = get_thread_regcache (thread);
struct value *func_func; struct value *func_func;
struct value *value; struct value *value;
CORE_ADDR resolved_address, resolved_pc; CORE_ADDR resolved_address, resolved_pc;

View file

@ -74,14 +74,14 @@ evaluate_subexp (struct type *expect_type, struct expression *exp,
gdb::optional<enable_thread_stack_temporaries> stack_temporaries; gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
if (*pos == 0 && target_has_execution if (*pos == 0 && target_has_execution
&& exp->language_defn->la_language == language_cplus && exp->language_defn->la_language == language_cplus
&& !thread_stack_temporaries_enabled_p (inferior_ptid)) && !thread_stack_temporaries_enabled_p (inferior_thread ()))
stack_temporaries.emplace (inferior_ptid); stack_temporaries.emplace (inferior_thread ());
retval = (*exp->language_defn->la_exp_desc->evaluate_exp) retval = (*exp->language_defn->la_exp_desc->evaluate_exp)
(expect_type, exp, pos, noside); (expect_type, exp, pos, noside);
if (stack_temporaries.has_value () if (stack_temporaries.has_value ()
&& value_in_thread_stack_temporaries (retval, inferior_ptid)) && value_in_thread_stack_temporaries (retval, inferior_thread ()))
retval = value_non_lval (retval); retval = value_non_lval (retval);
return retval; return retval;

View file

@ -1146,8 +1146,7 @@ fbsd_get_siginfo_type (struct gdbarch *gdbarch)
/* Implement the "get_syscall_number" gdbarch method. */ /* Implement the "get_syscall_number" gdbarch method. */
static LONGEST static LONGEST
fbsd_get_syscall_number (struct gdbarch *gdbarch, fbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
ptid_t ptid)
{ {
/* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD

View file

@ -1050,7 +1050,7 @@ frame_pop (struct frame_info *this_frame)
{ {
/* Popping a dummy frame involves restoring more than just registers. /* Popping a dummy frame involves restoring more than just registers.
dummy_frame_pop does all the work. */ dummy_frame_pop does all the work. */
dummy_frame_pop (get_frame_id (this_frame), inferior_ptid); dummy_frame_pop (get_frame_id (this_frame), inferior_thread ());
return; return;
} }
@ -1622,15 +1622,16 @@ has_stack_frames (void)
if (get_traceframe_number () < 0) if (get_traceframe_number () < 0)
{ {
/* No current inferior, no frame. */ /* No current inferior, no frame. */
if (ptid_equal (inferior_ptid, null_ptid)) if (inferior_ptid == null_ptid)
return 0; return 0;
thread_info *tp = inferior_thread ();
/* Don't try to read from a dead thread. */ /* Don't try to read from a dead thread. */
if (is_exited (inferior_ptid)) if (tp->state == THREAD_EXITED)
return 0; return 0;
/* ... or from a spinning thread. */ /* ... or from a spinning thread. */
if (is_executing (inferior_ptid)) if (tp->executing)
return 0; return 0;
} }
@ -2497,7 +2498,7 @@ find_frame_sal (frame_info *frame)
if (next_frame) if (next_frame)
sym = get_frame_function (next_frame); sym = get_frame_function (next_frame);
else else
sym = inline_skipped_symbol (inferior_ptid); sym = inline_skipped_symbol (inferior_thread ());
/* If frame is inline, it certainly has symbols. */ /* If frame is inline, it certainly has symbols. */
gdb_assert (sym); gdb_assert (sym);

View file

@ -23,6 +23,8 @@
#include "gregset.h" #include "gregset.h"
struct thread_info;
#ifdef HAVE_PROC_SERVICE_H #ifdef HAVE_PROC_SERVICE_H
/* glibc's proc_service.h doesn't wrap itself with extern "C". Need /* glibc's proc_service.h doesn't wrap itself with extern "C". Need
@ -179,7 +181,7 @@ typedef prfpregset_t gdb_prfpregset_t;
struct ps_prochandle struct ps_prochandle
{ {
/* The LWP we use for memory reads. */ /* The LWP we use for memory reads. */
ptid_t ptid; thread_info *thread;
}; };
#endif /* gdb_proc_service.h */ #endif /* gdb_proc_service.h */

View file

@ -4269,13 +4269,13 @@ gdbarch_get_syscall_number_p (struct gdbarch *gdbarch)
} }
LONGEST LONGEST
gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) gdbarch_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
{ {
gdb_assert (gdbarch != NULL); gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->get_syscall_number != NULL); gdb_assert (gdbarch->get_syscall_number != NULL);
if (gdbarch_debug >= 2) if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_number called\n"); fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_number called\n");
return gdbarch->get_syscall_number (gdbarch, ptid); return gdbarch->get_syscall_number (gdbarch, thread);
} }
void void

View file

@ -1168,8 +1168,8 @@ extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_
extern int gdbarch_get_syscall_number_p (struct gdbarch *gdbarch); extern int gdbarch_get_syscall_number_p (struct gdbarch *gdbarch);
typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, ptid_t ptid); typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, thread_info *thread);
extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid); extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread);
extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number); extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
/* The filename of the XML syscall for this architecture. */ /* The filename of the XML syscall for this architecture. */

View file

@ -904,7 +904,7 @@ M;void;record_special_symbol;struct objfile *objfile, asymbol *sym;objfile, sym
# Function for the 'catch syscall' feature. # Function for the 'catch syscall' feature.
# Get architecture-specific system calls information from registers. # Get architecture-specific system calls information from registers.
M;LONGEST;get_syscall_number;ptid_t ptid;ptid M;LONGEST;get_syscall_number;thread_info *thread;thread
# The filename of the XML syscall for this architecture. # The filename of the XML syscall for this architecture.
v;const char *;xml_syscall_file;;;0;0;;0;pstring (gdbarch->xml_syscall_file) v;const char *;xml_syscall_file;;;0;0;;0;pstring (gdbarch->xml_syscall_file)

View file

@ -211,6 +211,9 @@ public:
return (refcount () == 0 && !ptid_equal (ptid, inferior_ptid)); return (refcount () == 0 && !ptid_equal (ptid, inferior_ptid));
} }
/* Mark this thread as running and notify observers. */
void set_running (bool running);
struct thread_info *next = NULL; struct thread_info *next = NULL;
ptid_t ptid; /* "Actual process id"; ptid_t ptid; /* "Actual process id";
In fact, this may be overloaded with In fact, this may be overloaded with
@ -367,6 +370,11 @@ public:
struct thread_info *step_over_next = NULL; struct thread_info *step_over_next = NULL;
}; };
/* A gdb::ref_ptr pointer to a thread_info. */
using thread_info_ref
= gdb::ref_ptr<thread_info, refcounted_object_ref_policy>;
/* Create an empty thread list, or empty the existing one. */ /* Create an empty thread list, or empty the existing one. */
extern void init_thread_list (void); extern void init_thread_list (void);
@ -385,12 +393,12 @@ extern struct thread_info *add_thread_with_info (ptid_t ptid,
struct private_thread_info *); struct private_thread_info *);
/* Delete an existing thread list entry. */ /* Delete an existing thread list entry. */
extern void delete_thread (ptid_t); extern void delete_thread (thread_info *thread);
/* Delete an existing thread list entry, and be quiet about it. Used /* Delete an existing thread list entry, and be quiet about it. Used
after the process this thread having belonged to having already after the process this thread having belonged to having already
exited, for example. */ exited, for example. */
extern void delete_thread_silent (ptid_t); extern void delete_thread_silent (thread_info *thread);
/* Delete a step_resume_breakpoint from the thread database. */ /* Delete a step_resume_breakpoint from the thread database. */
extern void delete_step_resume_breakpoint (struct thread_info *); extern void delete_step_resume_breakpoint (struct thread_info *);
@ -411,16 +419,6 @@ extern int thread_has_single_step_breakpoint_here (struct thread_info *tp,
const address_space *aspace, const address_space *aspace,
CORE_ADDR addr); CORE_ADDR addr);
/* Translate the global integer thread id (GDB's homegrown id, not the
system's) into a "pid" (which may be overloaded with extra thread
information). */
extern ptid_t global_thread_id_to_ptid (int num);
/* Translate a 'pid' (which may be overloaded with extra thread
information) into the global integer thread id (GDB's homegrown id,
not the system's). */
extern int ptid_to_global_thread_id (ptid_t ptid);
/* Returns whether to show inferior-qualified thread IDs, or plain /* Returns whether to show inferior-qualified thread IDs, or plain
thread numbers. Inferior-qualified IDs are shown whenever we have thread numbers. Inferior-qualified IDs are shown whenever we have
multiple inferiors, or the only inferior left has number > 1. */ multiple inferiors, or the only inferior left has number > 1. */
@ -432,8 +430,7 @@ extern int show_inferior_qualified_tids (void);
circular static buffer, NUMCELLS deep. */ circular static buffer, NUMCELLS deep. */
const char *print_thread_id (struct thread_info *thr); const char *print_thread_id (struct thread_info *thr);
/* Boolean test for an already-known pid (which may be overloaded with /* Boolean test for an already-known ptid. */
extra thread information). */
extern int in_thread_list (ptid_t ptid); extern int in_thread_list (ptid_t ptid);
/* Boolean test for an already-known global thread id (GDB's homegrown /* Boolean test for an already-known global thread id (GDB's homegrown
@ -450,17 +447,16 @@ struct thread_info *find_thread_global_id (int global_id);
struct thread_info *find_thread_by_handle (struct value *thread_handle, struct thread_info *find_thread_by_handle (struct value *thread_handle,
struct inferior *inf); struct inferior *inf);
/* Finds the first thread of the inferior given by PID. If PID is -1, /* Finds the first thread of the specified inferior. */
returns the first thread in the list. */ extern thread_info *first_thread_of_inferior (inferior *inf);
struct thread_info *first_thread_of_process (int pid);
/* Returns any thread of process PID, giving preference to the current /* Returns any thread of inferior INF, giving preference to the
thread. */ current thread. */
extern struct thread_info *any_thread_of_process (int pid); extern thread_info *any_thread_of_inferior (inferior *inf);
/* Returns any non-exited thread of process PID, giving preference to /* Returns any non-exited thread of inferior INF, giving preference to
the current thread, and to not executing threads. */ the current thread, and to not executing threads. */
extern struct thread_info *any_live_thread_of_process (int pid); extern thread_info *any_live_thread_of_inferior (inferior *inf);
/* Change the ptid of thread OLD_PTID to NEW_PTID. */ /* Change the ptid of thread OLD_PTID to NEW_PTID. */
void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid);
@ -496,6 +492,12 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
extern int thread_count (void); extern int thread_count (void);
/* Switch context to thread THR. Also sets the STOP_PC global. */
extern void switch_to_thread (thread_info *thr);
/* Switch context to no thread selected. */
extern void switch_to_no_thread ();
/* Switch from one thread to another. Does not read registers and /* Switch from one thread to another. Does not read registers and
sets STOP_PC to -1. */ sets STOP_PC to -1. */
extern void switch_to_thread_no_regs (struct thread_info *thread); extern void switch_to_thread_no_regs (struct thread_info *thread);
@ -549,9 +551,6 @@ extern int is_stopped (ptid_t ptid);
thread_info. */ thread_info. */
extern void set_executing (ptid_t ptid, int executing); extern void set_executing (ptid_t ptid, int executing);
/* Reports if thread PTID is executing. */
extern int is_executing (ptid_t ptid);
/* True if any (known or unknown) thread is or may be executing. */ /* True if any (known or unknown) thread is or may be executing. */
extern int threads_are_executing (void); extern int threads_are_executing (void);
@ -653,48 +652,48 @@ extern void delete_exited_threads (void);
int pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread); int pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread);
/* Enable storing stack temporaries for thread with id PTID and /* Enable storing stack temporaries for thread THR and disable and
disable and clear the stack temporaries on destruction. */ clear the stack temporaries on destruction. Holds a strong
reference to THR. */
class enable_thread_stack_temporaries class enable_thread_stack_temporaries
{ {
public: public:
explicit enable_thread_stack_temporaries (ptid_t ptid) explicit enable_thread_stack_temporaries (thread_info *thr)
: m_ptid (ptid) : m_thr (thr)
{ {
struct thread_info *tp = find_thread_ptid (ptid); gdb_assert (m_thr != NULL);
gdb_assert (tp != NULL); m_thr->incref ();
tp->stack_temporaries_enabled = true;
tp->stack_temporaries.clear (); m_thr->stack_temporaries_enabled = true;
m_thr->stack_temporaries.clear ();
} }
~enable_thread_stack_temporaries () ~enable_thread_stack_temporaries ()
{ {
struct thread_info *tp = find_thread_ptid (m_ptid); m_thr->stack_temporaries_enabled = false;
m_thr->stack_temporaries.clear ();
if (tp != NULL) m_thr->decref ();
{
tp->stack_temporaries_enabled = false;
tp->stack_temporaries.clear ();
}
} }
DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries); DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);
private: private:
ptid_t m_ptid; thread_info *m_thr;
}; };
extern bool thread_stack_temporaries_enabled_p (ptid_t ptid); extern bool thread_stack_temporaries_enabled_p (thread_info *tp);
extern void push_thread_stack_temporary (ptid_t ptid, struct value *v); extern void push_thread_stack_temporary (thread_info *tp, struct value *v);
extern struct value *get_last_thread_stack_temporary (ptid_t); extern value *get_last_thread_stack_temporary (thread_info *tp);
extern bool value_in_thread_stack_temporaries (struct value *, ptid_t); extern bool value_in_thread_stack_temporaries (struct value *,
thread_info *thr);
/* Add TP to the end of its inferior's pending step-over chain. */ /* Add TP to the end of its inferior's pending step-over chain. */
@ -722,9 +721,9 @@ extern void thread_cancel_execution_command (struct thread_info *thr);
executing). */ executing). */
extern void validate_registers_access (void); extern void validate_registers_access (void);
/* Check whether it makes sense to access a register of PTID at this point. /* Check whether it makes sense to access a register of THREAD at this point.
Returns true if registers may be accessed; false otherwise. */ Returns true if registers may be accessed; false otherwise. */
extern bool can_access_registers_ptid (ptid_t ptid); extern bool can_access_registers_thread (thread_info *thread);
/* Returns whether to show which thread hit the breakpoint, received a /* Returns whether to show which thread hit the breakpoint, received a
signal, etc. and ended up causing a user-visible stop. This is signal, etc. and ended up causing a user-visible stop. This is

View file

@ -559,9 +559,9 @@ i386_linux_get_syscall_number_from_regcache (struct regcache *regcache)
static LONGEST static LONGEST
i386_linux_get_syscall_number (struct gdbarch *gdbarch, i386_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
return i386_linux_get_syscall_number_from_regcache (regcache); return i386_linux_get_syscall_number_from_regcache (regcache);
} }

View file

@ -422,7 +422,8 @@ static struct value *
get_call_return_value (struct call_return_meta_info *ri) get_call_return_value (struct call_return_meta_info *ri)
{ {
struct value *retval = NULL; struct value *retval = NULL;
bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid); thread_info *thr = inferior_thread ();
bool stack_temporaries = thread_stack_temporaries_enabled_p (thr);
if (TYPE_CODE (ri->value_type) == TYPE_CODE_VOID) if (TYPE_CODE (ri->value_type) == TYPE_CODE_VOID)
retval = allocate_value (ri->value_type); retval = allocate_value (ri->value_type);
@ -432,7 +433,7 @@ get_call_return_value (struct call_return_meta_info *ri)
{ {
retval = value_from_contents_and_address (ri->value_type, NULL, retval = value_from_contents_and_address (ri->value_type, NULL,
ri->struct_addr); ri->struct_addr);
push_thread_stack_temporary (inferior_ptid, retval); push_thread_stack_temporary (thr, retval);
} }
else else
{ {
@ -458,7 +459,7 @@ get_call_return_value (struct call_return_meta_info *ri)
the this pointer, GDB needs the memory address of the the this pointer, GDB needs the memory address of the
value. */ value. */
value_force_lval (retval, ri->struct_addr); value_force_lval (retval, ri->struct_addr);
push_thread_stack_temporary (inferior_ptid, retval); push_thread_stack_temporary (thr, retval);
} }
} }
@ -586,6 +587,7 @@ run_inferior_call (struct call_thread_fsm *sm,
struct gdb_exception caught_error = exception_none; struct gdb_exception caught_error = exception_none;
int saved_in_infcall = call_thread->control.in_infcall; int saved_in_infcall = call_thread->control.in_infcall;
ptid_t call_thread_ptid = call_thread->ptid; ptid_t call_thread_ptid = call_thread->ptid;
inferior *call_thread_inf = call_thread->inf;
enum prompt_state saved_prompt_state = current_ui->prompt_state; enum prompt_state saved_prompt_state = current_ui->prompt_state;
int was_running = call_thread->state == THREAD_RUNNING; int was_running = call_thread->state == THREAD_RUNNING;
int saved_ui_async = current_ui->async; int saved_ui_async = current_ui->async;
@ -637,10 +639,6 @@ run_inferior_call (struct call_thread_fsm *sm,
ui_register_input_event_handler (current_ui); ui_register_input_event_handler (current_ui);
current_ui->async = saved_ui_async; current_ui->async = saved_ui_async;
/* At this point the current thread may have changed. Refresh
CALL_THREAD as it could be invalid if its thread has exited. */
call_thread = find_thread_ptid (call_thread_ptid);
/* If the infcall does NOT succeed, normal_stop will have already /* If the infcall does NOT succeed, normal_stop will have already
finished the thread states. However, on success, normal_stop finished the thread states. However, on success, normal_stop
defers here, so that we can set back the thread states to what defers here, so that we can set back the thread states to what
@ -657,7 +655,7 @@ run_inferior_call (struct call_thread_fsm *sm,
evaluates true and thus we'll present a user-visible stop is evaluates true and thus we'll present a user-visible stop is
decided elsewhere. */ decided elsewhere. */
if (!was_running if (!was_running
&& ptid_equal (call_thread_ptid, inferior_ptid) && call_thread_ptid == inferior_ptid
&& stop_stack_dummy == STOP_STACK_DUMMY) && stop_stack_dummy == STOP_STACK_DUMMY)
finish_thread_state (user_visible_resume_ptid (0)); finish_thread_state (user_visible_resume_ptid (0));
@ -670,12 +668,11 @@ run_inferior_call (struct call_thread_fsm *sm,
of error out of resume()), then we wouldn't need this. */ of error out of resume()), then we wouldn't need this. */
if (caught_error.reason < 0) if (caught_error.reason < 0)
{ {
if (call_thread != NULL) if (call_thread->state != THREAD_EXITED)
breakpoint_auto_delete (call_thread->control.stop_bpstat); breakpoint_auto_delete (call_thread->control.stop_bpstat);
} }
if (call_thread != NULL) call_thread->control.in_infcall = saved_in_infcall;
call_thread->control.in_infcall = saved_in_infcall;
return caught_error; return caught_error;
} }
@ -739,7 +736,6 @@ call_function_by_hand_dummy (struct value *function,
ptid_t call_thread_ptid; ptid_t call_thread_ptid;
struct gdb_exception e; struct gdb_exception e;
char name_buf[RAW_FUNCTION_ADDRESS_SIZE]; char name_buf[RAW_FUNCTION_ADDRESS_SIZE];
bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
if (!target_has_execution) if (!target_has_execution)
noprocess (); noprocess ();
@ -750,6 +746,14 @@ call_function_by_hand_dummy (struct value *function,
if (execution_direction == EXEC_REVERSE) if (execution_direction == EXEC_REVERSE)
error (_("Cannot call functions in reverse mode.")); error (_("Cannot call functions in reverse mode."));
/* We're going to run the target, and inspect the thread's state
afterwards. Hold a strong reference so that the pointer remains
valid even if the thread exits. */
thread_info_ref call_thread
= thread_info_ref::new_reference (inferior_thread ());
bool stack_temporaries = thread_stack_temporaries_enabled_p (call_thread.get ());
frame = get_current_frame (); frame = get_current_frame ();
gdbarch = get_frame_arch (frame); gdbarch = get_frame_arch (frame);
@ -842,7 +846,7 @@ call_function_by_hand_dummy (struct value *function,
{ {
struct value *lastval; struct value *lastval;
lastval = get_last_thread_stack_temporary (inferior_ptid); lastval = get_last_thread_stack_temporary (call_thread.get ());
if (lastval != NULL) if (lastval != NULL)
{ {
CORE_ADDR lastval_addr = value_address (lastval); CORE_ADDR lastval_addr = value_address (lastval);
@ -1137,9 +1141,9 @@ call_function_by_hand_dummy (struct value *function,
/* Everything's ready, push all the info needed to restore the /* Everything's ready, push all the info needed to restore the
caller (and identify the dummy-frame) onto the dummy-frame caller (and identify the dummy-frame) onto the dummy-frame
stack. */ stack. */
dummy_frame_push (caller_state, &dummy_id, inferior_ptid); dummy_frame_push (caller_state, &dummy_id, call_thread.get ());
if (dummy_dtor != NULL) if (dummy_dtor != NULL)
register_dummy_frame_dtor (dummy_id, inferior_ptid, register_dummy_frame_dtor (dummy_id, call_thread.get (),
dummy_dtor, dummy_dtor_data); dummy_dtor, dummy_dtor_data);
/* Register a clean-up for unwind_on_terminating_exception_breakpoint. */ /* Register a clean-up for unwind_on_terminating_exception_breakpoint. */
@ -1150,20 +1154,17 @@ call_function_by_hand_dummy (struct value *function,
If you're looking to implement asynchronous dummy-frames, then If you're looking to implement asynchronous dummy-frames, then
just below is the place to chop this function in two.. */ just below is the place to chop this function in two.. */
/* TP is invalid after run_inferior_call returns, so enclose this
in a block so that it's only in scope during the time it's valid. */
{ {
struct thread_info *tp = inferior_thread ();
struct thread_fsm *saved_sm; struct thread_fsm *saved_sm;
struct call_thread_fsm *sm; struct call_thread_fsm *sm;
/* Save the current FSM. We'll override it. */ /* Save the current FSM. We'll override it. */
saved_sm = tp->thread_fsm; saved_sm = call_thread->thread_fsm;
tp->thread_fsm = NULL; call_thread->thread_fsm = NULL;
/* Save this thread's ptid, we need it later but the thread /* Save this thread's ptid, we need it later but the thread
may have exited. */ may have exited. */
call_thread_ptid = tp->ptid; call_thread_ptid = call_thread->ptid;
/* Run the inferior until it stops. */ /* Run the inferior until it stops. */
@ -1177,17 +1178,16 @@ call_function_by_hand_dummy (struct value *function,
struct_return || hidden_first_param_p, struct_return || hidden_first_param_p,
struct_addr); struct_addr);
e = run_inferior_call (sm, tp, real_pc); e = run_inferior_call (sm, call_thread.get (), real_pc);
gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr); gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);
tp = find_thread_ptid (call_thread_ptid); if (call_thread->state != THREAD_EXITED)
if (tp != NULL)
{ {
/* The FSM should still be the same. */ /* The FSM should still be the same. */
gdb_assert (tp->thread_fsm == &sm->thread_fsm); gdb_assert (call_thread->thread_fsm == &sm->thread_fsm);
if (thread_fsm_finished_p (tp->thread_fsm)) if (thread_fsm_finished_p (call_thread->thread_fsm))
{ {
struct value *retval; struct value *retval;
@ -1195,7 +1195,7 @@ call_function_by_hand_dummy (struct value *function,
which runs its destructors and restores the inferior's which runs its destructors and restores the inferior's
suspend state, and restore the inferior control suspend state, and restore the inferior control
state. */ state. */
dummy_frame_pop (dummy_id, call_thread_ptid); dummy_frame_pop (dummy_id, call_thread.get ());
restore_infcall_control_state (inf_status); restore_infcall_control_state (inf_status);
/* Get the return value. */ /* Get the return value. */
@ -1203,9 +1203,9 @@ call_function_by_hand_dummy (struct value *function,
/* Clean up / destroy the call FSM, and restore the /* Clean up / destroy the call FSM, and restore the
original one. */ original one. */
thread_fsm_clean_up (tp->thread_fsm, tp); thread_fsm_clean_up (call_thread->thread_fsm, call_thread.get ());
thread_fsm_delete (tp->thread_fsm); thread_fsm_delete (call_thread->thread_fsm);
tp->thread_fsm = saved_sm; call_thread->thread_fsm = saved_sm;
maybe_remove_breakpoints (); maybe_remove_breakpoints ();
@ -1216,7 +1216,7 @@ call_function_by_hand_dummy (struct value *function,
/* Didn't complete. Restore previous state machine, and /* Didn't complete. Restore previous state machine, and
handle the error. */ handle the error. */
tp->thread_fsm = saved_sm; call_thread->thread_fsm = saved_sm;
} }
} }
@ -1317,7 +1317,7 @@ When the function is done executing, GDB will silently stop."),
/* We must get back to the frame we were before the /* We must get back to the frame we were before the
dummy call. */ dummy call. */
dummy_frame_pop (dummy_id, call_thread_ptid); dummy_frame_pop (dummy_id, call_thread.get ());
/* We also need to restore inferior status to that before the /* We also need to restore inferior status to that before the
dummy call. */ dummy call. */
@ -1358,7 +1358,7 @@ When the function is done executing, GDB will silently stop."),
{ {
/* We must get back to the frame we were before the dummy /* We must get back to the frame we were before the dummy
call. */ call. */
dummy_frame_pop (dummy_id, call_thread_ptid); dummy_frame_pop (dummy_id, call_thread.get ());
/* We also need to restore inferior status to that before /* We also need to restore inferior status to that before
the dummy call. */ the dummy call. */

View file

@ -723,10 +723,10 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
much. If/when GDB gains a way to tell the target `hold this much. If/when GDB gains a way to tell the target `hold this
thread stopped until I say otherwise', then we can optimize thread stopped until I say otherwise', then we can optimize
this. */ this. */
if (!is_stopped (thread->ptid)) if (thread->state != THREAD_STOPPED)
return 0; return 0;
switch_to_thread (thread->ptid); switch_to_thread (thread);
clear_proceed_status (0); clear_proceed_status (0);
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
return 0; return 0;
@ -735,8 +735,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
static void static void
ensure_valid_thread (void) ensure_valid_thread (void)
{ {
if (ptid_equal (inferior_ptid, null_ptid) if (inferior_ptid == null_ptid
|| is_exited (inferior_ptid)) || inferior_thread ()->state == THREAD_EXITED)
error (_("Cannot execute this command without a live selected thread.")); error (_("Cannot execute this command without a live selected thread."));
} }
@ -765,7 +765,7 @@ error_is_running (void)
static void static void
ensure_not_running (void) ensure_not_running (void)
{ {
if (is_running (inferior_ptid)) if (inferior_thread ()->state == THREAD_RUNNING)
error_is_running (); error_is_running ();
} }
@ -855,7 +855,7 @@ continue_command (const char *args, int from_tty)
struct thread_info *tp; struct thread_info *tp;
if (non_stop) if (non_stop)
tp = find_thread_ptid (inferior_ptid); tp = inferior_thread ();
else else
{ {
ptid_t last_ptid; ptid_t last_ptid;
@ -1148,7 +1148,7 @@ prepare_one_step (struct step_command_fsm *sm)
/* Step at an inlined function behaves like "down". */ /* Step at an inlined function behaves like "down". */
if (!sm->skip_subroutines if (!sm->skip_subroutines
&& inline_skipped_frames (inferior_ptid)) && inline_skipped_frames (tp))
{ {
ptid_t resume_ptid; ptid_t resume_ptid;
@ -1156,7 +1156,7 @@ prepare_one_step (struct step_command_fsm *sm)
resume_ptid = user_visible_resume_ptid (1); resume_ptid = user_visible_resume_ptid (1);
set_running (resume_ptid, 1); set_running (resume_ptid, 1);
step_into_inline_frame (inferior_ptid); step_into_inline_frame (tp);
sm->count--; sm->count--;
return prepare_one_step (sm); return prepare_one_step (sm);
} }
@ -2076,7 +2076,6 @@ info_program_command (const char *args, int from_tty)
{ {
bpstat bs; bpstat bs;
int num, stat; int num, stat;
struct thread_info *tp;
ptid_t ptid; ptid_t ptid;
if (!target_has_execution) if (!target_has_execution)
@ -2094,12 +2093,16 @@ info_program_command (const char *args, int from_tty)
get_last_target_status (&ptid, &ws); get_last_target_status (&ptid, &ws);
} }
if (ptid_equal (ptid, null_ptid) || is_exited (ptid)) if (ptid == null_ptid)
error (_("No selected thread."));
thread_info *tp = find_thread_ptid (ptid);
if (tp->state == THREAD_EXITED)
error (_("Invalid selected thread.")); error (_("Invalid selected thread."));
else if (is_running (ptid)) else if (tp->state == THREAD_RUNNING)
error (_("Selected thread is running.")); error (_("Selected thread is running."));
tp = find_thread_ptid (ptid);
bs = tp->control.stop_bpstat; bs = tp->control.stop_bpstat;
stat = bpstat_num (&bs, &num); stat = bpstat_num (&bs, &num);
@ -2638,12 +2641,12 @@ proceed_after_attach_callback (struct thread_info *thread,
int pid = * (int *) arg; int pid = * (int *) arg;
if (ptid_get_pid (thread->ptid) == pid if (ptid_get_pid (thread->ptid) == pid
&& !is_exited (thread->ptid) && thread->state != THREAD_EXITED
&& !is_executing (thread->ptid) && !thread->executing
&& !thread->stop_requested && !thread->stop_requested
&& thread->suspend.stop_signal == GDB_SIGNAL_0) && thread->suspend.stop_signal == GDB_SIGNAL_0)
{ {
switch_to_thread (thread->ptid); switch_to_thread (thread);
clear_proceed_status (0); clear_proceed_status (0);
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
} }
@ -2773,7 +2776,7 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod
} }
} }
switch_to_thread (lowest->ptid); switch_to_thread (lowest);
} }
/* Tell the user/frontend where we're stopped. */ /* Tell the user/frontend where we're stopped. */
@ -2939,7 +2942,7 @@ attach_command (const char *args, int from_tty)
as stopped. */ as stopped. */
void void
notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
{ {
enum attach_post_wait_mode mode enum attach_post_wait_mode mode
= leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING; = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
@ -2951,12 +2954,12 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
/* Avoid reading registers -- we haven't fetched the target /* Avoid reading registers -- we haven't fetched the target
description yet. */ description yet. */
switch_to_thread_no_regs (find_thread_ptid (ptid)); switch_to_thread_no_regs (thr);
/* When we "notice" a new inferior we need to do all the things we /* When we "notice" a new inferior we need to do all the things we
would normally do if we had just attached to it. */ would normally do if we had just attached to it. */
if (is_executing (inferior_ptid)) if (thr->executing)
{ {
struct attach_command_continuation_args *a; struct attach_command_continuation_args *a;
struct inferior *inferior = current_inferior (); struct inferior *inferior = current_inferior ();

View file

@ -144,9 +144,9 @@ delete_thread_of_inferior (struct thread_info *tp, void *data)
if (ptid_get_pid (tp->ptid) == arg->pid) if (ptid_get_pid (tp->ptid) == arg->pid)
{ {
if (arg->silent) if (arg->silent)
delete_thread_silent (tp->ptid); delete_thread_silent (tp);
else else
delete_thread (tp->ptid); delete_thread (tp);
} }
return 0; return 0;
@ -230,10 +230,9 @@ exit_inferior_1 (struct inferior *inftoex, int silent)
} }
void void
exit_inferior (int pid) exit_inferior (inferior *inf)
{ {
struct inferior *inf = find_inferior_pid (pid); int pid = inf->pid;
exit_inferior_1 (inf, 0); exit_inferior_1 (inf, 0);
} }
@ -245,6 +244,12 @@ exit_inferior_silent (int pid)
exit_inferior_1 (inf, 1); exit_inferior_1 (inf, 1);
} }
void
exit_inferior_silent (inferior *inf)
{
exit_inferior_1 (inf, 1);
}
void void
exit_inferior_num_silent (int num) exit_inferior_num_silent (int num)
{ {
@ -269,14 +274,6 @@ detach_inferior (inferior *inf)
target_pid_to_str (pid_to_ptid (pid))); target_pid_to_str (pid_to_ptid (pid)));
} }
/* See inferior.h. */
void
detach_inferior (int pid)
{
detach_inferior (find_inferior_pid (pid));
}
void void
inferior_appeared (struct inferior *inf, int pid) inferior_appeared (struct inferior *inf, int pid)
{ {
@ -295,7 +292,7 @@ discard_all_inferiors (void)
for (inf = inferior_list; inf; inf = inf->next) for (inf = inferior_list; inf; inf = inf->next)
{ {
if (inf->pid != 0) if (inf->pid != 0)
exit_inferior_silent (inf->pid); exit_inferior_silent (inf);
} }
} }
@ -371,52 +368,6 @@ iterate_over_inferiors (int (*callback) (struct inferior *, void *),
return NULL; return NULL;
} }
int
valid_gdb_inferior_id (int num)
{
struct inferior *inf;
for (inf = inferior_list; inf; inf = inf->next)
if (inf->num == num)
return 1;
return 0;
}
int
pid_to_gdb_inferior_id (int pid)
{
struct inferior *inf;
for (inf = inferior_list; inf; inf = inf->next)
if (inf->pid == pid)
return inf->num;
return 0;
}
int
gdb_inferior_id_to_pid (int num)
{
struct inferior *inferior = find_inferior_id (num);
if (inferior)
return inferior->pid;
else
return -1;
}
int
in_inferior_list (int pid)
{
struct inferior *inf;
for (inf = inferior_list; inf; inf = inf->next)
if (inf->pid == pid)
return 1;
return 0;
}
int int
have_inferiors (void) have_inferiors (void)
{ {
@ -611,8 +562,6 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
static void static void
detach_inferior_command (const char *args, int from_tty) detach_inferior_command (const char *args, int from_tty)
{ {
struct thread_info *tp;
if (!args || !*args) if (!args || !*args)
error (_("Requires argument (inferior id(s) to detach)")); error (_("Requires argument (inferior id(s) to detach)"));
@ -621,27 +570,27 @@ detach_inferior_command (const char *args, int from_tty)
{ {
int num = parser.get_number (); int num = parser.get_number ();
if (!valid_gdb_inferior_id (num)) inferior *inf = find_inferior_id (num);
if (inf == NULL)
{ {
warning (_("Inferior ID %d not known."), num); warning (_("Inferior ID %d not known."), num);
continue; continue;
} }
int pid = gdb_inferior_id_to_pid (num); if (inf->pid == 0)
if (pid == 0)
{ {
warning (_("Inferior ID %d is not running."), num); warning (_("Inferior ID %d is not running."), num);
continue; continue;
} }
tp = any_thread_of_process (pid); thread_info *tp = any_thread_of_inferior (inf);
if (!tp) if (tp == NULL)
{ {
warning (_("Inferior ID %d has no threads."), num); warning (_("Inferior ID %d has no threads."), num);
continue; continue;
} }
switch_to_thread (tp->ptid); switch_to_thread (tp);
detach_command (NULL, from_tty); detach_command (NULL, from_tty);
} }
@ -650,8 +599,6 @@ detach_inferior_command (const char *args, int from_tty)
static void static void
kill_inferior_command (const char *args, int from_tty) kill_inferior_command (const char *args, int from_tty)
{ {
struct thread_info *tp;
if (!args || !*args) if (!args || !*args)
error (_("Requires argument (inferior id(s) to kill)")); error (_("Requires argument (inferior id(s) to kill)"));
@ -660,27 +607,27 @@ kill_inferior_command (const char *args, int from_tty)
{ {
int num = parser.get_number (); int num = parser.get_number ();
if (!valid_gdb_inferior_id (num)) inferior *inf = find_inferior_id (num);
if (inf == NULL)
{ {
warning (_("Inferior ID %d not known."), num); warning (_("Inferior ID %d not known."), num);
continue; continue;
} }
int pid = gdb_inferior_id_to_pid (num); if (inf->pid == 0)
if (pid == 0)
{ {
warning (_("Inferior ID %d is not running."), num); warning (_("Inferior ID %d is not running."), num);
continue; continue;
} }
tp = any_thread_of_process (pid); thread_info *tp = any_thread_of_inferior (inf);
if (!tp) if (tp == NULL)
{ {
warning (_("Inferior ID %d has no threads."), num); warning (_("Inferior ID %d has no threads."), num);
continue; continue;
} }
switch_to_thread (tp->ptid); switch_to_thread (tp);
target_kill (); target_kill ();
} }
@ -702,15 +649,13 @@ inferior_command (const char *args, int from_tty)
if (inf->pid != 0) if (inf->pid != 0)
{ {
if (inf->pid != ptid_get_pid (inferior_ptid)) if (inf != current_inferior ())
{ {
struct thread_info *tp; thread_info *tp = any_thread_of_inferior (inf);
if (tp == NULL)
tp = any_thread_of_process (inf->pid);
if (!tp)
error (_("Inferior has no threads.")); error (_("Inferior has no threads."));
switch_to_thread (tp->ptid); switch_to_thread (tp);
} }
gdb::observers::user_selected_context_changed.notify gdb::observers::user_selected_context_changed.notify
@ -721,7 +666,7 @@ inferior_command (const char *args, int from_tty)
else else
{ {
set_current_inferior (inf); set_current_inferior (inf);
switch_to_thread (null_ptid); switch_to_no_thread ();
set_current_program_space (inf->pspace); set_current_program_space (inf->pspace);
gdb::observers::user_selected_context_changed.notify gdb::observers::user_selected_context_changed.notify
@ -855,7 +800,7 @@ add_inferior_command (const char *args, int from_tty)
symbols.q. */ symbols.q. */
set_current_program_space (inf->pspace); set_current_program_space (inf->pspace);
set_current_inferior (inf); set_current_inferior (inf);
switch_to_thread (null_ptid); switch_to_no_thread ();
exec_file_attach (exec.get (), from_tty); exec_file_attach (exec.get (), from_tty);
symbol_file_add_main (exec.get (), add_flags); symbol_file_add_main (exec.get (), add_flags);
@ -943,7 +888,7 @@ clone_inferior_command (const char *args, int from_tty)
printf_filtered (_("Added inferior %d.\n"), inf->num); printf_filtered (_("Added inferior %d.\n"), inf->num);
set_current_inferior (inf); set_current_inferior (inf);
switch_to_thread (null_ptid); switch_to_no_thread ();
clone_program_space (pspace, orginf->pspace); clone_program_space (pspace, orginf->pspace);
} }
} }

View file

@ -32,6 +32,7 @@ struct terminal_info;
struct target_desc_info; struct target_desc_info;
struct continuation; struct continuation;
struct inferior; struct inferior;
struct thread_info;
/* For bpstat. */ /* For bpstat. */
#include "breakpoint.h" #include "breakpoint.h"
@ -176,7 +177,7 @@ extern void delete_longjmp_breakpoint_cleanup (void *arg);
extern void detach_command (const char *, int); extern void detach_command (const char *, int);
extern void notice_new_inferior (ptid_t, int, int); extern void notice_new_inferior (thread_info *, int, int);
extern struct value *get_return_value (struct value *function, extern struct value *get_return_value (struct value *function,
struct type *value_type); struct type *value_type);
@ -474,12 +475,9 @@ extern void delete_inferior (struct inferior *todel);
/* Delete an existing inferior list entry, due to inferior detaching. */ /* Delete an existing inferior list entry, due to inferior detaching. */
extern void detach_inferior (inferior *inf); extern void detach_inferior (inferior *inf);
/* Same as the above, but with the inferior specified by PID. */ extern void exit_inferior (inferior *inf);
extern void detach_inferior (int pid);
extern void exit_inferior (int pid); extern void exit_inferior_silent (inferior *inf);
extern void exit_inferior_silent (int pid);
extern void exit_inferior_num_silent (int num); extern void exit_inferior_num_silent (int num);
@ -488,21 +486,6 @@ extern void inferior_appeared (struct inferior *inf, int pid);
/* Get rid of all inferiors. */ /* Get rid of all inferiors. */
extern void discard_all_inferiors (void); extern void discard_all_inferiors (void);
/* Translate the integer inferior id (GDB's homegrown id, not the system's)
into a "pid" (which may be overloaded with extra inferior information). */
extern int gdb_inferior_id_to_pid (int);
/* Translate a target 'pid' into the integer inferior id (GDB's
homegrown id, not the system's). */
extern int pid_to_gdb_inferior_id (int pid);
/* Boolean test for an already-known pid. */
extern int in_inferior_list (int pid);
/* Boolean test for an already-known inferior id (GDB's homegrown id,
not the system's). */
extern int valid_gdb_inferior_id (int num);
/* Search function to lookup an inferior by target 'pid'. */ /* Search function to lookup an inferior by target 'pid'. */
extern struct inferior *find_inferior_pid (int pid); extern struct inferior *find_inferior_pid (int pid);

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@
#include "block.h" #include "block.h"
#include "frame-unwind.h" #include "frame-unwind.h"
#include "inferior.h" #include "inferior.h"
#include "gdbthread.h"
#include "regcache.h" #include "regcache.h"
#include "symtab.h" #include "symtab.h"
#include "vec.h" #include "vec.h"
@ -36,16 +37,15 @@
keep our own list. */ keep our own list. */
struct inline_state struct inline_state
{ {
inline_state (ptid_t ptid_, int skipped_frames_, CORE_ADDR saved_pc_, inline_state (thread_info *thread_, int skipped_frames_, CORE_ADDR saved_pc_,
symbol *skipped_symbol_) symbol *skipped_symbol_)
: ptid (ptid_), skipped_frames (skipped_frames_), saved_pc (saved_pc_), : thread (thread_), skipped_frames (skipped_frames_), saved_pc (saved_pc_),
skipped_symbol (skipped_symbol_) skipped_symbol (skipped_symbol_)
{} {}
/* The thread this data relates to. It should be a currently /* The thread this data relates to. It should be a currently
stopped thread; we assume thread IDs never change while the stopped thread. */
thread is stopped. */ thread_info *thread;
ptid_t ptid;
/* The number of inlined functions we are skipping. Each of these /* The number of inlined functions we are skipping. Each of these
functions can be stepped in to. */ functions can be stepped in to. */
@ -65,23 +65,23 @@ struct inline_state
static std::vector<inline_state> inline_states; static std::vector<inline_state> inline_states;
/* Locate saved inlined frame state for PTID, if it exists /* Locate saved inlined frame state for THREAD, if it exists and is
and is valid. */ valid. */
static struct inline_state * static struct inline_state *
find_inline_frame_state (ptid_t ptid) find_inline_frame_state (thread_info *thread)
{ {
auto state_it = std::find_if (inline_states.begin (), inline_states.end (), auto state_it = std::find_if (inline_states.begin (), inline_states.end (),
[&ptid] (const inline_state &state) [thread] (const inline_state &state)
{ {
return ptid == state.ptid; return state.thread == thread;
}); });
if (state_it == inline_states.end ()) if (state_it == inline_states.end ())
return nullptr; return nullptr;
inline_state &state = *state_it; inline_state &state = *state_it;
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
CORE_ADDR current_pc = regcache_read_pc (regcache); CORE_ADDR current_pc = regcache_read_pc (regcache);
if (current_pc != state.saved_pc) if (current_pc != state.saved_pc)
@ -115,7 +115,7 @@ clear_inline_frame_state (ptid_t ptid)
auto it = std::remove_if (inline_states.begin (), inline_states.end (), auto it = std::remove_if (inline_states.begin (), inline_states.end (),
[pid] (const inline_state &state) [pid] (const inline_state &state)
{ {
return pid == state.ptid.pid (); return pid == state.thread->inf->pid;
}); });
inline_states.erase (it, inline_states.end ()); inline_states.erase (it, inline_states.end ());
@ -126,7 +126,7 @@ clear_inline_frame_state (ptid_t ptid)
auto it = std::find_if (inline_states.begin (), inline_states.end (), auto it = std::find_if (inline_states.begin (), inline_states.end (),
[&ptid] (const inline_state &state) [&ptid] (const inline_state &state)
{ {
return ptid == state.ptid; return ptid == state.thread->ptid;
}); });
if (it != inline_states.end ()) if (it != inline_states.end ())
@ -199,7 +199,7 @@ inline_frame_sniffer (const struct frame_unwind *self,
const struct block *frame_block, *cur_block; const struct block *frame_block, *cur_block;
int depth; int depth;
struct frame_info *next_frame; struct frame_info *next_frame;
struct inline_state *state = find_inline_frame_state (inferior_ptid); struct inline_state *state = find_inline_frame_state (inferior_thread ());
this_pc = get_frame_address_in_block (this_frame); this_pc = get_frame_address_in_block (this_frame);
frame_block = block_for_pc (this_pc); frame_block = block_for_pc (this_pc);
@ -313,7 +313,7 @@ stopped_by_user_bp_inline_frame (const block *frame_block, bpstat stop_chain)
/* See inline-frame.h. */ /* See inline-frame.h. */
void void
skip_inline_frames (ptid_t ptid, bpstat stop_chain) skip_inline_frames (thread_info *thread, bpstat stop_chain)
{ {
const struct block *frame_block, *cur_block; const struct block *frame_block, *cur_block;
struct symbol *last_sym = NULL; struct symbol *last_sym = NULL;
@ -356,8 +356,8 @@ skip_inline_frames (ptid_t ptid, bpstat stop_chain)
} }
} }
gdb_assert (find_inline_frame_state (ptid) == NULL); gdb_assert (find_inline_frame_state (thread) == NULL);
inline_states.emplace_back (ptid, skip_count, this_pc, last_sym); inline_states.emplace_back (thread, skip_count, this_pc, last_sym);
if (skip_count != 0) if (skip_count != 0)
reinit_frame_cache (); reinit_frame_cache ();
@ -366,9 +366,9 @@ skip_inline_frames (ptid_t ptid, bpstat stop_chain)
/* Step into an inlined function by unhiding it. */ /* Step into an inlined function by unhiding it. */
void void
step_into_inline_frame (ptid_t ptid) step_into_inline_frame (thread_info *thread)
{ {
struct inline_state *state = find_inline_frame_state (ptid); inline_state *state = find_inline_frame_state (thread);
gdb_assert (state != NULL && state->skipped_frames > 0); gdb_assert (state != NULL && state->skipped_frames > 0);
state->skipped_frames--; state->skipped_frames--;
@ -379,9 +379,9 @@ step_into_inline_frame (ptid_t ptid)
frame. */ frame. */
int int
inline_skipped_frames (ptid_t ptid) inline_skipped_frames (thread_info *thread)
{ {
struct inline_state *state = find_inline_frame_state (ptid); inline_state *state = find_inline_frame_state (thread);
if (state == NULL) if (state == NULL)
return 0; return 0;
@ -393,9 +393,9 @@ inline_skipped_frames (ptid_t ptid)
the function inlined into the current frame. */ the function inlined into the current frame. */
struct symbol * struct symbol *
inline_skipped_symbol (ptid_t ptid) inline_skipped_symbol (thread_info *thread)
{ {
struct inline_state *state = find_inline_frame_state (ptid); inline_state *state = find_inline_frame_state (thread);
gdb_assert (state != NULL); gdb_assert (state != NULL);
return state->skipped_symbol; return state->skipped_symbol;
@ -422,7 +422,7 @@ frame_inlined_callees (struct frame_info *this_frame)
they can be stepped into later. If we are unwinding already they can be stepped into later. If we are unwinding already
outer frames from some non-inlined frame this does not apply. */ outer frames from some non-inlined frame this does not apply. */
if (next_frame == NULL) if (next_frame == NULL)
inline_count += inline_skipped_frames (inferior_ptid); inline_count += inline_skipped_frames (inferior_thread ());
return inline_count; return inline_count;
} }

View file

@ -36,7 +36,7 @@ extern const struct frame_unwind inline_frame_unwind;
user's perspective. GDB will stop "in" the inlined frame instead of user's perspective. GDB will stop "in" the inlined frame instead of
the caller. */ the caller. */
void skip_inline_frames (ptid_t ptid, struct bpstats *stop_chain); void skip_inline_frames (thread_info *thread, struct bpstats *stop_chain);
/* Forget about any hidden inlined functions in PTID, which is new or /* Forget about any hidden inlined functions in PTID, which is new or
about to be resumed. If PTID is minus_one_ptid, forget about all about to be resumed. If PTID is minus_one_ptid, forget about all
@ -46,17 +46,17 @@ void clear_inline_frame_state (ptid_t ptid);
/* Step into an inlined function by unhiding it. */ /* Step into an inlined function by unhiding it. */
void step_into_inline_frame (ptid_t ptid); void step_into_inline_frame (thread_info *thread);
/* Return the number of hidden functions inlined into the current /* Return the number of hidden functions inlined into the current
frame. */ frame. */
int inline_skipped_frames (ptid_t ptid); int inline_skipped_frames (thread_info *thread);
/* If one or more inlined functions are hidden, return the symbol for /* If one or more inlined functions are hidden, return the symbol for
the function inlined into the current frame. */ the function inlined into the current frame. */
struct symbol *inline_skipped_symbol (ptid_t ptid); struct symbol *inline_skipped_symbol (thread_info *thread);
/* Return the number of functions inlined into THIS_FRAME. Some of /* Return the number of functions inlined into THIS_FRAME. Some of
the callees may not have associated frames (see the callees may not have associated frames (see

View file

@ -535,10 +535,11 @@ Please switch to another checkpoint before deleting the current one"));
/* If fi->parent_ptid is not a part of lwp but it's a part of checkpoint /* If fi->parent_ptid is not a part of lwp but it's a part of checkpoint
list, waitpid the ptid. list, waitpid the ptid.
If fi->parent_ptid is a part of lwp and it is stoped, waitpid the If fi->parent_ptid is a part of lwp and it is stopped, waitpid the
ptid. */ ptid. */
if ((!find_thread_ptid (pptid) && find_fork_ptid (pptid)) thread_info *parent = find_thread_ptid (pptid);
|| (find_thread_ptid (pptid) && is_stopped (pptid))) if ((parent == NULL && find_fork_ptid (pptid))
|| (parent != NULL && parent->state == THREAD_STOPPED))
{ {
if (inferior_call_waitpid (pptid, ptid_get_pid (ptid))) if (inferior_call_waitpid (pptid, ptid_get_pid (ptid)))
warning (_("Unable to wait pid %s"), target_pid_to_str (ptid)); warning (_("Unable to wait pid %s"), target_pid_to_str (ptid));

View file

@ -1006,7 +1006,7 @@ exit_lwp (struct lwp_info *lp)
if (print_thread_events) if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid)); printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid));
delete_thread (lp->ptid); delete_thread (th);
} }
delete_lwp (lp->ptid); delete_lwp (lp->ptid);
@ -1298,27 +1298,26 @@ get_detach_signal (struct lwp_info *lp)
signo = GDB_SIGNAL_0; /* a pending ptrace event, not a real signal. */ signo = GDB_SIGNAL_0; /* a pending ptrace event, not a real signal. */
else if (lp->status) else if (lp->status)
signo = gdb_signal_from_host (WSTOPSIG (lp->status)); signo = gdb_signal_from_host (WSTOPSIG (lp->status));
else if (target_is_non_stop_p () && !is_executing (lp->ptid)) else
{ {
struct thread_info *tp = find_thread_ptid (lp->ptid); struct thread_info *tp = find_thread_ptid (lp->ptid);
if (tp->suspend.waitstatus_pending_p) if (target_is_non_stop_p () && !tp->executing)
signo = tp->suspend.waitstatus.value.sig;
else
signo = tp->suspend.stop_signal;
}
else if (!target_is_non_stop_p ())
{
struct target_waitstatus last;
ptid_t last_ptid;
get_last_target_status (&last_ptid, &last);
if (ptid_get_lwp (lp->ptid) == ptid_get_lwp (last_ptid))
{ {
struct thread_info *tp = find_thread_ptid (lp->ptid); if (tp->suspend.waitstatus_pending_p)
signo = tp->suspend.waitstatus.value.sig;
else
signo = tp->suspend.stop_signal;
}
else if (!target_is_non_stop_p ())
{
struct target_waitstatus last;
ptid_t last_ptid;
signo = tp->suspend.stop_signal; get_last_target_status (&last_ptid, &last);
if (ptid_get_lwp (lp->ptid) == ptid_get_lwp (last_ptid))
signo = tp->suspend.stop_signal;
} }
} }
@ -1801,7 +1800,8 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
{ {
struct target_waitstatus *ourstatus = &lp->waitstatus; struct target_waitstatus *ourstatus = &lp->waitstatus;
struct gdbarch *gdbarch = target_thread_architecture (lp->ptid); struct gdbarch *gdbarch = target_thread_architecture (lp->ptid);
int syscall_number = (int) gdbarch_get_syscall_number (gdbarch, lp->ptid); thread_info *thread = find_thread_ptid (lp->ptid);
int syscall_number = (int) gdbarch_get_syscall_number (gdbarch, thread);
if (stopping) if (stopping)
{ {

View file

@ -210,8 +210,9 @@ struct thread_db_info
bookkeeping. */ bookkeeping. */
struct thread_db_info *thread_db_list; struct thread_db_info *thread_db_list;
static void thread_db_find_new_threads_1 (ptid_t ptid); static void thread_db_find_new_threads_1 (thread_info *stopped);
static void thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new); static void thread_db_find_new_threads_2 (thread_info *stopped,
bool until_no_new);
static void check_thread_signals (void); static void check_thread_signals (void);
@ -376,10 +377,11 @@ thread_db_err_str (td_err_e err)
} }
} }
/* Fetch the user-level thread id of PTID. */ /* Fetch the user-level thread id of PTID. STOPPED is a stopped
thread that we can use to access memory. */
static struct thread_info * static struct thread_info *
thread_from_lwp (ptid_t ptid) thread_from_lwp (thread_info *stopped, ptid_t ptid)
{ {
td_thrhandle_t th; td_thrhandle_t th;
td_thrinfo_t ti; td_thrinfo_t ti;
@ -397,7 +399,7 @@ thread_from_lwp (ptid_t ptid)
info = get_thread_db_info (ptid_get_pid (ptid)); info = get_thread_db_info (ptid_get_pid (ptid));
/* Access an lwp we know is stopped. */ /* Access an lwp we know is stopped. */
info->proc_handle.ptid = ptid; info->proc_handle.thread = stopped;
err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid_get_lwp (ptid), err = info->td_ta_map_lwp2thr_p (info->thread_agent, ptid_get_lwp (ptid),
&th); &th);
if (err != TD_OK) if (err != TD_OK)
@ -427,11 +429,13 @@ thread_db_notice_clone (ptid_t parent, ptid_t child)
if (info == NULL) if (info == NULL)
return 0; return 0;
thread_from_lwp (child); thread_info *stopped = find_thread_ptid (parent);
/* If we do not know about the main thread yet, this would be a good thread_from_lwp (stopped, child);
time to find it. */
thread_from_lwp (parent); /* If we do not know about the main thread's pthread info yet, this
would be a good time to find it. */
thread_from_lwp (stopped, parent);
return 1; return 1;
} }
@ -482,12 +486,12 @@ inferior_has_bug (const char *ver_symbol, int ver_major_min, int ver_minor_min)
otherwise. */ otherwise. */
static int static int
thread_db_find_new_threads_silently (ptid_t ptid) thread_db_find_new_threads_silently (thread_info *stopped)
{ {
TRY TRY
{ {
thread_db_find_new_threads_2 (ptid, 1); thread_db_find_new_threads_2 (stopped, true);
} }
CATCH (except, RETURN_MASK_ERROR) CATCH (except, RETURN_MASK_ERROR)
@ -823,7 +827,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
CHK (TDB_VERBOSE_DLSYM (info, td_ta_new)); CHK (TDB_VERBOSE_DLSYM (info, td_ta_new));
/* Initialize the structure that identifies the child process. */ /* Initialize the structure that identifies the child process. */
info->proc_handle.ptid = inferior_ptid; info->proc_handle.thread = inferior_thread ();
/* Now attempt to open a connection to the thread library. */ /* Now attempt to open a connection to the thread library. */
err = info->td_ta_new_p (&info->proc_handle, &info->thread_agent); err = info->td_ta_new_p (&info->proc_handle, &info->thread_agent);
@ -887,16 +891,17 @@ try_thread_db_load_1 (struct thread_db_info *info)
{ {
struct lwp_info *lp; struct lwp_info *lp;
int pid = ptid_get_pid (inferior_ptid); int pid = ptid_get_pid (inferior_ptid);
thread_info *curr_thread = inferior_thread ();
linux_stop_and_wait_all_lwps (); linux_stop_and_wait_all_lwps ();
ALL_LWPS (lp) ALL_LWPS (lp)
if (ptid_get_pid (lp->ptid) == pid) if (ptid_get_pid (lp->ptid) == pid)
thread_from_lwp (lp->ptid); thread_from_lwp (curr_thread, lp->ptid);
linux_unstop_all_lwps (); linux_unstop_all_lwps ();
} }
else if (thread_db_find_new_threads_silently (inferior_ptid) != 0) else if (thread_db_find_new_threads_silently (inferior_thread ()) != 0)
{ {
/* Even if libthread_db initializes, if the thread list is /* Even if libthread_db initializes, if the thread list is
corrupted, we'd not manage to list any threads. Better reject this corrupted, we'd not manage to list any threads. Better reject this
@ -1397,7 +1402,7 @@ thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
} }
/* Fill in the thread's user-level thread id and status. */ /* Fill in the thread's user-level thread id and status. */
thread_from_lwp (ptid); thread_from_lwp (find_thread_ptid (ptid), ptid);
return ptid; return ptid;
} }
@ -1425,7 +1430,6 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
{ {
td_thrinfo_t ti; td_thrinfo_t ti;
td_err_e err; td_err_e err;
ptid_t ptid;
struct thread_info *tp; struct thread_info *tp;
struct callback_data *cb_data = (struct callback_data *) data; struct callback_data *cb_data = (struct callback_data *) data;
struct thread_db_info *info = cb_data->info; struct thread_db_info *info = cb_data->info;
@ -1476,7 +1480,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
return 0; return 0;
} }
ptid = ptid_build (info->pid, ti.ti_lid, 0); ptid_t ptid (info->pid, ti.ti_lid);
tp = find_thread_ptid (ptid); tp = find_thread_ptid (ptid);
if (tp == NULL || tp->priv == NULL) if (tp == NULL || tp->priv == NULL)
record_thread (info, tp, ptid, th_p, &ti); record_thread (info, tp, ptid, th_p, &ti);
@ -1539,16 +1543,16 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
searches in a row do not discover any new threads. */ searches in a row do not discover any new threads. */
static void static void
thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new) thread_db_find_new_threads_2 (thread_info *stopped, bool until_no_new)
{ {
td_err_e err = TD_OK; td_err_e err = TD_OK;
struct thread_db_info *info; struct thread_db_info *info;
int i, loop; int i, loop;
info = get_thread_db_info (ptid_get_pid (ptid)); info = get_thread_db_info (stopped->ptid.pid ());
/* Access an lwp we know is stopped. */ /* Access an lwp we know is stopped. */
info->proc_handle.ptid = ptid; info->proc_handle.thread = stopped;
if (until_no_new) if (until_no_new)
{ {
@ -1571,9 +1575,9 @@ thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new)
} }
static void static void
thread_db_find_new_threads_1 (ptid_t ptid) thread_db_find_new_threads_1 (thread_info *stopped)
{ {
thread_db_find_new_threads_2 (ptid, 0); thread_db_find_new_threads_2 (stopped, 0);
} }
/* Implement the to_update_thread_list target method for this /* Implement the to_update_thread_list target method for this
@ -1598,7 +1602,7 @@ thread_db_target::update_thread_list ()
if (info == NULL) if (info == NULL)
continue; continue;
thread = any_live_thread_of_process (inf->pid); thread = any_live_thread_of_inferior (inf);
if (thread == NULL || thread->executing) if (thread == NULL || thread->executing)
continue; continue;
@ -1616,7 +1620,7 @@ thread_db_target::update_thread_list ()
if (target_has_execution_1 (thread->ptid)) if (target_has_execution_1 (thread->ptid))
continue; continue;
thread_db_find_new_threads_1 (thread->ptid); thread_db_find_new_threads_1 (thread);
} }
/* Give the beneath target a chance to do extra processing. */ /* Give the beneath target a chance to do extra processing. */
@ -1706,7 +1710,7 @@ thread_db_target::get_thread_local_address (ptid_t ptid,
/* We may not have discovered the thread yet. */ /* We may not have discovered the thread yet. */
if (thread_info != NULL && thread_info->priv == NULL) if (thread_info != NULL && thread_info->priv == NULL)
thread_info = thread_from_lwp (ptid); thread_info = thread_from_lwp (thread_info, ptid);
if (thread_info != NULL && thread_info->priv != NULL) if (thread_info != NULL && thread_info->priv != NULL)
{ {

View file

@ -31,6 +31,7 @@
#include "gdbthread.h" #include "gdbthread.h"
#include "mi-parse.h" #include "mi-parse.h"
#include "common/gdb_optional.h" #include "common/gdb_optional.h"
#include "inferior.h"
extern unsigned int varobjdebug; /* defined in varobj.c. */ extern unsigned int varobjdebug; /* defined in varobj.c. */
@ -600,22 +601,21 @@ static void
mi_cmd_var_update_iter (struct varobj *var, void *data_pointer) mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
{ {
struct mi_cmd_var_update *data = (struct mi_cmd_var_update *) data_pointer; struct mi_cmd_var_update *data = (struct mi_cmd_var_update *) data_pointer;
int thread_id, thread_stopped; bool thread_stopped;
thread_id = varobj_get_thread_id (var); int thread_id = varobj_get_thread_id (var);
if (thread_id == -1 if (thread_id == -1)
&& (ptid_equal (inferior_ptid, null_ptid) {
|| is_stopped (inferior_ptid))) thread_stopped = (inferior_ptid == null_ptid
thread_stopped = 1; || inferior_thread ()->state == THREAD_STOPPED);
}
else else
{ {
struct thread_info *tp = find_thread_global_id (thread_id); thread_info *tp = find_thread_global_id (thread_id);
if (tp) thread_stopped = (tp == NULL
thread_stopped = is_stopped (tp->ptid); || tp->state == THREAD_STOPPED);
else
thread_stopped = 1;
} }
if (thread_stopped if (thread_stopped

View file

@ -328,10 +328,6 @@ mi_interp::pre_command_loop ()
static void static void
mi_new_thread (struct thread_info *t) mi_new_thread (struct thread_info *t)
{ {
struct inferior *inf = find_inferior_ptid (t->ptid);
gdb_assert (inf);
SWITCH_THRU_ALL_UIS () SWITCH_THRU_ALL_UIS ()
{ {
struct mi_interp *mi = as_mi_interp (top_level_interpreter ()); struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
@ -344,7 +340,7 @@ mi_new_thread (struct thread_info *t)
fprintf_unfiltered (mi->event_channel, fprintf_unfiltered (mi->event_channel,
"thread-created,id=\"%d\",group-id=\"i%d\"", "thread-created,id=\"%d\",group-id=\"i%d\"",
t->global_num, inf->num); t->global_num, t->inf->num);
gdb_flush (mi->event_channel); gdb_flush (mi->event_channel);
} }
} }
@ -658,7 +654,7 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
else else
mi_uiout->field_string ("stopped-threads", "all"); mi_uiout->field_string ("stopped-threads", "all");
core = target_core_of_thread (inferior_ptid); core = target_core_of_thread (tp->ptid);
if (core != -1) if (core != -1)
mi_uiout->field_int ("core", core); mi_uiout->field_int ("core", core);
} }
@ -939,11 +935,9 @@ mi_breakpoint_modified (struct breakpoint *b)
} }
} }
static int static void
mi_output_running_pid (struct thread_info *info, void *arg) mi_output_running (struct thread_info *thread)
{ {
ptid_t *ptid = (ptid_t *) arg;
SWITCH_THRU_ALL_UIS () SWITCH_THRU_ALL_UIS ()
{ {
struct mi_interp *mi = as_mi_interp (top_level_interpreter ()); struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
@ -951,25 +945,10 @@ mi_output_running_pid (struct thread_info *info, void *arg)
if (mi == NULL) if (mi == NULL)
continue; continue;
if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) fprintf_unfiltered (mi->raw_stdout,
fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n",
"*running,thread-id=\"%d\"\n", thread->global_num);
info->global_num);
} }
return 0;
}
static int
mi_inferior_count (struct inferior *inf, void *arg)
{
if (inf->pid != 0)
{
int *count_p = (int *) arg;
(*count_p)++;
}
return 0;
} }
static void static void
@ -994,24 +973,37 @@ mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
else if (ptid_is_pid (ptid)) else if (ptid_is_pid (ptid))
{ {
int count = 0; int count = 0;
inferior *inf;
/* Backwards compatibility. If there's only one inferior, /* Backwards compatibility. If there's only one inferior,
output "all", otherwise, output each resumed thread output "all", otherwise, output each resumed thread
individually. */ individually. */
iterate_over_inferiors (mi_inferior_count, &count); ALL_INFERIORS (inf)
if (inf->pid != 0)
{
count++;
if (count > 1)
break;
}
if (count == 1) if (count == 1)
fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n"); fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
else else
iterate_over_threads (mi_output_running_pid, &ptid); {
thread_info *tp;
inferior *curinf = current_inferior ();
ALL_NON_EXITED_THREADS (tp)
if (tp->inf == curinf)
mi_output_running (tp);
}
} }
else else
{ {
struct thread_info *ti = find_thread_ptid (ptid); thread_info *ti = find_thread_ptid (ptid);
gdb_assert (ti); gdb_assert (ti);
fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n", mi_output_running (ti);
ti->global_num);
} }
if (!running_result_record_printed && mi_proceeded) if (!running_result_record_printed && mi_proceeded)
@ -1234,7 +1226,10 @@ mi_user_selected_context_changed (user_selected_what selection)
if (mi_suppress_notification.user_selected_context) if (mi_suppress_notification.user_selected_context)
return; return;
tp = find_thread_ptid (inferior_ptid); if (inferior_ptid != null_ptid)
tp = inferior_thread ();
else
tp = NULL;
SWITCH_THRU_ALL_UIS () SWITCH_THRU_ALL_UIS ()
{ {

View file

@ -243,13 +243,13 @@ mi_cmd_exec_jump (const char *args, char **argv, int argc)
static void static void
proceed_thread (struct thread_info *thread, int pid) proceed_thread (struct thread_info *thread, int pid)
{ {
if (!is_stopped (thread->ptid)) if (thread->state != THREAD_STOPPED)
return; return;
if (pid != 0 && ptid_get_pid (thread->ptid) != pid) if (pid != 0 && ptid_get_pid (thread->ptid) != pid)
return; return;
switch_to_thread (thread->ptid); switch_to_thread (thread);
clear_proceed_status (0); clear_proceed_status (0);
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
} }
@ -345,7 +345,7 @@ interrupt_thread_callback (struct thread_info *thread, void *arg)
{ {
int pid = *(int *)arg; int pid = *(int *)arg;
if (!is_running (thread->ptid)) if (thread->state != THREAD_RUNNING)
return 0; return 0;
if (ptid_get_pid (thread->ptid) != pid) if (ptid_get_pid (thread->ptid) != pid)
@ -409,21 +409,16 @@ run_one_inferior (struct inferior *inf, void *arg)
if (inf->pid != 0) if (inf->pid != 0)
{ {
if (inf->pid != ptid_get_pid (inferior_ptid)) thread_info *tp = any_thread_of_inferior (inf);
{ if (tp == NULL)
struct thread_info *tp; error (_("Inferior has no threads."));
tp = any_thread_of_process (inf->pid); switch_to_thread (tp);
if (!tp)
error (_("Inferior has no threads."));
switch_to_thread (tp->ptid);
}
} }
else else
{ {
set_current_inferior (inf); set_current_inferior (inf);
switch_to_thread (null_ptid); switch_to_no_thread ();
set_current_program_space (inf->pspace); set_current_program_space (inf->pspace);
} }
mi_execute_cli_command (run_cmd, async_p, mi_execute_cli_command (run_cmd, async_p,
@ -492,7 +487,7 @@ find_thread_of_process (struct thread_info *ti, void *p)
{ {
int pid = *(int *)p; int pid = *(int *)p;
if (ptid_get_pid (ti->ptid) == pid && !is_exited (ti->ptid)) if (ptid_get_pid (ti->ptid) == pid && ti->state != THREAD_EXITED)
return 1; return 1;
return 0; return 0;
@ -540,7 +535,7 @@ mi_cmd_target_detach (const char *command, char **argv, int argc)
if (!tp) if (!tp)
error (_("Thread group is empty")); error (_("Thread group is empty"));
switch_to_thread (tp->ptid); switch_to_thread (tp);
} }
detach_command (NULL, 0); detach_command (NULL, 0);
@ -1771,8 +1766,11 @@ mi_cmd_remove_inferior (const char *command, char **argv, int argc)
set_current_inferior (new_inferior); set_current_inferior (new_inferior);
if (new_inferior->pid != 0) if (new_inferior->pid != 0)
tp = any_thread_of_process (new_inferior->pid); tp = any_thread_of_inferior (new_inferior);
switch_to_thread (tp ? tp->ptid : null_ptid); if (tp != NULL)
switch_to_thread (tp);
else
switch_to_no_thread ();
set_current_program_space (new_inferior->pspace); set_current_program_space (new_inferior->pspace);
} }
@ -2058,22 +2056,25 @@ mi_cmd_execute (struct mi_parse *parse)
provide --thread if it wishes to operate on a specific provide --thread if it wishes to operate on a specific
thread. */ thread. */
if (inf->pid != 0) if (inf->pid != 0)
tp = any_live_thread_of_process (inf->pid); tp = any_live_thread_of_inferior (inf);
switch_to_thread (tp ? tp->ptid : null_ptid); if (tp != NULL)
switch_to_thread (tp);
else
switch_to_no_thread ();
set_current_program_space (inf->pspace); set_current_program_space (inf->pspace);
} }
if (parse->thread != -1) if (parse->thread != -1)
{ {
struct thread_info *tp = find_thread_global_id (parse->thread); thread_info *tp = find_thread_global_id (parse->thread);
if (!tp) if (tp == NULL)
error (_("Invalid thread id: %d"), parse->thread); error (_("Invalid thread id: %d"), parse->thread);
if (is_exited (tp->ptid)) if (tp->state == THREAD_EXITED)
error (_("Thread id: %d has terminated"), parse->thread); error (_("Thread id: %d has terminated"), parse->thread);
switch_to_thread (tp->ptid); switch_to_thread (tp);
} }
if (parse->frame != -1) if (parse->frame != -1)

View file

@ -1314,9 +1314,9 @@ mips_linux_syscall_next_pc (struct frame_info *frame)
static LONGEST static LONGEST
mips_linux_get_syscall_number (struct gdbarch *gdbarch, mips_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int regsize = register_size (gdbarch, MIPS_V0_REGNUM); int regsize = register_size (gdbarch, MIPS_V0_REGNUM);

View file

@ -803,9 +803,9 @@ ppc_linux_trap_reg_p (struct gdbarch *gdbarch)
r0 register. When the function fails, it returns -1. */ r0 register. When the function fails, it returns -1. */
static LONGEST static LONGEST
ppc_linux_get_syscall_number (struct gdbarch *gdbarch, ppc_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

View file

@ -21,6 +21,7 @@
#include "gdbcore.h" #include "gdbcore.h"
#include "inferior.h" #include "inferior.h"
#include "gdbthread.h"
#include "symtab.h" #include "symtab.h"
#include "target.h" #include "target.h"
#include "regcache.h" #include "regcache.h"
@ -73,7 +74,7 @@ ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr,
int ret; int ret;
CORE_ADDR core_addr = ps_addr_to_core_addr (addr); CORE_ADDR core_addr = ps_addr_to_core_addr (addr);
inferior_ptid = ph->ptid; inferior_ptid = ph->thread->ptid;
if (write) if (write)
ret = target_write_memory (core_addr, buf, len); ret = target_write_memory (core_addr, buf, len);
@ -92,7 +93,7 @@ ps_err_e
ps_pglobal_lookup (struct ps_prochandle *ph, const char *obj, ps_pglobal_lookup (struct ps_prochandle *ph, const char *obj,
const char *name, psaddr_t *sym_addr) const char *name, psaddr_t *sym_addr)
{ {
struct inferior *inf = find_inferior_ptid (ph->ptid); inferior *inf = ph->thread->inf;
scoped_restore_current_program_space restore_pspace; scoped_restore_current_program_space restore_pspace;
@ -131,9 +132,7 @@ ps_pdwrite (struct ps_prochandle *ph, psaddr_t addr,
ps_err_e ps_err_e
ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset) ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
{ {
ptid_t ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); struct regcache *regcache = get_thread_regcache (ph->thread);
struct regcache *regcache
= get_thread_arch_regcache (ptid, target_gdbarch ());
target_fetch_registers (regcache, -1); target_fetch_registers (regcache, -1);
fill_gregset (regcache, (gdb_gregset_t *) gregset, -1); fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
@ -147,9 +146,7 @@ ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
ps_err_e ps_err_e
ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset) ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset)
{ {
ptid_t ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); struct regcache *regcache = get_thread_regcache (ph->thread);
struct regcache *regcache
= get_thread_arch_regcache (ptid, target_gdbarch ());
supply_gregset (regcache, (const gdb_gregset_t *) gregset); supply_gregset (regcache, (const gdb_gregset_t *) gregset);
target_store_registers (regcache, -1); target_store_registers (regcache, -1);
@ -163,9 +160,7 @@ ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset)
ps_err_e ps_err_e
ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, gdb_prfpregset_t *fpregset) ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, gdb_prfpregset_t *fpregset)
{ {
ptid_t ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); struct regcache *regcache = get_thread_regcache (ph->thread);
struct regcache *regcache
= get_thread_arch_regcache (ptid, target_gdbarch ());
target_fetch_registers (regcache, -1); target_fetch_registers (regcache, -1);
fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
@ -180,9 +175,7 @@ ps_err_e
ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
const gdb_prfpregset_t *fpregset) const gdb_prfpregset_t *fpregset)
{ {
ptid_t ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); struct regcache *regcache = get_thread_regcache (ph->thread);
struct regcache *regcache
= get_thread_arch_regcache (ptid, target_gdbarch ());
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset); supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
target_store_registers (regcache, -1); target_store_registers (regcache, -1);
@ -196,7 +189,7 @@ ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
pid_t pid_t
ps_getpid (struct ps_prochandle *ph) ps_getpid (struct ps_prochandle *ph)
{ {
return ptid_get_pid (ph->ptid); return ptid_get_pid (ph->thread->ptid);
} }
void void

View file

@ -17,6 +17,7 @@
#include "defs.h" #include "defs.h"
#include "progspace-and-thread.h" #include "progspace-and-thread.h"
#include "inferior.h"
/* See progspace-and-thread.h */ /* See progspace-and-thread.h */
@ -27,17 +28,17 @@ switch_to_program_space_and_thread (program_space *pspace)
if (inf != NULL && inf->pid != 0) if (inf != NULL && inf->pid != 0)
{ {
thread_info *tp = any_live_thread_of_process (inf->pid); thread_info *tp = any_live_thread_of_inferior (inf);
if (tp != NULL) if (tp != NULL)
{ {
switch_to_thread (tp->ptid); switch_to_thread (tp);
/* Switching thread switches pspace implicitly. We're /* Switching thread switches pspace implicitly. We're
done. */ done. */
return; return;
} }
} }
switch_to_thread (null_ptid); switch_to_no_thread ();
set_current_program_space (pspace); set_current_program_space (pspace);
} }

View file

@ -24,6 +24,7 @@
#include "gdbcore.h" #include "gdbcore.h"
#include "solib.h" #include "solib.h"
#include "gdbthread.h" #include "gdbthread.h"
#include "inferior.h"
/* The last program space number assigned. */ /* The last program space number assigned. */
int last_program_space_num = 0; int last_program_space_num = 0;

View file

@ -39,10 +39,10 @@ create_exited_event_object (const LONGEST *exit_code, struct inferior *inf)
return NULL; return NULL;
} }
gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (inf));
if (inf_obj == NULL || evpy_add_attribute (exited_event.get (), if (inf_obj == NULL || evpy_add_attribute (exited_event.get (),
"inferior", "inferior",
inf_obj.get ()) < 0) (PyObject *) inf_obj.get ()) < 0)
return NULL; return NULL;
return exited_event.release (); return exited_event.release ();

View file

@ -221,14 +221,15 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
if (PyErr_Occurred ()) if (PyErr_Occurred ())
return -1; return -1;
thread = ptid_to_global_thread_id (inferior_ptid); if (inferior_ptid == null_ptid)
if (thread == 0)
{ {
PyErr_SetString (PyExc_ValueError, PyErr_SetString (PyExc_ValueError,
_("No thread currently selected.")); _("No thread currently selected."));
return -1; return -1;
} }
thread = inferior_thread ()->global_num;
if (internal) if (internal)
{ {
internal_bp = PyObject_IsTrue (internal); internal_bp = PyObject_IsTrue (internal);

View file

@ -35,7 +35,7 @@ struct threadlist_entry {
struct threadlist_entry *next; struct threadlist_entry *next;
}; };
typedef struct struct inferior_object
{ {
PyObject_HEAD PyObject_HEAD
@ -48,7 +48,7 @@ typedef struct
/* Number of threads in the list. */ /* Number of threads in the list. */
int nthreads; int nthreads;
} inferior_object; };
extern PyTypeObject inferior_object_type extern PyTypeObject inferior_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object"); CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
@ -207,7 +207,8 @@ python_new_objfile (struct objfile *objfile)
representing INFERIOR. If the object has already been created, representing INFERIOR. If the object has already been created,
return it and increment the reference count, otherwise, create it. return it and increment the reference count, otherwise, create it.
Return NULL on failure. */ Return NULL on failure. */
PyObject *
inferior_object *
inferior_to_inferior_object (struct inferior *inferior) inferior_to_inferior_object (struct inferior *inferior)
{ {
inferior_object *inf_obj; inferior_object *inf_obj;
@ -232,7 +233,7 @@ inferior_to_inferior_object (struct inferior *inferior)
/* We are returning a new reference. */ /* We are returning a new reference. */
Py_INCREF ((PyObject *)inf_obj); Py_INCREF ((PyObject *)inf_obj);
return (PyObject *) inf_obj; return inf_obj;
} }
/* Called when a new inferior is created. Notifies any Python event /* Called when a new inferior is created. Notifies any Python event
@ -248,7 +249,7 @@ python_new_inferior (struct inferior *inf)
if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
return; return;
gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (inf));
if (inf_obj == NULL) if (inf_obj == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();
@ -257,7 +258,8 @@ python_new_inferior (struct inferior *inf)
gdbpy_ref<> event (create_event_object (&new_inferior_event_object_type)); gdbpy_ref<> event (create_event_object (&new_inferior_event_object_type));
if (event == NULL if (event == NULL
|| evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 || evpy_add_attribute (event.get (), "inferior",
(PyObject *) inf_obj.get ()) < 0
|| evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0) || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
gdbpy_print_stack (); gdbpy_print_stack ();
} }
@ -275,7 +277,7 @@ python_inferior_deleted (struct inferior *inf)
if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
return; return;
gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (inf));
if (inf_obj == NULL) if (inf_obj == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();
@ -284,7 +286,8 @@ python_inferior_deleted (struct inferior *inf)
gdbpy_ref<> event (create_event_object (&inferior_deleted_event_object_type)); gdbpy_ref<> event (create_event_object (&inferior_deleted_event_object_type));
if (event == NULL if (event == NULL
|| evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 || evpy_add_attribute (event.get (), "inferior",
(PyObject *) inf_obj.get ()) < 0
|| evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0) || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
gdbpy_print_stack (); gdbpy_print_stack ();
} }
@ -298,28 +301,22 @@ find_inferior_object (int pid)
struct inferior *inf = find_inferior_pid (pid); struct inferior *inf = find_inferior_pid (pid);
if (inf) if (inf)
return inferior_to_inferior_object (inf); return (PyObject *) inferior_to_inferior_object (inf);
return NULL; return NULL;
} }
thread_object * thread_object *
find_thread_object (ptid_t ptid) thread_to_thread_object (thread_info *thr)
{ {
int pid; gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (thr->inf));
struct threadlist_entry *thread;
pid = ptid_get_pid (ptid);
if (pid == 0)
return NULL;
gdbpy_ref<> inf_obj (find_inferior_object (pid));
if (inf_obj == NULL) if (inf_obj == NULL)
return NULL; return NULL;
for (thread = ((inferior_object *)(inf_obj.get ()))->threads; thread; for (threadlist_entry *thread = inf_obj->threads;
thread != NULL;
thread = thread->next) thread = thread->next)
if (ptid_equal (thread->thread_obj->thread->ptid, ptid)) if (thread->thread_obj->thread == thr)
return thread->thread_obj; return thread->thread_obj;
return NULL; return NULL;
@ -374,7 +371,7 @@ delete_thread_object (struct thread_info *tp, int ignore)
gdbpy_enter enter_py (python_gdbarch, python_language); gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_ref<inferior_object> inf_obj gdbpy_ref<inferior_object> inf_obj
((inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid))); ((inferior_object *) inferior_to_inferior_object (tp->inf));
if (inf_obj == NULL) if (inf_obj == NULL)
return; return;
@ -466,12 +463,12 @@ static int
build_inferior_list (struct inferior *inf, void *arg) build_inferior_list (struct inferior *inf, void *arg)
{ {
PyObject *list = (PyObject *) arg; PyObject *list = (PyObject *) arg;
gdbpy_ref<> inferior (inferior_to_inferior_object (inf)); gdbpy_ref<inferior_object> inferior (inferior_to_inferior_object (inf));
if (inferior == NULL) if (inferior == NULL)
return 0; return 0;
return PyList_Append (list, inferior.get ()) ? 1 : 0; return PyList_Append (list, (PyObject *) inferior.get ()) ? 1 : 0;
} }
/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
@ -848,7 +845,7 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
thread_info = find_thread_by_handle (val, inf_obj->inferior); thread_info = find_thread_by_handle (val, inf_obj->inferior);
if (thread_info != NULL) if (thread_info != NULL)
{ {
result = (PyObject *) find_thread_object (thread_info->ptid); result = (PyObject *) thread_to_thread_object (thread_info);
if (result != NULL) if (result != NULL)
Py_INCREF (result); Py_INCREF (result);
} }
@ -910,7 +907,7 @@ py_free_inferior (struct inferior *inf, void *datum)
PyObject * PyObject *
gdbpy_selected_inferior (PyObject *self, PyObject *args) gdbpy_selected_inferior (PyObject *self, PyObject *args)
{ {
return inferior_to_inferior_object (current_inferior ()); return (PyObject *) inferior_to_inferior_object (current_inferior ());
} }
int int

View file

@ -46,7 +46,7 @@ create_thread_object (struct thread_info *tp)
return NULL; return NULL;
thread_obj->thread = tp; thread_obj->thread = tp;
thread_obj->inf_obj = find_inferior_object (ptid_get_pid (tp->ptid)); thread_obj->inf_obj = (PyObject *) inferior_to_inferior_object (tp->inf);
return thread_obj; return thread_obj;
} }
@ -179,7 +179,7 @@ thpy_switch (PyObject *self, PyObject *args)
TRY TRY
{ {
switch_to_thread (thread_obj->thread->ptid); switch_to_thread (thread_obj->thread);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -200,7 +200,7 @@ thpy_is_stopped (PyObject *self, PyObject *args)
THPY_REQUIRE_VALID (thread_obj); THPY_REQUIRE_VALID (thread_obj);
if (is_stopped (thread_obj->thread->ptid)) if (thread_obj->thread->state == THREAD_STOPPED)
Py_RETURN_TRUE; Py_RETURN_TRUE;
Py_RETURN_FALSE; Py_RETURN_FALSE;
@ -216,7 +216,7 @@ thpy_is_running (PyObject *self, PyObject *args)
THPY_REQUIRE_VALID (thread_obj); THPY_REQUIRE_VALID (thread_obj);
if (is_running (thread_obj->thread->ptid)) if (thread_obj->thread->state == THREAD_RUNNING)
Py_RETURN_TRUE; Py_RETURN_TRUE;
Py_RETURN_FALSE; Py_RETURN_FALSE;
@ -232,7 +232,7 @@ thpy_is_exited (PyObject *self, PyObject *args)
THPY_REQUIRE_VALID (thread_obj); THPY_REQUIRE_VALID (thread_obj);
if (is_exited (thread_obj->thread->ptid)) if (thread_obj->thread->state == THREAD_EXITED)
Py_RETURN_TRUE; Py_RETURN_TRUE;
Py_RETURN_FALSE; Py_RETURN_FALSE;
@ -283,13 +283,15 @@ gdbpy_create_ptid_object (ptid_t ptid)
PyObject * PyObject *
gdbpy_selected_thread (PyObject *self, PyObject *args) gdbpy_selected_thread (PyObject *self, PyObject *args)
{ {
PyObject *thread_obj; if (inferior_ptid != null_ptid)
thread_obj = (PyObject *) find_thread_object (inferior_ptid);
if (thread_obj)
{ {
Py_INCREF (thread_obj); PyObject *thread_obj
return thread_obj; = (PyObject *) thread_to_thread_object (inferior_thread ());
if (thread_obj != NULL)
{
Py_INCREF (thread_obj);
return thread_obj;
}
} }
Py_RETURN_NONE; Py_RETURN_NONE;

View file

@ -43,7 +43,7 @@ typedef struct {
PyObject_HEAD PyObject_HEAD
/* The thread this list belongs to. */ /* The thread this list belongs to. */
ptid_t ptid; thread_info *thread;
/* The first index being part of this list. */ /* The first index being part of this list. */
Py_ssize_t first; Py_ssize_t first;
@ -82,7 +82,7 @@ btrace_insn_from_recpy_insn (const PyObject * const pyobject)
} }
obj = (const recpy_element_object *) pyobject; obj = (const recpy_element_object *) pyobject;
tinfo = find_thread_ptid (obj->ptid); tinfo = obj->thread;
if (tinfo == NULL || btrace_is_empty (tinfo)) if (tinfo == NULL || btrace_is_empty (tinfo))
{ {
@ -125,7 +125,7 @@ btrace_func_from_recpy_func (const PyObject * const pyobject)
} }
obj = (const recpy_element_object *) pyobject; obj = (const recpy_element_object *) pyobject;
tinfo = find_thread_ptid (obj->ptid); tinfo = obj->thread;
if (tinfo == NULL || btrace_is_empty (tinfo)) if (tinfo == NULL || btrace_is_empty (tinfo))
{ {
@ -153,7 +153,7 @@ btrace_func_from_recpy_func (const PyObject * const pyobject)
gdb.RecordInstruction or gdb.RecordGap object for it accordingly. */ gdb.RecordInstruction or gdb.RecordGap object for it accordingly. */
static PyObject * static PyObject *
btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number) btpy_insn_or_gap_new (thread_info *tinfo, Py_ssize_t number)
{ {
btrace_insn_iterator iter; btrace_insn_iterator iter;
int err_code; int err_code;
@ -172,13 +172,13 @@ btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
return recpy_gap_new (err_code, err_string, number); return recpy_gap_new (err_code, err_string, number);
} }
return recpy_insn_new (tinfo->ptid, RECORD_METHOD_BTRACE, number); return recpy_insn_new (tinfo, RECORD_METHOD_BTRACE, number);
} }
/* Create a new gdb.BtraceList object. */ /* Create a new gdb.BtraceList object. */
static PyObject * static PyObject *
btpy_list_new (ptid_t ptid, Py_ssize_t first, Py_ssize_t last, Py_ssize_t step, btpy_list_new (thread_info *thread, Py_ssize_t first, Py_ssize_t last, Py_ssize_t step,
PyTypeObject *element_type) PyTypeObject *element_type)
{ {
btpy_list_object * const obj = PyObject_New (btpy_list_object, btpy_list_object * const obj = PyObject_New (btpy_list_object,
@ -187,7 +187,7 @@ btpy_list_new (ptid_t ptid, Py_ssize_t first, Py_ssize_t last, Py_ssize_t step,
if (obj == NULL) if (obj == NULL)
return NULL; return NULL;
obj->ptid = ptid; obj->thread = thread;
obj->first = first; obj->first = first;
obj->last = last; obj->last = last;
obj->step = step; obj->step = step;
@ -344,7 +344,7 @@ recpy_bt_func_level (PyObject *self, void *closure)
if (func == NULL) if (func == NULL)
return NULL; return NULL;
tinfo = find_thread_ptid (((recpy_element_object *) self)->ptid); tinfo = ((recpy_element_object *) self)->thread;
return PyInt_FromLong (tinfo->btrace.level + func->level); return PyInt_FromLong (tinfo->btrace.level + func->level);
} }
@ -383,7 +383,7 @@ recpy_bt_func_instructions (PyObject *self, void *closure)
if (len == 0) if (len == 0)
len = 1; len = 1;
return btpy_list_new (((recpy_element_object *) self)->ptid, return btpy_list_new (((recpy_element_object *) self)->thread,
func->insn_offset, func->insn_offset + len, 1, func->insn_offset, func->insn_offset + len, 1,
&recpy_insn_type); &recpy_insn_type);
} }
@ -402,7 +402,7 @@ recpy_bt_func_up (PyObject *self, void *closure)
if (func->up == 0) if (func->up == 0)
Py_RETURN_NONE; Py_RETURN_NONE;
return recpy_func_new (((recpy_element_object *) self)->ptid, return recpy_func_new (((recpy_element_object *) self)->thread,
RECORD_METHOD_BTRACE, func->up); RECORD_METHOD_BTRACE, func->up);
} }
@ -420,7 +420,7 @@ recpy_bt_func_prev (PyObject *self, void *closure)
if (func->prev == 0) if (func->prev == 0)
Py_RETURN_NONE; Py_RETURN_NONE;
return recpy_func_new (((recpy_element_object *) self)->ptid, return recpy_func_new (((recpy_element_object *) self)->thread,
RECORD_METHOD_BTRACE, func->prev); RECORD_METHOD_BTRACE, func->prev);
} }
@ -438,7 +438,7 @@ recpy_bt_func_next (PyObject *self, void *closure)
if (func->next == 0) if (func->next == 0)
Py_RETURN_NONE; Py_RETURN_NONE;
return recpy_func_new (((recpy_element_object *) self)->ptid, return recpy_func_new (((recpy_element_object *) self)->thread,
RECORD_METHOD_BTRACE, func->next); RECORD_METHOD_BTRACE, func->next);
} }
@ -474,9 +474,9 @@ btpy_list_item (PyObject *self, Py_ssize_t index)
number = obj->first + (obj->step * index); number = obj->first + (obj->step * index);
if (obj->element_type == &recpy_insn_type) if (obj->element_type == &recpy_insn_type)
return recpy_insn_new (obj->ptid, RECORD_METHOD_BTRACE, number); return recpy_insn_new (obj->thread, RECORD_METHOD_BTRACE, number);
else else
return recpy_func_new (obj->ptid, RECORD_METHOD_BTRACE, number); return recpy_func_new (obj->thread, RECORD_METHOD_BTRACE, number);
} }
/* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */ /* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */
@ -506,7 +506,7 @@ btpy_list_slice (PyObject *self, PyObject *value)
&step, &slicelength)) &step, &slicelength))
return NULL; return NULL;
return btpy_list_new (obj->ptid, obj->first + obj->step * start, return btpy_list_new (obj->thread, obj->first + obj->step * start,
obj->first + obj->step * stop, obj->step * step, obj->first + obj->step * stop, obj->step * step,
obj->element_type); obj->element_type);
} }
@ -524,7 +524,7 @@ btpy_list_position (PyObject *self, PyObject *value)
if (list_obj->element_type != Py_TYPE (value)) if (list_obj->element_type != Py_TYPE (value))
return -1; return -1;
if (!ptid_equal (list_obj->ptid, obj->ptid)) if (list_obj->thread != obj->thread)
return -1; return -1;
if (index < list_obj->first || index > list_obj->last) if (index < list_obj->first || index > list_obj->last)
@ -590,7 +590,7 @@ btpy_list_richcompare (PyObject *self, PyObject *other, int op)
switch (op) switch (op)
{ {
case Py_EQ: case Py_EQ:
if (ptid_equal (obj1->ptid, obj2->ptid) if (obj1->thread == obj2->thread
&& obj1->element_type == obj2->element_type && obj1->element_type == obj2->element_type
&& obj1->first == obj2->first && obj1->first == obj2->first
&& obj1->last == obj2->last && obj1->last == obj2->last
@ -600,7 +600,7 @@ btpy_list_richcompare (PyObject *self, PyObject *other, int op)
Py_RETURN_FALSE; Py_RETURN_FALSE;
case Py_NE: case Py_NE:
if (!ptid_equal (obj1->ptid, obj2->ptid) if (obj1->thread != obj2->thread
|| obj1->element_type != obj2->element_type || obj1->element_type != obj2->element_type
|| obj1->first != obj2->first || obj1->first != obj2->first
|| obj1->last != obj2->last || obj1->last != obj2->last
@ -633,7 +633,7 @@ PyObject *
recpy_bt_format (PyObject *self, void *closure) recpy_bt_format (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
const struct thread_info * const tinfo = find_thread_ptid (record->ptid); const struct thread_info * const tinfo = record->thread;
const struct btrace_config * config; const struct btrace_config * config;
if (tinfo == NULL) if (tinfo == NULL)
@ -654,7 +654,7 @@ PyObject *
recpy_bt_replay_position (PyObject *self, void *closure) recpy_bt_replay_position (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
const struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info * tinfo = record->thread;
if (tinfo == NULL) if (tinfo == NULL)
Py_RETURN_NONE; Py_RETURN_NONE;
@ -673,7 +673,7 @@ PyObject *
recpy_bt_begin (PyObject *self, void *closure) recpy_bt_begin (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info *const tinfo = record->thread;
struct btrace_insn_iterator iterator; struct btrace_insn_iterator iterator;
if (tinfo == NULL) if (tinfo == NULL)
@ -695,7 +695,7 @@ PyObject *
recpy_bt_end (PyObject *self, void *closure) recpy_bt_end (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info *const tinfo = record->thread;
struct btrace_insn_iterator iterator; struct btrace_insn_iterator iterator;
if (tinfo == NULL) if (tinfo == NULL)
@ -717,7 +717,7 @@ PyObject *
recpy_bt_instruction_history (PyObject *self, void *closure) recpy_bt_instruction_history (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info *const tinfo = record->thread;
struct btrace_insn_iterator iterator; struct btrace_insn_iterator iterator;
unsigned long first = 0; unsigned long first = 0;
unsigned long last = 0; unsigned long last = 0;
@ -736,7 +736,7 @@ recpy_bt_instruction_history (PyObject *self, void *closure)
btrace_insn_end (&iterator, &tinfo->btrace); btrace_insn_end (&iterator, &tinfo->btrace);
last = btrace_insn_number (&iterator); last = btrace_insn_number (&iterator);
return btpy_list_new (record->ptid, first, last, 1, &recpy_insn_type); return btpy_list_new (tinfo, first, last, 1, &recpy_insn_type);
} }
/* Implementation of /* Implementation of
@ -746,7 +746,7 @@ PyObject *
recpy_bt_function_call_history (PyObject *self, void *closure) recpy_bt_function_call_history (PyObject *self, void *closure)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info *const tinfo = record->thread;
struct btrace_call_iterator iterator; struct btrace_call_iterator iterator;
unsigned long first = 0; unsigned long first = 0;
unsigned long last = 0; unsigned long last = 0;
@ -765,7 +765,7 @@ recpy_bt_function_call_history (PyObject *self, void *closure)
btrace_call_end (&iterator, &tinfo->btrace); btrace_call_end (&iterator, &tinfo->btrace);
last = btrace_call_number (&iterator); last = btrace_call_number (&iterator);
return btpy_list_new (record->ptid, first, last, 1, &recpy_func_type); return btpy_list_new (tinfo, first, last, 1, &recpy_func_type);
} }
/* Implementation of BtraceRecord.goto (self, BtraceInstruction) -> None. */ /* Implementation of BtraceRecord.goto (self, BtraceInstruction) -> None. */
@ -774,7 +774,7 @@ PyObject *
recpy_bt_goto (PyObject *self, PyObject *args) recpy_bt_goto (PyObject *self, PyObject *args)
{ {
const recpy_record_object * const record = (recpy_record_object *) self; const recpy_record_object * const record = (recpy_record_object *) self;
struct thread_info * const tinfo = find_thread_ptid (record->ptid); thread_info *const tinfo = record->thread;
const recpy_element_object *obj; const recpy_element_object *obj;
if (tinfo == NULL || btrace_is_empty (tinfo)) if (tinfo == NULL || btrace_is_empty (tinfo))

View file

@ -23,6 +23,7 @@
#include "py-record-btrace.h" #include "py-record-btrace.h"
#include "py-record-full.h" #include "py-record-full.h"
#include "target.h" #include "target.h"
#include "gdbthread.h"
/* Python Record type. */ /* Python Record type. */
@ -176,7 +177,7 @@ recpy_end (PyObject *self, void* closure)
/* Create a new gdb.RecordInstruction object. */ /* Create a new gdb.RecordInstruction object. */
PyObject * PyObject *
recpy_insn_new (ptid_t ptid, enum record_method method, Py_ssize_t number) recpy_insn_new (thread_info *thread, enum record_method method, Py_ssize_t number)
{ {
recpy_element_object * const obj = PyObject_New (recpy_element_object, recpy_element_object * const obj = PyObject_New (recpy_element_object,
&recpy_insn_type); &recpy_insn_type);
@ -184,7 +185,7 @@ recpy_insn_new (ptid_t ptid, enum record_method method, Py_ssize_t number)
if (obj == NULL) if (obj == NULL)
return NULL; return NULL;
obj->ptid = ptid; obj->thread = thread;
obj->method = method; obj->method = method;
obj->number = number; obj->number = number;
@ -272,7 +273,7 @@ recpy_insn_is_speculative (PyObject *self, void *closure)
/* Create a new gdb.RecordFunctionSegment object. */ /* Create a new gdb.RecordFunctionSegment object. */
PyObject * PyObject *
recpy_func_new (ptid_t ptid, enum record_method method, Py_ssize_t number) recpy_func_new (thread_info *thread, enum record_method method, Py_ssize_t number)
{ {
recpy_element_object * const obj = PyObject_New (recpy_element_object, recpy_element_object * const obj = PyObject_New (recpy_element_object,
&recpy_func_type); &recpy_func_type);
@ -280,7 +281,7 @@ recpy_func_new (ptid_t ptid, enum record_method method, Py_ssize_t number)
if (obj == NULL) if (obj == NULL)
return NULL; return NULL;
obj->ptid = ptid; obj->thread = thread;
obj->method = method; obj->method = method;
obj->number = number; obj->number = number;
@ -405,7 +406,7 @@ recpy_element_richcompare (PyObject *self, PyObject *other, int op)
switch (op) switch (op)
{ {
case Py_EQ: case Py_EQ:
if (ptid_equal (obj1->ptid, obj2->ptid) if (obj1->thread == obj2->thread
&& obj1->method == obj2->method && obj1->method == obj2->method
&& obj1->number == obj2->number) && obj1->number == obj2->number)
Py_RETURN_TRUE; Py_RETURN_TRUE;
@ -413,7 +414,7 @@ recpy_element_richcompare (PyObject *self, PyObject *other, int op)
Py_RETURN_FALSE; Py_RETURN_FALSE;
case Py_NE: case Py_NE:
if (!ptid_equal (obj1->ptid, obj2->ptid) if (obj1->thread != obj2->thread
|| obj1->method != obj2->method || obj1->method != obj2->method
|| obj1->number != obj2->number) || obj1->number != obj2->number)
Py_RETURN_TRUE; Py_RETURN_TRUE;
@ -626,8 +627,8 @@ gdbpy_current_recording (PyObject *self, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
ret = PyObject_New (recpy_record_object, &recpy_record_type); ret = PyObject_New (recpy_record_object, &recpy_record_type);
ret->ptid = inferior_ptid; ret->thread = inferior_thread ();
ret->method = target_record_method (inferior_ptid); ret->method = target_record_method (ret->thread->ptid);
return (PyObject *) ret; return (PyObject *) ret;
} }

View file

@ -29,8 +29,8 @@ typedef struct
{ {
PyObject_HEAD PyObject_HEAD
/* The ptid this object refers to. */ /* The thread this object refers to. */
ptid_t ptid; thread_info *thread;
/* The current recording method. */ /* The current recording method. */
enum record_method method; enum record_method method;
@ -43,8 +43,8 @@ typedef struct
{ {
PyObject_HEAD PyObject_HEAD
/* The ptid this object refers to. */ /* The thread this object refers to. */
ptid_t ptid; thread_info *thread;
/* The current recording method. */ /* The current recording method. */
enum record_method method; enum record_method method;
@ -60,11 +60,11 @@ extern PyTypeObject recpy_insn_type;
extern PyTypeObject recpy_func_type; extern PyTypeObject recpy_func_type;
/* Create a new gdb.RecordInstruction object. */ /* Create a new gdb.RecordInstruction object. */
extern PyObject *recpy_insn_new (ptid_t ptid, enum record_method method, extern PyObject *recpy_insn_new (thread_info *thread, enum record_method method,
Py_ssize_t number); Py_ssize_t number);
/* Create a new gdb.RecordFunctionSegment object. */ /* Create a new gdb.RecordFunctionSegment object. */
extern PyObject *recpy_func_new (ptid_t ptid, enum record_method method, extern PyObject *recpy_func_new (thread_info *thread, enum record_method method,
Py_ssize_t number); Py_ssize_t number);
/* Create a new gdb.RecordGap object. */ /* Create a new gdb.RecordGap object. */

View file

@ -18,6 +18,7 @@
#include "defs.h" #include "defs.h"
#include "py-event.h" #include "py-event.h"
#include "infrun.h" #include "infrun.h"
#include "gdbthread.h"
/* thread events can either be thread specific or process wide. If gdb is /* thread events can either be thread specific or process wide. If gdb is
running in non-stop mode then the event is thread specific, otherwise running in non-stop mode then the event is thread specific, otherwise
@ -31,10 +32,10 @@ static PyObject *get_event_thread (void)
static PyObject * static PyObject *
get_event_thread (void) get_event_thread (void)
{ {
PyObject *thread = NULL; PyObject *thread;
if (non_stop) if (non_stop)
thread = (PyObject *) find_thread_object (inferior_ptid); thread = (PyObject *) thread_to_thread_object (inferior_thread ());
else else
thread = Py_None; thread = Py_None;

View file

@ -440,6 +440,8 @@ typedef struct
PyObject *inf_obj; PyObject *inf_obj;
} thread_object; } thread_object;
struct inferior_object;
extern struct cmd_list_element *set_python_list; extern struct cmd_list_element *set_python_list;
extern struct cmd_list_element *show_python_list; extern struct cmd_list_element *show_python_list;
@ -532,10 +534,9 @@ PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch); PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
thread_object *create_thread_object (struct thread_info *tp); thread_object *create_thread_object (struct thread_info *tp);
thread_object *find_thread_object (ptid_t ptid) thread_object *thread_to_thread_object (thread_info *thr)
CPYCHECKER_RETURNS_BORROWED_REF; CPYCHECKER_RETURNS_BORROWED_REF;
PyObject *find_inferior_object (int pid); inferior_object *inferior_to_inferior_object (inferior *inf);
PyObject *inferior_to_inferior_object (struct inferior *inferior);
const struct block *block_object_to_block (PyObject *obj); const struct block *block_object_to_block (PyObject *obj);
struct symbol *symbol_object_to_symbol (PyObject *obj); struct symbol *symbol_object_to_symbol (PyObject *obj);

View file

@ -39,6 +39,7 @@
#include "event-loop.h" #include "event-loop.h"
#include "inf-loop.h" #include "inf-loop.h"
#include "vec.h" #include "vec.h"
#include "inferior.h"
#include <algorithm> #include <algorithm>
static const target_info record_btrace_target_info = { static const target_info record_btrace_target_info = {
@ -244,14 +245,13 @@ record_btrace_get_cpu (void)
static struct thread_info * static struct thread_info *
require_btrace_thread (void) require_btrace_thread (void)
{ {
struct thread_info *tp;
DEBUG ("require"); DEBUG ("require");
tp = find_thread_ptid (inferior_ptid); if (inferior_ptid == null_ptid)
if (tp == NULL)
error (_("No thread.")); error (_("No thread."));
thread_info *tp = inferior_thread ();
validate_registers_access (); validate_registers_access ();
btrace_fetch (tp, record_btrace_get_cpu ()); btrace_fetch (tp, record_btrace_get_cpu ());
@ -1778,8 +1778,7 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
struct frame_info *next; struct frame_info *next;
/* THIS_FRAME does not contain a reference to its thread. */ /* THIS_FRAME does not contain a reference to its thread. */
tp = find_thread_ptid (inferior_ptid); tp = inferior_thread ();
gdb_assert (tp != NULL);
bfun = NULL; bfun = NULL;
next = get_next_frame (this_frame); next = get_next_frame (this_frame);
@ -1845,7 +1844,7 @@ record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0) if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
return 0; return 0;
tinfo = find_thread_ptid (inferior_ptid); tinfo = inferior_thread ();
if (btrace_find_call_by_number (&it, &tinfo->btrace, callee->up) == 0) if (btrace_find_call_by_number (&it, &tinfo->btrace, callee->up) == 0)
return 0; return 0;
@ -1977,9 +1976,11 @@ get_thread_current_frame (struct thread_info *tp)
ptid_t old_inferior_ptid; ptid_t old_inferior_ptid;
int executing; int executing;
/* Set INFERIOR_PTID, which is implicitly used by get_current_frame. */ /* Set current thread, which is implicitly used by
old_inferior_ptid = inferior_ptid; get_current_frame. */
inferior_ptid = tp->ptid; scoped_restore_current_thread restore_thread;
switch_to_thread (tp);
/* Clear the executing flag to allow changes to the current frame. /* Clear the executing flag to allow changes to the current frame.
We are not actually running, yet. We just started a reverse execution We are not actually running, yet. We just started a reverse execution
@ -1988,8 +1989,8 @@ get_thread_current_frame (struct thread_info *tp)
For the former, EXECUTING is true and we're in wait, about to For the former, EXECUTING is true and we're in wait, about to
move the thread. Since we need to recompute the stack, we temporarily move the thread. Since we need to recompute the stack, we temporarily
set EXECUTING to flase. */ set EXECUTING to flase. */
executing = is_executing (inferior_ptid); executing = tp->executing;
set_executing (inferior_ptid, 0); set_executing (inferior_ptid, false);
frame = NULL; frame = NULL;
TRY TRY
@ -2001,9 +2002,6 @@ get_thread_current_frame (struct thread_info *tp)
/* Restore the previous execution state. */ /* Restore the previous execution state. */
set_executing (inferior_ptid, executing); set_executing (inferior_ptid, executing);
/* Restore the previous inferior_ptid. */
inferior_ptid = old_inferior_ptid;
throw_exception (except); throw_exception (except);
} }
END_CATCH END_CATCH
@ -2011,9 +2009,6 @@ get_thread_current_frame (struct thread_info *tp)
/* Restore the previous execution state. */ /* Restore the previous execution state. */
set_executing (inferior_ptid, executing); set_executing (inferior_ptid, executing);
/* Restore the previous inferior_ptid. */
inferior_ptid = old_inferior_ptid;
return frame; return frame;
} }
@ -2073,7 +2068,7 @@ record_btrace_start_replaying (struct thread_info *tp)
btinfo->replay = replay; btinfo->replay = replay;
/* Make sure we're not using any stale registers. */ /* Make sure we're not using any stale registers. */
registers_changed_ptid (tp->ptid); registers_changed_thread (tp);
/* The current frame with replaying - computed via btrace unwind. */ /* The current frame with replaying - computed via btrace unwind. */
frame = get_thread_current_frame (tp); frame = get_thread_current_frame (tp);
@ -2090,7 +2085,7 @@ record_btrace_start_replaying (struct thread_info *tp)
xfree (btinfo->replay); xfree (btinfo->replay);
btinfo->replay = NULL; btinfo->replay = NULL;
registers_changed_ptid (tp->ptid); registers_changed_thread (tp);
throw_exception (except); throw_exception (except);
} }
@ -2112,7 +2107,7 @@ record_btrace_stop_replaying (struct thread_info *tp)
btinfo->replay = NULL; btinfo->replay = NULL;
/* Make sure we're not leaving any stale registers. */ /* Make sure we're not leaving any stale registers. */
registers_changed_ptid (tp->ptid); registers_changed_thread (tp);
} }
/* Stop replaying TP if it is at the end of its execution history. */ /* Stop replaying TP if it is at the end of its execution history. */
@ -2334,7 +2329,6 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
struct btrace_insn_iterator *replay; struct btrace_insn_iterator *replay;
struct btrace_thread_info *btinfo; struct btrace_thread_info *btinfo;
const struct btrace_insn *insn; const struct btrace_insn *insn;
struct inferior *inf;
btinfo = &tp->btrace; btinfo = &tp->btrace;
replay = btinfo->replay; replay = btinfo->replay;
@ -2346,11 +2340,7 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
if (insn == NULL) if (insn == NULL)
return 0; return 0;
inf = find_inferior_ptid (tp->ptid); return record_check_stopped_by_breakpoint (tp->inf->aspace, insn->pc,
if (inf == NULL)
return 0;
return record_check_stopped_by_breakpoint (inf->aspace, insn->pc,
&btinfo->stop_reason); &btinfo->stop_reason);
} }
@ -2664,7 +2654,7 @@ record_btrace_target::wait (ptid_t ptid, struct target_waitstatus *status,
record_btrace_clear_histories (&eventing->btrace); record_btrace_clear_histories (&eventing->btrace);
/* We moved the replay position but did not update registers. */ /* We moved the replay position but did not update registers. */
registers_changed_ptid (eventing->ptid); registers_changed_thread (eventing);
DEBUG ("wait ended by thread %s (%s): %s", DEBUG ("wait ended by thread %s (%s): %s",
print_thread_id (eventing), print_thread_id (eventing),
@ -2782,7 +2772,7 @@ record_btrace_target::thread_alive (ptid_t ptid)
{ {
/* We don't add or remove threads during replay. */ /* We don't add or remove threads during replay. */
if (record_is_replaying (minus_one_ptid)) if (record_is_replaying (minus_one_ptid))
return find_thread_ptid (ptid) != NULL; return true;
/* Forward the request. */ /* Forward the request. */
return this->beneath ()->thread_alive (ptid); return this->beneath ()->thread_alive (ptid);
@ -2809,7 +2799,7 @@ record_btrace_set_replay (struct thread_info *tp,
return; return;
*btinfo->replay = *it; *btinfo->replay = *it;
registers_changed_ptid (tp->ptid); registers_changed_thread (tp);
} }
/* Start anew from the new replay position. */ /* Start anew from the new replay position. */

View file

@ -21,6 +21,7 @@
#include "gdbcmd.h" #include "gdbcmd.h"
#include "regcache.h" #include "regcache.h"
#include "gdbthread.h" #include "gdbthread.h"
#include "inferior.h"
#include "event-top.h" #include "event-top.h"
#include "completer.h" #include "completer.h"
#include "arch-utils.h" #include "arch-utils.h"

View file

@ -19,6 +19,7 @@
#include "defs.h" #include "defs.h"
#include "inferior.h" #include "inferior.h"
#include "gdbthread.h"
#include "target.h" #include "target.h"
#include "gdbarch.h" #include "gdbarch.h"
#include "gdbcmd.h" #include "gdbcmd.h"
@ -390,10 +391,18 @@ get_thread_regcache (ptid_t ptid)
return get_thread_arch_regcache (ptid, current_thread_arch); return get_thread_arch_regcache (ptid, current_thread_arch);
} }
/* See regcache.h. */
struct regcache *
get_thread_regcache (thread_info *thread)
{
return get_thread_regcache (thread->ptid);
}
struct regcache * struct regcache *
get_current_regcache (void) get_current_regcache (void)
{ {
return get_thread_regcache (inferior_ptid); return get_thread_regcache (inferior_thread ());
} }
/* See common/common-regcache.h. */ /* See common/common-regcache.h. */
@ -466,6 +475,14 @@ registers_changed_ptid (ptid_t ptid)
} }
} }
/* See regcache.h. */
void
registers_changed_thread (thread_info *thread)
{
registers_changed_ptid (thread->ptid);
}
void void
registers_changed (void) registers_changed (void)
{ {

View file

@ -30,6 +30,10 @@ struct address_space;
extern struct regcache *get_current_regcache (void); extern struct regcache *get_current_regcache (void);
extern struct regcache *get_thread_regcache (ptid_t ptid); extern struct regcache *get_thread_regcache (ptid_t ptid);
/* Get the regcache of THREAD. */
extern struct regcache *get_thread_regcache (thread_info *thread);
extern struct regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *); extern struct regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *);
extern struct regcache *get_thread_arch_aspace_regcache (ptid_t, extern struct regcache *get_thread_arch_aspace_regcache (ptid_t,
struct gdbarch *, struct gdbarch *,
@ -349,6 +353,7 @@ public:
static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid); static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid);
protected: protected:
regcache (gdbarch *gdbarch, const address_space *aspace_); regcache (gdbarch *gdbarch, const address_space *aspace_);
static std::forward_list<regcache *> current_regcache; static std::forward_list<regcache *> current_regcache;
private: private:
@ -401,6 +406,10 @@ public:
extern void registers_changed (void); extern void registers_changed (void);
extern void registers_changed_ptid (ptid_t); extern void registers_changed_ptid (ptid_t);
/* Indicate that registers of THREAD may have changed, so invalidate
the cache. */
extern void registers_changed_thread (thread_info *thread);
/* An abstract base class for register dump. */ /* An abstract base class for register dump. */
class register_dump class register_dump

View file

@ -737,7 +737,7 @@ public: /* Remote specific methods. */
ptid_t ptid); ptid_t ptid);
static void open_1 (const char *name, int from_tty, int extended_p); static void open_1 (const char *name, int from_tty, int extended_p);
void start_remote (int from_tty, int extended_p); void start_remote (int from_tty, int extended_p);
void remote_detach_1 (int from_tty, struct inferior *inf); void remote_detach_1 (struct inferior *inf, int from_tty);
char *append_resumption (char *p, char *endp, char *append_resumption (char *p, char *endp,
ptid_t ptid, int step, gdb_signal siggnal); ptid_t ptid, int step, gdb_signal siggnal);
@ -758,7 +758,7 @@ public: /* Remote specific methods. */
void process_initial_stop_replies (int from_tty); void process_initial_stop_replies (int from_tty);
void remote_add_thread (ptid_t ptid, bool running, bool executing); thread_info *remote_add_thread (ptid_t ptid, bool running, bool executing);
void btrace_sync_conf (const btrace_config *conf); void btrace_sync_conf (const btrace_config *conf);
@ -2374,11 +2374,12 @@ remote_target::remote_add_inferior (int fake_pid_p, int pid, int attached,
} }
static remote_thread_info *get_remote_thread_info (thread_info *thread); static remote_thread_info *get_remote_thread_info (thread_info *thread);
static remote_thread_info *get_remote_thread_info (ptid_t ptid);
/* Add thread PTID to GDB's thread list. Tag it as executing/running /* Add thread PTID to GDB's thread list. Tag it as executing/running
according to RUNNING. */ according to RUNNING. */
void thread_info *
remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing) remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing)
{ {
struct remote_state *rs = get_remote_state (); struct remote_state *rs = get_remote_state ();
@ -2398,6 +2399,8 @@ remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing)
get_remote_thread_info (thread)->vcont_resumed = executing; get_remote_thread_info (thread)->vcont_resumed = executing;
set_executing (ptid, executing); set_executing (ptid, executing);
set_running (ptid, running); set_running (ptid, running);
return thread;
} }
/* Come here when we learn about a thread id from the remote target. /* Come here when we learn about a thread id from the remote target.
@ -2418,7 +2421,8 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing)
/* If this is a new thread, add it to GDB's thread list. /* If this is a new thread, add it to GDB's thread list.
If we leave it up to WFI to do this, bad things will happen. */ If we leave it up to WFI to do this, bad things will happen. */
if (in_thread_list (currthread) && is_exited (currthread)) thread_info *tp = find_thread_ptid (currthread);
if (tp != NULL && tp->state == THREAD_EXITED)
{ {
/* We're seeing an event on a thread id we knew had exited. /* We're seeing an event on a thread id we knew had exited.
This has to be a new thread reusing the old id. Add it. */ This has to be a new thread reusing the old id. Add it. */
@ -2464,7 +2468,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing)
extended-remote which already was debugging an inferior, we extended-remote which already was debugging an inferior, we
may not know about it yet. Add it before adding its child may not know about it yet. Add it before adding its child
thread, so notifications are emitted in a sensible order. */ thread, so notifications are emitted in a sensible order. */
if (!in_inferior_list (ptid_get_pid (currthread))) if (find_inferior_pid (ptid_get_pid (currthread)) == NULL)
{ {
struct remote_state *rs = get_remote_state (); struct remote_state *rs = get_remote_state ();
int fake_pid_p = !remote_multi_process_p (rs); int fake_pid_p = !remote_multi_process_p (rs);
@ -2474,7 +2478,8 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing)
} }
/* This is really a new thread. Add it. */ /* This is really a new thread. Add it. */
remote_add_thread (currthread, running, executing); thread_info *new_thr
= remote_add_thread (currthread, running, executing);
/* If we found a new inferior, let the common code do whatever /* If we found a new inferior, let the common code do whatever
it needs to with it (e.g., read shared libraries, insert it needs to with it (e.g., read shared libraries, insert
@ -2485,7 +2490,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing)
struct remote_state *rs = get_remote_state (); struct remote_state *rs = get_remote_state ();
if (!rs->starting_up) if (!rs->starting_up)
notice_new_inferior (currthread, executing, 0); notice_new_inferior (new_thr, executing, 0);
} }
} }
} }
@ -2503,14 +2508,11 @@ get_remote_thread_info (thread_info *thread)
return static_cast<remote_thread_info *> (thread->priv.get ()); return static_cast<remote_thread_info *> (thread->priv.get ());
} }
/* Return PTID's private thread data, creating it if necessary. */
static remote_thread_info * static remote_thread_info *
get_remote_thread_info (ptid_t ptid) get_remote_thread_info (ptid_t ptid)
{ {
struct thread_info *info = find_thread_ptid (ptid); thread_info *thr = find_thread_ptid (ptid);
return get_remote_thread_info (thr);
return get_remote_thread_info (info);
} }
/* Call this function as a result of /* Call this function as a result of
@ -3773,7 +3775,7 @@ remote_target::update_thread_list ()
if (!context.contains_thread (tp->ptid)) if (!context.contains_thread (tp->ptid))
{ {
/* Not found. */ /* Not found. */
delete_thread (tp->ptid); delete_thread (tp);
} }
} }
@ -3795,7 +3797,8 @@ remote_target::update_thread_list ()
remote_notice_new_inferior (item.ptid, executing); remote_notice_new_inferior (item.ptid, executing);
remote_thread_info *info = get_remote_thread_info (item.ptid); thread_info *tp = find_thread_ptid (item.ptid);
remote_thread_info *info = get_remote_thread_info (tp);
info->core = item.core; info->core = item.core;
info->extra = std::move (item.extra); info->extra = std::move (item.extra);
info->name = std::move (item.name); info->name = std::move (item.name);
@ -3846,11 +3849,9 @@ remote_target::extra_thread_info (thread_info *tp)
if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE) if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
{ {
struct thread_info *info = find_thread_ptid (tp->ptid); if (tp->priv != NULL)
if (info != NULL && info->priv != NULL)
{ {
const std::string &extra = get_remote_thread_info (info)->extra; const std::string &extra = get_remote_thread_info (tp)->extra;
return !extra.empty () ? extra.c_str () : NULL; return !extra.empty () ? extra.c_str () : NULL;
} }
else else
@ -4329,7 +4330,7 @@ print_one_stopped_thread (struct thread_info *thread)
{ {
struct target_waitstatus *ws = &thread->suspend.waitstatus; struct target_waitstatus *ws = &thread->suspend.waitstatus;
switch_to_thread (thread->ptid); switch_to_thread (thread);
stop_pc = get_frame_pc (get_current_frame ()); stop_pc = get_frame_pc (get_current_frame ());
set_current_sal_from_frame (get_current_frame ()); set_current_sal_from_frame (get_current_frame ());
@ -4432,9 +4433,8 @@ remote_target::process_initial_stop_replies (int from_tty)
if (non_stop) if (non_stop)
{ {
thread = any_live_thread_of_process (inf->pid); thread = any_live_thread_of_inferior (inf);
notice_new_inferior (thread->ptid, notice_new_inferior (thread, thread->state == THREAD_RUNNING,
thread->state == THREAD_RUNNING,
from_tty); from_tty);
} }
} }
@ -4455,7 +4455,7 @@ remote_target::process_initial_stop_replies (int from_tty)
if (inf->needs_setup) if (inf->needs_setup)
{ {
thread = any_live_thread_of_process (inf->pid); thread = any_live_thread_of_inferior (inf);
switch_to_thread_no_regs (thread); switch_to_thread_no_regs (thread);
setup_inferior (0); setup_inferior (0);
} }
@ -4471,7 +4471,7 @@ remote_target::process_initial_stop_replies (int from_tty)
first = thread; first = thread;
if (!non_stop) if (!non_stop)
set_running (thread->ptid, 0); thread->set_running (false);
else if (thread->state != THREAD_STOPPED) else if (thread->state != THREAD_STOPPED)
continue; continue;
@ -5654,11 +5654,10 @@ remote_target::remote_detach_pid (int pid)
one. */ one. */
void void
remote_target::remote_detach_1 (int from_tty, inferior *inf) remote_target::remote_detach_1 (inferior *inf, int from_tty)
{ {
int pid = ptid_get_pid (inferior_ptid); int pid = ptid_get_pid (inferior_ptid);
struct remote_state *rs = get_remote_state (); struct remote_state *rs = get_remote_state ();
struct thread_info *tp = find_thread_ptid (inferior_ptid);
int is_fork_parent; int is_fork_parent;
if (!target_has_execution) if (!target_has_execution)
@ -5673,6 +5672,8 @@ remote_target::remote_detach_1 (int from_tty, inferior *inf)
if (from_tty && !rs->extended && number_of_live_inferiors () == 1) if (from_tty && !rs->extended && number_of_live_inferiors () == 1)
puts_filtered (_("Ending remote debugging.\n")); puts_filtered (_("Ending remote debugging.\n"));
struct thread_info *tp = find_thread_ptid (inferior_ptid);
/* Check to see if we are detaching a fork parent. Note that if we /* Check to see if we are detaching a fork parent. Note that if we
are detaching a fork child, tp == NULL. */ are detaching a fork child, tp == NULL. */
is_fork_parent = (tp != NULL is_fork_parent = (tp != NULL
@ -5694,20 +5695,20 @@ remote_target::remote_detach_1 (int from_tty, inferior *inf)
else else
{ {
inferior_ptid = null_ptid; inferior_ptid = null_ptid;
detach_inferior (pid); detach_inferior (current_inferior ());
} }
} }
void void
remote_target::detach (inferior *inf, int from_tty) remote_target::detach (inferior *inf, int from_tty)
{ {
remote_detach_1 (from_tty, inf); remote_detach_1 (inf, from_tty);
} }
void void
extended_remote_target::detach (inferior *inf, int from_tty) extended_remote_target::detach (inferior *inf, int from_tty)
{ {
remote_detach_1 (from_tty, inf); remote_detach_1 (inf, from_tty);
} }
/* Target follow-fork function for remote targets. On entry, and /* Target follow-fork function for remote targets. On entry, and
@ -5851,7 +5852,7 @@ extended_remote_target::attach (const char *args, int from_tty)
/* Get list of threads. */ /* Get list of threads. */
update_thread_list (); update_thread_list ();
thread = first_thread_of_process (pid); thread = first_thread_of_inferior (current_inferior ());
if (thread) if (thread)
inferior_ptid = thread->ptid; inferior_ptid = thread->ptid;
else else

View file

@ -557,9 +557,9 @@ static const struct frame_unwind s390_sigtramp_frame_unwind = {
static LONGEST static LONGEST
s390_linux_get_syscall_number (struct gdbarch *gdbarch, s390_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regs = get_thread_regcache (ptid); struct regcache *regs = get_thread_regcache (thread);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST pc; ULONGEST pc;

View file

@ -274,9 +274,9 @@ sparc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
static LONGEST static LONGEST
sparc32_linux_get_syscall_number (struct gdbarch *gdbarch, sparc32_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The content of a register. */ /* The content of a register. */
gdb_byte buf[4]; gdb_byte buf[4];

View file

@ -282,9 +282,9 @@ sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
static LONGEST static LONGEST
sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
ptid_t ptid) thread_info *thread)
{ {
struct regcache *regcache = get_thread_regcache (ptid); struct regcache *regcache = get_thread_regcache (thread);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The content of a register. */ /* The content of a register. */
gdb_byte buf[8]; gdb_byte buf[8];

View file

@ -134,7 +134,7 @@ frame_show_address (struct frame_info *frame,
if (sal.line != 0 && sal.pc == 0 && sal.end == 0) if (sal.line != 0 && sal.pc == 0 && sal.end == 0)
{ {
if (get_next_frame (frame) == NULL) if (get_next_frame (frame) == NULL)
gdb_assert (inline_skipped_frames (inferior_ptid) > 0); gdb_assert (inline_skipped_frames (inferior_thread ()) > 0);
else else
gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME); gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
return 0; return 0;

View file

@ -182,6 +182,8 @@
target_debug_do_print (plongest (X)) target_debug_do_print (plongest (X))
#define target_debug_print_thread_info_p(X) \ #define target_debug_print_thread_info_p(X) \
target_debug_do_print (host_address_to_string (X)) target_debug_do_print (host_address_to_string (X))
#define target_debug_print_thread_info_pp(X) \
target_debug_do_print (host_address_to_string (X))
static void static void
target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status) target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)

View file

@ -1128,7 +1128,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
return TARGET_XFER_E_IO; return TARGET_XFER_E_IO;
if (!ptid_equal (inferior_ptid, null_ptid)) if (!ptid_equal (inferior_ptid, null_ptid))
inf = find_inferior_ptid (inferior_ptid); inf = current_inferior ();
else else
inf = NULL; inf = NULL;
@ -2025,12 +2025,10 @@ target_pre_inferior (int from_tty)
static int static int
dispose_inferior (struct inferior *inf, void *args) dispose_inferior (struct inferior *inf, void *args)
{ {
struct thread_info *thread; thread_info *thread = any_thread_of_inferior (inf);
if (thread != NULL)
thread = any_thread_of_process (inf->pid);
if (thread)
{ {
switch_to_thread (thread->ptid); switch_to_thread (thread);
/* Core inferiors actually should be detached, not killed. */ /* Core inferiors actually should be detached, not killed. */
if (target_has_execution) if (target_has_execution)
@ -2087,8 +2085,8 @@ target_detach (inferior *inf, int from_tty)
; ;
else else
/* If we're in breakpoints-always-inserted mode, have to remove /* If we're in breakpoints-always-inserted mode, have to remove
them before detaching. */ breakpoints before detaching. */
remove_breakpoints_pid (ptid_get_pid (inferior_ptid)); remove_breakpoints_inf (current_inferior ());
prepare_for_detach (); prepare_for_detach ();
@ -3252,9 +3250,8 @@ target_announce_detach (int from_tty)
void void
generic_mourn_inferior (void) generic_mourn_inferior (void)
{ {
ptid_t ptid; inferior *inf = current_inferior ();
ptid = inferior_ptid;
inferior_ptid = null_ptid; inferior_ptid = null_ptid;
/* Mark breakpoints uninserted in case something tries to delete a /* Mark breakpoints uninserted in case something tries to delete a
@ -3262,11 +3259,8 @@ generic_mourn_inferior (void)
fail, since the inferior is long gone). */ fail, since the inferior is long gone). */
mark_breakpoints_out (); mark_breakpoints_out ();
if (!ptid_equal (ptid, null_ptid)) if (inf->pid != 0)
{ exit_inferior (inf);
int pid = ptid_get_pid (ptid);
exit_inferior (pid);
}
/* Note this wipes step-resume breakpoints, so needs to be done /* Note this wipes step-resume breakpoints, so needs to be done
after exit_inferior, which ends up referencing the step-resume after exit_inferior, which ends up referencing the step-resume

View file

@ -220,16 +220,12 @@ set_thread_exited (thread_info *tp, int silent)
void void
init_thread_list (void) init_thread_list (void)
{ {
struct thread_info *tp, *tpnext; struct thread_info *tp, *tmp;
highest_thread_num = 0; highest_thread_num = 0;
if (!thread_list) ALL_THREADS_SAFE (tp, tmp)
return;
for (tp = thread_list; tp; tp = tpnext)
{ {
tpnext = tp->next;
if (tp->deletable ()) if (tp->deletable ())
delete tp; delete tp;
else else
@ -285,28 +281,28 @@ add_thread_silent (ptid_t ptid)
if (inferior_ptid == ptid) if (inferior_ptid == ptid)
{ {
tp = new_thread (inf, null_ptid); thread_info *new_thr = new_thread (inf, null_ptid);
/* Make switch_to_thread not read from the thread. */ /* Make switch_to_thread not read from the thread. */
tp->state = THREAD_EXITED; new_thr->state = THREAD_EXITED;
switch_to_thread (null_ptid); switch_to_no_thread ();
/* Now we can delete it. */ /* Now we can delete it. */
delete_thread (ptid); delete_thread (tp);
/* Now reset its ptid, and reswitch inferior_ptid to it. */ /* Now reset its ptid, and reswitch inferior_ptid to it. */
tp->ptid = ptid; new_thr->ptid = ptid;
tp->state = THREAD_STOPPED; new_thr->state = THREAD_STOPPED;
switch_to_thread (ptid); switch_to_thread (new_thr);
gdb::observers::new_thread.notify (tp); gdb::observers::new_thread.notify (new_thr);
/* All done. */ /* All done. */
return tp; return new_thr;
} }
else else
/* Just go ahead and delete it. */ /* Just go ahead and delete it. */
delete_thread (ptid); delete_thread (tp);
} }
tp = new_thread (inf, ptid); tp = new_thread (inf, ptid);
@ -436,17 +432,18 @@ thread_step_over_chain_remove (struct thread_info *tp)
step_over_chain_remove (&step_over_queue_head, tp); step_over_chain_remove (&step_over_queue_head, tp);
} }
/* Delete thread PTID. If SILENT, don't notify the observer of this /* Delete thread TP. If SILENT, don't notify the observer of this
exit. */ exit. */
static void static void
delete_thread_1 (ptid_t ptid, int silent) delete_thread_1 (thread_info *thr, bool silent)
{ {
struct thread_info *tp, *tpprev; struct thread_info *tp, *tpprev;
tpprev = NULL; tpprev = NULL;
for (tp = thread_list; tp; tpprev = tp, tp = tp->next) for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
if (tp->ptid == ptid) if (tp == thr)
break; break;
if (!tp) if (!tp)
@ -468,20 +465,21 @@ delete_thread_1 (ptid_t ptid, int silent)
delete tp; delete tp;
} }
/* Delete thread PTID and notify of thread exit. If this is /* Delete thread THREAD and notify of thread exit. If this is the
inferior_ptid, don't actually delete it, but tag it as exited and current thread, don't actually delete it, but tag it as exited and
do the notification. If PTID is the user selected thread, clear do the notification. If this is the user selected thread, clear
it. */ it. */
void void
delete_thread (ptid_t ptid) delete_thread (thread_info *thread)
{ {
delete_thread_1 (ptid, 0 /* not silent */); delete_thread_1 (thread, false /* not silent */);
} }
void void
delete_thread_silent (ptid_t ptid) delete_thread_silent (thread_info *thread)
{ {
delete_thread_1 (ptid, 1 /* silent */); delete_thread_1 (thread, true /* silent */);
} }
struct thread_info * struct thread_info *
@ -601,29 +599,6 @@ valid_global_thread_id (int global_id)
return 0; return 0;
} }
int
ptid_to_global_thread_id (ptid_t ptid)
{
struct thread_info *tp;
for (tp = thread_list; tp; tp = tp->next)
if (tp->ptid == ptid)
return tp->global_num;
return 0;
}
ptid_t
global_thread_id_to_ptid (int global_id)
{
struct thread_info *thread = find_thread_global_id (global_id);
if (thread)
return thread->ptid;
else
return minus_one_ptid;
}
int int
in_thread_list (ptid_t ptid) in_thread_list (ptid_t ptid)
{ {
@ -636,51 +611,50 @@ in_thread_list (ptid_t ptid)
return 0; /* Never heard of 'im. */ return 0; /* Never heard of 'im. */
} }
/* Finds the first thread of the inferior given by PID. If PID is -1, /* Finds the first thread of the inferior. */
return the first thread in the list. */
struct thread_info * thread_info *
first_thread_of_process (int pid) first_thread_of_inferior (inferior *inf)
{ {
struct thread_info *tp, *ret = NULL; struct thread_info *tp, *ret = NULL;
for (tp = thread_list; tp; tp = tp->next) for (tp = thread_list; tp; tp = tp->next)
if (pid == -1 || ptid_get_pid (tp->ptid) == pid) if (tp->inf == inf)
if (ret == NULL || tp->global_num < ret->global_num) if (ret == NULL || tp->global_num < ret->global_num)
ret = tp; ret = tp;
return ret; return ret;
} }
struct thread_info * thread_info *
any_thread_of_process (int pid) any_thread_of_inferior (inferior *inf)
{ {
struct thread_info *tp; struct thread_info *tp;
gdb_assert (pid != 0); gdb_assert (inf->pid != 0);
/* Prefer the current thread. */ /* Prefer the current thread. */
if (ptid_get_pid (inferior_ptid) == pid) if (inf == current_inferior ())
return inferior_thread (); return inferior_thread ();
ALL_NON_EXITED_THREADS (tp) ALL_NON_EXITED_THREADS (tp)
if (ptid_get_pid (tp->ptid) == pid) if (tp->inf == inf)
return tp; return tp;
return NULL; return NULL;
} }
struct thread_info * thread_info *
any_live_thread_of_process (int pid) any_live_thread_of_inferior (inferior *inf)
{ {
struct thread_info *curr_tp = NULL; struct thread_info *curr_tp = NULL;
struct thread_info *tp; struct thread_info *tp;
struct thread_info *tp_executing = NULL; struct thread_info *tp_executing = NULL;
gdb_assert (pid != 0); gdb_assert (inf != NULL && inf->pid != 0);
/* Prefer the current thread if it's not executing. */ /* Prefer the current thread if it's not executing. */
if (ptid_get_pid (inferior_ptid) == pid) if (inferior_ptid != null_ptid && current_inferior () == inf)
{ {
/* If the current thread is dead, forget it. If it's not /* If the current thread is dead, forget it. If it's not
executing, use it. Otherwise, still choose it (below), but executing, use it. Otherwise, still choose it (below), but
@ -693,7 +667,7 @@ any_live_thread_of_process (int pid)
} }
ALL_NON_EXITED_THREADS (tp) ALL_NON_EXITED_THREADS (tp)
if (ptid_get_pid (tp->ptid) == pid) if (tp->inf == inf)
{ {
if (!tp->executing) if (!tp->executing)
return tp; return tp;
@ -731,7 +705,7 @@ prune_threads (void)
ALL_THREADS_SAFE (tp, tmp) ALL_THREADS_SAFE (tp, tmp)
{ {
if (!thread_alive (tp)) if (!thread_alive (tp))
delete_thread (tp->ptid); delete_thread (tp);
} }
} }
@ -745,18 +719,16 @@ delete_exited_threads (void)
ALL_THREADS_SAFE (tp, tmp) ALL_THREADS_SAFE (tp, tmp)
{ {
if (tp->state == THREAD_EXITED) if (tp->state == THREAD_EXITED)
delete_thread (tp->ptid); delete_thread (tp);
} }
} }
/* Return true value if stack temporaies are enabled for the thread /* Return true value if stack temporaies are enabled for the thread
with id PTID. */ TP. */
bool bool
thread_stack_temporaries_enabled_p (ptid_t ptid) thread_stack_temporaries_enabled_p (thread_info *tp)
{ {
struct thread_info *tp = find_thread_ptid (ptid);
if (tp == NULL) if (tp == NULL)
return false; return false;
else else
@ -766,22 +738,18 @@ thread_stack_temporaries_enabled_p (ptid_t ptid)
/* Push V on to the stack temporaries of the thread with id PTID. */ /* Push V on to the stack temporaries of the thread with id PTID. */
void void
push_thread_stack_temporary (ptid_t ptid, struct value *v) push_thread_stack_temporary (thread_info *tp, struct value *v)
{ {
struct thread_info *tp = find_thread_ptid (ptid);
gdb_assert (tp != NULL && tp->stack_temporaries_enabled); gdb_assert (tp != NULL && tp->stack_temporaries_enabled);
tp->stack_temporaries.push_back (v); tp->stack_temporaries.push_back (v);
} }
/* Return true if VAL is among the stack temporaries of the thread /* Return true if VAL is among the stack temporaries of the thread
with id PTID. Return false otherwise. */ TP. Return false otherwise. */
bool bool
value_in_thread_stack_temporaries (struct value *val, ptid_t ptid) value_in_thread_stack_temporaries (struct value *val, thread_info *tp)
{ {
struct thread_info *tp = find_thread_ptid (ptid);
gdb_assert (tp != NULL && tp->stack_temporaries_enabled); gdb_assert (tp != NULL && tp->stack_temporaries_enabled);
for (value *v : tp->stack_temporaries) for (value *v : tp->stack_temporaries)
if (v == val) if (v == val)
@ -793,11 +761,10 @@ value_in_thread_stack_temporaries (struct value *val, ptid_t ptid)
/* Return the last of the stack temporaries for thread with id PTID. /* Return the last of the stack temporaries for thread with id PTID.
Return NULL if there are no stack temporaries for the thread. */ Return NULL if there are no stack temporaries for the thread. */
struct value * value *
get_last_thread_stack_temporary (ptid_t ptid) get_last_thread_stack_temporary (thread_info *tp)
{ {
struct value *lastval = NULL; struct value *lastval = NULL;
struct thread_info *tp = find_thread_ptid (ptid);
gdb_assert (tp != NULL); gdb_assert (tp != NULL);
if (!tp->stack_temporaries.empty ()) if (!tp->stack_temporaries.empty ())
@ -870,6 +837,15 @@ set_running_thread (struct thread_info *tp, int running)
return started; return started;
} }
/* See gdbthread.h. */
void
thread_info::set_running (bool running)
{
if (set_running_thread (this, running))
gdb::observers::target_resumed.notify (this->ptid);
}
void void
set_running (ptid_t ptid, int running) set_running (ptid_t ptid, int running)
{ {
@ -1049,8 +1025,10 @@ validate_registers_access (void)
if (inferior_ptid == null_ptid) if (inferior_ptid == null_ptid)
error (_("No thread selected.")); error (_("No thread selected."));
thread_info *tp = inferior_thread ();
/* Don't try to read from a dead thread. */ /* Don't try to read from a dead thread. */
if (is_exited (inferior_ptid)) if (tp->state == THREAD_EXITED)
error (_("The current thread has terminated")); error (_("The current thread has terminated"));
/* ... or from a spinning thread. FIXME: This isn't actually fully /* ... or from a spinning thread. FIXME: This isn't actually fully
@ -1058,25 +1036,25 @@ validate_registers_access (void)
at the prompt) when a thread is not executing for some internal at the prompt) when a thread is not executing for some internal
reason, but is marked running from the user's perspective. E.g., reason, but is marked running from the user's perspective. E.g.,
the thread is waiting for its turn in the step-over queue. */ the thread is waiting for its turn in the step-over queue. */
if (is_executing (inferior_ptid)) if (tp->executing)
error (_("Selected thread is running.")); error (_("Selected thread is running."));
} }
/* See gdbthread.h. */ /* See gdbthread.h. */
bool bool
can_access_registers_ptid (ptid_t ptid) can_access_registers_thread (thread_info *thread)
{ {
/* No thread, no registers. */ /* No thread, no registers. */
if (ptid == null_ptid) if (thread == NULL)
return false; return false;
/* Don't try to read from a dead thread. */ /* Don't try to read from a dead thread. */
if (is_exited (ptid)) if (thread->state == THREAD_EXITED)
return false; return false;
/* ... or from a spinning thread. FIXME: see validate_registers_access. */ /* ... or from a spinning thread. FIXME: see validate_registers_access. */
if (is_executing (ptid)) if (thread->executing)
return false; return false;
return true; return true;
@ -1139,13 +1117,19 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
int show_global_ids) int show_global_ids)
{ {
struct thread_info *tp; struct thread_info *tp;
ptid_t current_ptid;
const char *extra_info, *name, *target_id; const char *extra_info, *name, *target_id;
struct inferior *inf; struct inferior *inf;
int default_inf_num = current_inferior ()->num; int default_inf_num = current_inferior ()->num;
update_thread_list (); update_thread_list ();
current_ptid = inferior_ptid;
/* Whether we saw any thread. */
bool any_thread = false;
/* Whether the current thread is exited. */
bool current_exited = false;
thread_info *current_thread = (inferior_ptid != null_ptid
? inferior_thread () : NULL);
{ {
/* For backward compatibility, we make a list for MI. A table is /* For backward compatibility, we make a list for MI. A table is
@ -1160,7 +1144,7 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
{ {
int n_threads = 0; int n_threads = 0;
for (tp = thread_list; tp; tp = tp->next) ALL_THREADS (tp)
{ {
if (!should_print_thread (requested_threads, default_inf_num, if (!should_print_thread (requested_threads, default_inf_num,
global_ids, pid, tp)) global_ids, pid, tp))
@ -1198,6 +1182,10 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
{ {
int core; int core;
any_thread = true;
if (tp == current_thread && tp->state == THREAD_EXITED)
current_exited = true;
if (!should_print_thread (requested_threads, default_inf_num, if (!should_print_thread (requested_threads, default_inf_num,
global_ids, pid, tp)) global_ids, pid, tp))
continue; continue;
@ -1206,7 +1194,7 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
if (!uiout->is_mi_like_p ()) if (!uiout->is_mi_like_p ())
{ {
if (tp->ptid == current_ptid) if (tp == current_thread)
uiout->field_string ("current", "*"); uiout->field_string ("current", "*");
else else
uiout->field_skip ("current"); uiout->field_skip ("current");
@ -1259,7 +1247,7 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
{ {
/* The switch below puts us at the top of the stack (leaf /* The switch below puts us at the top of the stack (leaf
frame). */ frame). */
switch_to_thread (tp->ptid); switch_to_thread (tp);
print_stack_frame (get_selected_frame (NULL), print_stack_frame (get_selected_frame (NULL),
/* For MI output, print frame level. */ /* For MI output, print frame level. */
uiout->is_mi_like_p (), uiout->is_mi_like_p (),
@ -1287,20 +1275,14 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
if (pid == -1 && requested_threads == NULL) if (pid == -1 && requested_threads == NULL)
{ {
if (uiout->is_mi_like_p () if (uiout->is_mi_like_p () && inferior_ptid != null_ptid)
&& inferior_ptid != null_ptid) uiout->field_int ("current-thread-id", current_thread->global_num);
{
int num = ptid_to_global_thread_id (inferior_ptid);
gdb_assert (num != 0); if (inferior_ptid != null_ptid && current_exited)
uiout->field_int ("current-thread-id", num);
}
if (inferior_ptid != null_ptid && is_exited (inferior_ptid))
uiout->message ("\n\ uiout->message ("\n\
The current thread <Thread ID %s> has terminated. See `help thread'.\n", The current thread <Thread ID %s> has terminated. See `help thread'.\n",
print_thread_id (inferior_thread ())); print_thread_id (inferior_thread ()));
else if (thread_list != NULL && inferior_ptid == null_ptid) else if (any_thread && inferior_ptid == null_ptid)
uiout->message ("\n\ uiout->message ("\n\
No selected thread. See `help thread'.\n"); No selected thread. See `help thread'.\n");
} }
@ -1349,9 +1331,9 @@ switch_to_thread_no_regs (struct thread_info *thread)
stop_pc = ~(CORE_ADDR) 0; stop_pc = ~(CORE_ADDR) 0;
} }
/* Switch to no thread selected. */ /* See gdbthread.h. */
static void void
switch_to_no_thread () switch_to_no_thread ()
{ {
if (inferior_ptid == null_ptid) if (inferior_ptid == null_ptid)
@ -1362,9 +1344,9 @@ switch_to_no_thread ()
stop_pc = ~(CORE_ADDR) 0; stop_pc = ~(CORE_ADDR) 0;
} }
/* Switch from one thread to another. */ /* See gdbthread.h. */
static void void
switch_to_thread (thread_info *thr) switch_to_thread (thread_info *thr)
{ {
gdb_assert (thr != NULL); gdb_assert (thr != NULL);
@ -1381,18 +1363,16 @@ switch_to_thread (thread_info *thr)
internal event. */ internal event. */
if (thr->state != THREAD_EXITED if (thr->state != THREAD_EXITED
&& !thr->executing) && !thr->executing)
stop_pc = regcache_read_pc (get_thread_regcache (thr->ptid)); stop_pc = regcache_read_pc (get_thread_regcache (thr));
} }
/* See gdbthread.h. */ /* See common/common-gdbthread.h. */
void void
switch_to_thread (ptid_t ptid) switch_to_thread (ptid_t ptid)
{ {
if (ptid == null_ptid) thread_info *thr = find_thread_ptid (ptid);
switch_to_no_thread (); switch_to_thread (thr);
else
switch_to_thread (find_thread_ptid (ptid));
} }
static void static void
@ -1476,7 +1456,7 @@ scoped_restore_current_thread::~scoped_restore_current_thread ()
changed, so we have to recheck it here. */ changed, so we have to recheck it here. */
if (inferior_ptid != null_ptid if (inferior_ptid != null_ptid
&& m_was_stopped && m_was_stopped
&& is_stopped (inferior_ptid) && m_thread->state == THREAD_STOPPED
&& target_has_registers && target_has_registers
&& target_has_stack && target_has_stack
&& target_has_memory) && target_has_memory)
@ -1494,11 +1474,9 @@ scoped_restore_current_thread::scoped_restore_current_thread ()
if (inferior_ptid != null_ptid) if (inferior_ptid != null_ptid)
{ {
thread_info *tp = find_thread_ptid (inferior_ptid); thread_info *tp = inferior_thread ();
struct frame_info *frame; struct frame_info *frame;
gdb_assert (tp != NULL);
m_was_stopped = tp->state == THREAD_STOPPED; m_was_stopped = tp->state == THREAD_STOPPED;
if (m_was_stopped if (m_was_stopped
&& target_has_registers && target_has_registers
@ -1638,7 +1616,7 @@ thread_apply_all_command (const char *cmd, int from_tty)
for (thread_info *thr : thr_list_cpy) for (thread_info *thr : thr_list_cpy)
if (thread_alive (thr)) if (thread_alive (thr))
{ {
switch_to_thread (thr->ptid); switch_to_thread (thr);
printf_filtered (_("\nThread %s (%s):\n"), printf_filtered (_("\nThread %s (%s):\n"),
print_thread_id (thr), print_thread_id (thr),
target_pid_to_str (inferior_ptid)); target_pid_to_str (inferior_ptid));
@ -1725,7 +1703,7 @@ thread_apply_command (const char *tidlist, int from_tty)
continue; continue;
} }
switch_to_thread (tp->ptid); switch_to_thread (tp);
printf_filtered (_("\nThread %s (%s):\n"), print_thread_id (tp), printf_filtered (_("\nThread %s (%s):\n"), print_thread_id (tp),
target_pid_to_str (inferior_ptid)); target_pid_to_str (inferior_ptid));
@ -1747,7 +1725,7 @@ thread_command (const char *tidstr, int from_tty)
{ {
struct thread_info *tp = inferior_thread (); struct thread_info *tp = inferior_thread ();
if (is_exited (inferior_ptid)) if (tp->state == THREAD_EXITED)
printf_filtered (_("[Current thread is %s (%s) (exited)]\n"), printf_filtered (_("[Current thread is %s (%s) (exited)]\n"),
print_thread_id (tp), print_thread_id (tp),
target_pid_to_str (inferior_ptid)); target_pid_to_str (inferior_ptid));
@ -1871,7 +1849,7 @@ thread_select (const char *tidstr, thread_info *tp)
if (!thread_alive (tp)) if (!thread_alive (tp))
error (_("Thread ID %s has terminated."), tidstr); error (_("Thread ID %s has terminated."), tidstr);
switch_to_thread (tp->ptid); switch_to_thread (tp);
annotate_thread_changed (); annotate_thread_changed ();
@ -1954,15 +1932,18 @@ update_thread_list (void)
static struct value * static struct value *
thread_num_make_value_helper (struct gdbarch *gdbarch, int global) thread_num_make_value_helper (struct gdbarch *gdbarch, int global)
{ {
struct thread_info *tp = find_thread_ptid (inferior_ptid);
int int_val; int int_val;
if (tp == NULL) if (inferior_ptid == null_ptid)
int_val = 0; int_val = 0;
else if (global)
int_val = tp->global_num;
else else
int_val = tp->per_inf_num; {
thread_info *tp = inferior_thread ();
if (global)
int_val = tp->global_num;
else
int_val = tp->per_inf_num;
}
return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val);
} }

View file

@ -646,7 +646,7 @@ execute_command (const char *p, int from_tty)
we just finished executing did not resume the inferior's execution. we just finished executing did not resume the inferior's execution.
If it did resume the inferior, we will do that check after If it did resume the inferior, we will do that check after
the inferior stopped. */ the inferior stopped. */
if (has_stack_frames () && !is_running (inferior_ptid)) if (has_stack_frames () && inferior_thread ()->state != THREAD_RUNNING)
check_frame_language_change (); check_frame_language_change ();
discard_cleanups (cleanup_if_error); discard_cleanups (cleanup_if_error);
@ -1505,15 +1505,14 @@ static int
kill_or_detach (struct inferior *inf, void *args) kill_or_detach (struct inferior *inf, void *args)
{ {
struct qt_args *qt = (struct qt_args *) args; struct qt_args *qt = (struct qt_args *) args;
struct thread_info *thread;
if (inf->pid == 0) if (inf->pid == 0)
return 0; return 0;
thread = any_thread_of_process (inf->pid); thread_info *thread = any_thread_of_inferior (inf);
if (thread != NULL) if (thread != NULL)
{ {
switch_to_thread (thread->ptid); switch_to_thread (thread);
/* Leave core files alone. */ /* Leave core files alone. */
if (target_has_execution) if (target_has_execution)

View file

@ -615,14 +615,11 @@ tfile_interp_line (char *line, struct uploaded_tp **utpp,
void void
tfile_target::close () tfile_target::close ()
{ {
int pid;
if (trace_fd < 0) if (trace_fd < 0)
return; return;
pid = ptid_get_pid (inferior_ptid);
inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
exit_inferior_silent (pid); exit_inferior_silent (current_inferior ());
::close (trace_fd); ::close (trace_fd);
trace_fd = -1; trace_fd = -1;

View file

@ -33,6 +33,7 @@
#include "infrun.h" #include "infrun.h"
#include "observable.h" #include "observable.h"
#include "gdbthread.h" #include "gdbthread.h"
#include "inferior.h"
/* Set to 1 when the TUI mode must be activated when we first start /* Set to 1 when the TUI mode must be activated when we first start
gdb. */ gdb. */

View file

@ -356,7 +356,7 @@ varobj_create (const char *objname,
error (_("Failed to find the specified frame")); error (_("Failed to find the specified frame"));
var->root->frame = get_frame_id (fi); var->root->frame = get_frame_id (fi);
var->root->thread_id = ptid_to_global_thread_id (inferior_ptid); var->root->thread_id = inferior_thread ()->global_num;
old_id = get_frame_id (get_selected_frame (NULL)); old_id = get_frame_id (get_selected_frame (NULL));
select_frame (fi); select_frame (fi);
} }
@ -2122,11 +2122,11 @@ value_of_root_1 (struct varobj **var_handle)
} }
else else
{ {
ptid_t ptid = global_thread_id_to_ptid (var->root->thread_id); thread_info *thread = find_thread_global_id (var->root->thread_id);
if (!ptid_equal (minus_one_ptid, ptid)) if (thread != NULL)
{ {
switch_to_thread (ptid); switch_to_thread (thread);
within_scope = check_scope (var); within_scope = check_scope (var);
} }
} }