mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
de1ec836c8
Debugging a program under Darwin does not work: (gdb) start Temporary breakpoint 1 at 0x100000fb4: file /tmp/helloworld.c, line 1. Starting program: /private/tmp/helloworld [New Thread 0x2903 of process 60326] During startup program terminated with signal SIGTRAP, Trace/breakpoint trap. Field signaled from darwin_thread_info is not initialized thus signal sent to the debuggee is considered as not sent by GDB whereas it should. This patch fixes this problem and also updates (change type and/or initialize) other fields in the same structure at the same time. gdb/ChangeLog: * darwin-nat.h (struct darwin_thread_info) <gdb_port, inf_port, msg_state>: Initialize. (struct darwin_thread_info) <signaled, single_step>: Change type and initialize. (struct darwin_thread_info) <event>: Initialize. Change-Id: I0fe2a6985df9d0dfcc8a2a258a3ef70cfa19b403
205 lines
5.5 KiB
C++
205 lines
5.5 KiB
C++
/* Common things used by the various darwin files
|
|
Copyright (C) 1995-2018 Free Software Foundation, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef __DARWIN_NAT_H__
|
|
#define __DARWIN_NAT_H__
|
|
|
|
#include "inf-child.h"
|
|
#include <mach/mach.h>
|
|
#include "gdbthread.h"
|
|
|
|
/* This needs to be overridden by the platform specific nat code. */
|
|
|
|
class darwin_nat_target : public inf_child_target
|
|
{
|
|
void create_inferior (const char *exec_file,
|
|
const std::string &allargs,
|
|
char **env, int from_tty) override;
|
|
|
|
void attach (const char *, int) override;
|
|
|
|
void detach (inferior *, int) override;
|
|
|
|
ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
|
|
|
|
void mourn_inferior () override;
|
|
|
|
void kill () override;
|
|
|
|
void interrupt () override;
|
|
|
|
void resume (ptid_t, int , enum gdb_signal) override;
|
|
|
|
bool thread_alive (ptid_t ptid) override;
|
|
|
|
const char *pid_to_str (ptid_t) override;
|
|
|
|
char *pid_to_exec_file (int pid) override;
|
|
|
|
enum target_xfer_status xfer_partial (enum target_object object,
|
|
const char *annex,
|
|
gdb_byte *readbuf,
|
|
const gdb_byte *writebuf,
|
|
ULONGEST offset, ULONGEST len,
|
|
ULONGEST *xfered_len) override;
|
|
|
|
bool supports_multi_process () override;
|
|
|
|
ptid_t get_ada_task_ptid (long lwp, long thread) override;
|
|
};
|
|
|
|
/* Describe the mach exception handling state for a task. This state is saved
|
|
before being changed and restored when a process is detached.
|
|
For more information on these fields see task_get_exception_ports manual
|
|
page. */
|
|
struct darwin_exception_info
|
|
{
|
|
/* Exceptions handled by the port. */
|
|
exception_mask_t masks[EXC_TYPES_COUNT] {};
|
|
|
|
/* Ports receiving exception messages. */
|
|
mach_port_t ports[EXC_TYPES_COUNT] {};
|
|
|
|
/* Type of messages sent. */
|
|
exception_behavior_t behaviors[EXC_TYPES_COUNT] {};
|
|
|
|
/* Type of state to be sent. */
|
|
thread_state_flavor_t flavors[EXC_TYPES_COUNT] {};
|
|
|
|
/* Number of elements set. */
|
|
mach_msg_type_number_t count = 0;
|
|
};
|
|
|
|
struct darwin_exception_msg
|
|
{
|
|
mach_msg_header_t header;
|
|
|
|
/* Thread and task taking the exception. */
|
|
mach_port_t thread_port;
|
|
mach_port_t task_port;
|
|
|
|
/* Type of the exception. */
|
|
exception_type_t ex_type;
|
|
|
|
/* Machine dependent details. */
|
|
mach_msg_type_number_t data_count;
|
|
integer_t ex_data[2];
|
|
};
|
|
|
|
enum darwin_msg_state
|
|
{
|
|
/* The thread is running. */
|
|
DARWIN_RUNNING,
|
|
|
|
/* The thread is stopped. */
|
|
DARWIN_STOPPED,
|
|
|
|
/* The thread has sent a message and waits for a reply. */
|
|
DARWIN_MESSAGE
|
|
};
|
|
|
|
struct darwin_thread_info : public private_thread_info
|
|
{
|
|
/* The thread port from a GDB point of view. */
|
|
thread_t gdb_port = 0;
|
|
|
|
/* The thread port from the inferior point of view. Not to be used inside
|
|
gdb except for get_ada_task_ptid. */
|
|
thread_t inf_port = 0;
|
|
|
|
/* Current message state.
|
|
If the kernel has sent a message it expects a reply and the inferior
|
|
can't be killed before. */
|
|
enum darwin_msg_state msg_state = DARWIN_RUNNING;
|
|
|
|
/* True if this thread is single-stepped. */
|
|
bool single_step = false;
|
|
|
|
/* True if a signal was manually sent to the thread. */
|
|
bool signaled = false;
|
|
|
|
/* The last exception received. */
|
|
struct darwin_exception_msg event {};
|
|
};
|
|
typedef struct darwin_thread_info darwin_thread_t;
|
|
|
|
static inline darwin_thread_info *
|
|
get_darwin_thread_info (class thread_info *thread)
|
|
{
|
|
return static_cast<darwin_thread_info *> (thread->priv.get ());
|
|
}
|
|
|
|
/* Describe an inferior. */
|
|
struct darwin_inferior : public private_inferior
|
|
{
|
|
/* Corresponding task port. */
|
|
task_t task = 0;
|
|
|
|
/* Port which will receive the dead-name notification for the task port.
|
|
This is used to detect the death of the task. */
|
|
mach_port_t notify_port = 0;
|
|
|
|
/* Initial exception handling. */
|
|
darwin_exception_info exception_info;
|
|
|
|
/* Number of messages that have been received but not yet replied. */
|
|
unsigned int pending_messages = 0;
|
|
|
|
/* Set if inferior is not controlled by ptrace(2) but through Mach. */
|
|
bool no_ptrace = false;
|
|
|
|
/* True if this task is suspended. */
|
|
bool suspended = false;
|
|
|
|
/* Sorted vector of known threads. */
|
|
std::vector<darwin_thread_t *> threads;
|
|
};
|
|
|
|
/* Return the darwin_inferior attached to INF. */
|
|
|
|
static inline darwin_inferior *
|
|
get_darwin_inferior (inferior *inf)
|
|
{
|
|
return static_cast<darwin_inferior *> (inf->priv.get ());
|
|
}
|
|
|
|
/* Exception port. */
|
|
extern mach_port_t darwin_ex_port;
|
|
|
|
/* Port set. */
|
|
extern mach_port_t darwin_port_set;
|
|
|
|
/* A copy of mach_host_self (). */
|
|
extern mach_port_t darwin_host_self;
|
|
|
|
/* FUNCTION_NAME is defined in common-utils.h (or not). */
|
|
#ifdef FUNCTION_NAME
|
|
#define MACH_CHECK_ERROR(ret) \
|
|
mach_check_error (ret, __FILE__, __LINE__, FUNCTION_NAME)
|
|
#else
|
|
#define MACH_CHECK_ERROR(ret) \
|
|
mach_check_error (ret, __FILE__, __LINE__, "??")
|
|
#endif
|
|
|
|
extern void mach_check_error (kern_return_t ret, const char *file,
|
|
unsigned int line, const char *func);
|
|
|
|
void darwin_set_sstep (thread_t thread, int enable);
|
|
|
|
void darwin_check_osabi (darwin_inferior *inf, thread_t thread);
|
|
|
|
#endif /* __DARWIN_NAT_H__ */
|