forked from Imagelibrary/binutils-gdb
Compare commits
3 Commits
users/fche
...
users/palv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a015c47e1 | ||
|
|
bea0a5aeec | ||
|
|
021f945efb |
185
gdb/breakpoint.c
185
gdb/breakpoint.c
@@ -44,7 +44,6 @@
|
||||
#include "source.h"
|
||||
#include "linespec.h"
|
||||
#include "completer.h"
|
||||
#include "gdb.h"
|
||||
#include "ui-out.h"
|
||||
#include "cli/cli-script.h"
|
||||
#include "block.h"
|
||||
@@ -103,8 +102,6 @@ static void map_breakpoint_numbers (const char *,
|
||||
|
||||
static void ignore_command (char *, int);
|
||||
|
||||
static int breakpoint_re_set_one (void *);
|
||||
|
||||
static void breakpoint_re_set_default (struct breakpoint *);
|
||||
|
||||
static void
|
||||
@@ -178,8 +175,6 @@ static void info_breakpoints_command (char *, int);
|
||||
|
||||
static void info_watchpoints_command (char *, int);
|
||||
|
||||
static int breakpoint_cond_eval (void *);
|
||||
|
||||
static void cleanup_executing_breakpoints (void *);
|
||||
|
||||
static void commands_command (char *, int);
|
||||
@@ -191,8 +186,6 @@ static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
|
||||
|
||||
static enum print_stop_action print_bp_stop_message (bpstat bs);
|
||||
|
||||
static int watchpoint_check (void *);
|
||||
|
||||
static int hw_breakpoint_used_count (void);
|
||||
|
||||
static int hw_watchpoint_use_count (struct breakpoint *);
|
||||
@@ -4842,21 +4835,16 @@ bpstat_print (bpstat bs, int kind)
|
||||
return PRINT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Evaluate the expression EXP and return 1 if value is zero.
|
||||
This returns the inverse of the condition because it is called
|
||||
from catch_errors which returns 0 if an exception happened, and if an
|
||||
exception happens we want execution to stop.
|
||||
The argument is a "struct expression *" that has been cast to a
|
||||
"void *" to make it pass through catch_errors. */
|
||||
/* Evaluate the boolean expression EXP and return the result. */
|
||||
|
||||
static int
|
||||
breakpoint_cond_eval (void *exp)
|
||||
static bool
|
||||
breakpoint_cond_eval (expression *exp)
|
||||
{
|
||||
struct value *mark = value_mark ();
|
||||
int i = !value_true (evaluate_expression ((struct expression *) exp));
|
||||
bool res = value_true (evaluate_expression (exp));
|
||||
|
||||
value_free_to_mark (mark);
|
||||
return i;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Allocate a new bpstat. Link it to the FIFO list by BS_LINK_POINTER. */
|
||||
@@ -4966,30 +4954,28 @@ watchpoints_triggered (struct target_waitstatus *ws)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Possible return values for watchpoint_check (this can't be an enum
|
||||
because of check_errors). */
|
||||
/* The watchpoint has been deleted. */
|
||||
#define WP_DELETED 1
|
||||
/* The value has changed. */
|
||||
#define WP_VALUE_CHANGED 2
|
||||
/* The value has not changed. */
|
||||
#define WP_VALUE_NOT_CHANGED 3
|
||||
/* Ignore this watchpoint, no matter if the value changed or not. */
|
||||
#define WP_IGNORE 4
|
||||
/* Possible return values for watchpoint_check. */
|
||||
enum wp_check_result
|
||||
{
|
||||
/* The watchpoint has been deleted. */
|
||||
WP_DELETED = 1,
|
||||
/* The value has changed. */
|
||||
WP_VALUE_CHANGED = 2,
|
||||
/* The value has not changed. */
|
||||
WP_VALUE_NOT_CHANGED = 3,
|
||||
/* Ignore this watchpoint, no matter if the value changed or not. */
|
||||
WP_IGNORE = 4,
|
||||
};
|
||||
|
||||
#define BP_TEMPFLAG 1
|
||||
#define BP_HARDWAREFLAG 2
|
||||
|
||||
/* Evaluate watchpoint condition expression and check if its value
|
||||
changed.
|
||||
changed. */
|
||||
|
||||
P should be a pointer to struct bpstat, but is defined as a void *
|
||||
in order for this function to be usable with catch_errors. */
|
||||
|
||||
static int
|
||||
watchpoint_check (void *p)
|
||||
static wp_check_result
|
||||
watchpoint_check (bpstat bs)
|
||||
{
|
||||
bpstat bs = (bpstat) p;
|
||||
struct watchpoint *b;
|
||||
struct frame_info *fr;
|
||||
int within_current_scope;
|
||||
@@ -5185,13 +5171,29 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
|
||||
if (must_check_value)
|
||||
{
|
||||
char *message
|
||||
= xstrprintf ("Error evaluating expression for watchpoint %d\n",
|
||||
b->number);
|
||||
struct cleanup *cleanups = make_cleanup (xfree, message);
|
||||
int e = catch_errors (watchpoint_check, bs, message,
|
||||
RETURN_MASK_ALL);
|
||||
do_cleanups (cleanups);
|
||||
wp_check_result e;
|
||||
|
||||
TRY
|
||||
{
|
||||
e = watchpoint_check (bs);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error evaluating expression "
|
||||
"for watchpoint %d\n",
|
||||
b->number);
|
||||
|
||||
SWITCH_THRU_ALL_UIS ()
|
||||
{
|
||||
printf_filtered (_("Watchpoint %d deleted.\n"),
|
||||
b->number);
|
||||
}
|
||||
watchpoint_del_at_next_stop (b);
|
||||
e = WP_DELETED;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case WP_DELETED:
|
||||
@@ -5287,18 +5289,6 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
break;
|
||||
default:
|
||||
/* Can't happen. */
|
||||
case 0:
|
||||
/* Error from catch_errors. */
|
||||
{
|
||||
SWITCH_THRU_ALL_UIS ()
|
||||
{
|
||||
printf_filtered (_("Watchpoint %d deleted.\n"),
|
||||
b->number);
|
||||
}
|
||||
watchpoint_del_at_next_stop (b);
|
||||
/* We've already printed what needs to be printed. */
|
||||
bs->print_it = print_it_done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5324,7 +5314,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
||||
{
|
||||
const struct bp_location *bl;
|
||||
struct breakpoint *b;
|
||||
int value_is_zero = 0;
|
||||
/* Assume stop. */
|
||||
bool condition_result = true;
|
||||
struct expression *cond;
|
||||
|
||||
gdb_assert (bs->stop);
|
||||
@@ -5420,23 +5411,30 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
||||
within_current_scope = 0;
|
||||
}
|
||||
if (within_current_scope)
|
||||
value_is_zero
|
||||
= catch_errors (breakpoint_cond_eval, cond,
|
||||
"Error in testing breakpoint condition:\n",
|
||||
RETURN_MASK_ALL);
|
||||
{
|
||||
TRY
|
||||
{
|
||||
condition_result = breakpoint_cond_eval (cond);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error in testing breakpoint condition:\n");
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
else
|
||||
{
|
||||
warning (_("Watchpoint condition cannot be tested "
|
||||
"in the current scope"));
|
||||
/* If we failed to set the right context for this
|
||||
watchpoint, unconditionally report it. */
|
||||
value_is_zero = 0;
|
||||
}
|
||||
/* FIXME-someday, should give breakpoint #. */
|
||||
value_free_to_mark (mark);
|
||||
}
|
||||
|
||||
if (cond && value_is_zero)
|
||||
if (cond && !condition_result)
|
||||
{
|
||||
bs->stop = 0;
|
||||
}
|
||||
@@ -6597,44 +6595,11 @@ breakpoint_address_bits (struct breakpoint *b)
|
||||
return print_address_bits;
|
||||
}
|
||||
|
||||
struct captured_breakpoint_query_args
|
||||
{
|
||||
int bnum;
|
||||
};
|
||||
|
||||
static int
|
||||
do_captured_breakpoint_query (struct ui_out *uiout, void *data)
|
||||
void
|
||||
print_breakpoint (breakpoint *b)
|
||||
{
|
||||
struct captured_breakpoint_query_args *args
|
||||
= (struct captured_breakpoint_query_args *) data;
|
||||
struct breakpoint *b;
|
||||
struct bp_location *dummy_loc = NULL;
|
||||
|
||||
ALL_BREAKPOINTS (b)
|
||||
{
|
||||
if (args->bnum == b->number)
|
||||
{
|
||||
print_one_breakpoint (b, &dummy_loc, 0);
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
}
|
||||
return GDB_RC_NONE;
|
||||
}
|
||||
|
||||
enum gdb_rc
|
||||
gdb_breakpoint_query (struct ui_out *uiout, int bnum,
|
||||
char **error_message)
|
||||
{
|
||||
struct captured_breakpoint_query_args args;
|
||||
|
||||
args.bnum = bnum;
|
||||
/* For the moment we don't trust print_one_breakpoint() to not throw
|
||||
an error. */
|
||||
if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
|
||||
error_message, RETURN_MASK_ALL) < 0)
|
||||
return GDB_RC_FAIL;
|
||||
else
|
||||
return GDB_RC_OK;
|
||||
print_one_breakpoint (b, &dummy_loc, 0);
|
||||
}
|
||||
|
||||
/* Return true if this breakpoint was set by the user, false if it is
|
||||
@@ -14148,21 +14113,16 @@ prepare_re_set_context (struct breakpoint *b)
|
||||
return make_cleanup (null_cleanup, NULL);
|
||||
}
|
||||
|
||||
/* Reset a breakpoint given it's struct breakpoint * BINT.
|
||||
The value we return ends up being the return value from catch_errors.
|
||||
Unused in this case. */
|
||||
/* Reset a breakpoint. */
|
||||
|
||||
static int
|
||||
breakpoint_re_set_one (void *bint)
|
||||
static void
|
||||
breakpoint_re_set_one (breakpoint *b)
|
||||
{
|
||||
/* Get past catch_errs. */
|
||||
struct breakpoint *b = (struct breakpoint *) bint;
|
||||
struct cleanup *cleanups;
|
||||
|
||||
cleanups = prepare_re_set_context (b);
|
||||
b->ops->re_set (b);
|
||||
do_cleanups (cleanups);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Re-set breakpoint locations for the current program space.
|
||||
@@ -14188,12 +14148,17 @@ breakpoint_re_set (void)
|
||||
|
||||
ALL_BREAKPOINTS_SAFE (b, b_tmp)
|
||||
{
|
||||
/* Format possible error msg. */
|
||||
char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
|
||||
b->number);
|
||||
struct cleanup *cleanups = make_cleanup (xfree, message);
|
||||
catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
|
||||
do_cleanups (cleanups);
|
||||
TRY
|
||||
{
|
||||
breakpoint_re_set_one (b);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error in re-setting breakpoint %d: ",
|
||||
b->number);
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
set_language (save_language);
|
||||
input_radix = save_input_radix;
|
||||
|
||||
@@ -1644,4 +1644,7 @@ extern const char *ep_parse_optional_if_clause (const char **arg);
|
||||
UIOUT iff debugging multiple threads. */
|
||||
extern void maybe_print_thread_hit_breakpoint (struct ui_out *uiout);
|
||||
|
||||
/* Print the specified breakpoint. */
|
||||
extern void print_breakpoint (breakpoint *bp);
|
||||
|
||||
#endif /* !defined (BREAKPOINT_H) */
|
||||
|
||||
122
gdb/exceptions.c
122
gdb/exceptions.c
@@ -134,128 +134,6 @@ exception_fprintf (struct ui_file *file, struct gdb_exception e,
|
||||
}
|
||||
}
|
||||
|
||||
/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
|
||||
handler. If an exception (enum return_reason) is thrown using
|
||||
throw_exception() than all cleanups installed since
|
||||
catch_exceptions() was entered are invoked, the (-ve) exception
|
||||
value is then returned by catch_exceptions. If FUNC() returns
|
||||
normally (with a positive or zero return value) then that value is
|
||||
returned by catch_exceptions(). It is an internal_error() for
|
||||
FUNC() to return a negative value.
|
||||
|
||||
See exceptions.h for further usage details. */
|
||||
|
||||
/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
|
||||
error() et al. could maintain a set of flags that indicate the
|
||||
current state of each of the longjmp buffers. This would give the
|
||||
longjmp code the chance to detect a longjmp botch (before it gets
|
||||
to longjmperror()). Prior to 1999-11-05 this wasn't possible as
|
||||
code also randomly used a SET_TOP_LEVEL macro that directly
|
||||
initialized the longjmp buffers. */
|
||||
|
||||
int
|
||||
catch_exceptions (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func,
|
||||
void *func_args,
|
||||
return_mask mask)
|
||||
{
|
||||
return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
|
||||
}
|
||||
|
||||
int
|
||||
catch_exceptions_with_msg (struct ui_out *func_uiout,
|
||||
catch_exceptions_ftype *func,
|
||||
void *func_args,
|
||||
char **gdberrmsg,
|
||||
return_mask mask)
|
||||
{
|
||||
struct gdb_exception exception = exception_none;
|
||||
volatile int val = 0;
|
||||
struct ui_out *saved_uiout;
|
||||
|
||||
/* Save and override the global ``struct ui_out'' builder. */
|
||||
saved_uiout = current_uiout;
|
||||
current_uiout = func_uiout;
|
||||
|
||||
TRY
|
||||
{
|
||||
val = (*func) (current_uiout, func_args);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
/* Restore the global builder. */
|
||||
current_uiout = saved_uiout;
|
||||
|
||||
if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
|
||||
{
|
||||
/* The caller didn't request that the event be caught.
|
||||
Rethrow. */
|
||||
throw_exception (exception);
|
||||
}
|
||||
|
||||
exception_print (gdb_stderr, exception);
|
||||
gdb_assert (val >= 0);
|
||||
gdb_assert (exception.reason <= 0);
|
||||
if (exception.reason < 0)
|
||||
{
|
||||
/* If caller wants a copy of the low-level error message, make
|
||||
one. This is used in the case of a silent error whereby the
|
||||
caller may optionally want to issue the message. */
|
||||
if (gdberrmsg != NULL)
|
||||
{
|
||||
if (exception.message != NULL)
|
||||
*gdberrmsg = xstrdup (exception.message);
|
||||
else
|
||||
*gdberrmsg = NULL;
|
||||
}
|
||||
return exception.reason;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* This function is superseded by catch_exceptions(). */
|
||||
|
||||
int
|
||||
catch_errors (catch_errors_ftype *func, void *func_args,
|
||||
const char *errstring, return_mask mask)
|
||||
{
|
||||
struct gdb_exception exception = exception_none;
|
||||
volatile int val = 0;
|
||||
struct ui_out *saved_uiout;
|
||||
|
||||
/* Save the global ``struct ui_out'' builder. */
|
||||
saved_uiout = current_uiout;
|
||||
|
||||
TRY
|
||||
{
|
||||
val = func (func_args);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
/* Restore the global builder. */
|
||||
current_uiout = saved_uiout;
|
||||
|
||||
if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
|
||||
{
|
||||
/* The caller didn't request that the event be caught.
|
||||
Rethrow. */
|
||||
throw_exception (exception);
|
||||
}
|
||||
|
||||
exception_fprintf (gdb_stderr, exception, "%s", errstring);
|
||||
if (exception.reason != 0)
|
||||
return 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* See exceptions.h. */
|
||||
|
||||
int
|
||||
|
||||
@@ -48,46 +48,27 @@ extern void exception_fprintf (struct ui_file *file, struct gdb_exception e,
|
||||
copy of the gdb error message. This is used when a silent error is
|
||||
issued and the caller wants to manually issue the error message.
|
||||
|
||||
MASK specifies what to catch; it is normally set to
|
||||
RETURN_MASK_ALL, if for no other reason than that the code which
|
||||
calls catch_errors might not be set up to deal with a quit which
|
||||
isn't caught. But if the code can deal with it, it generally
|
||||
should be RETURN_MASK_ERROR, unless for some reason it is more
|
||||
useful to abort only the portion of the operation inside the
|
||||
catch_errors. Note that quit should return to the command line
|
||||
MASK specifies what to catch; it is normally set to RETURN_MASK_ALL
|
||||
if the code which calls catch_exceptions is not set up to deal with
|
||||
a quit which isn't caught. But if the code can deal with it, it
|
||||
generally should be RETURN_MASK_ERROR, unless for some reason it is
|
||||
more useful to abort only the portion of the operation inside the
|
||||
catch_exceptions. Note that quit should return to the command line
|
||||
fairly quickly, even if some further processing is being done.
|
||||
|
||||
FIXME; cagney/2001-08-13: The need to override the global UIOUT
|
||||
builder variable should just go away.
|
||||
|
||||
This function supersedes catch_errors().
|
||||
|
||||
This function uses SETJMP() and LONGJUMP(). */
|
||||
builder variable should just go away. */
|
||||
|
||||
struct ui_out;
|
||||
typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
|
||||
typedef int (catch_exceptions_ftype) (struct ui_out *ui_out);
|
||||
extern int catch_exceptions (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func, void *func_args,
|
||||
gdb::function_view<catch_exceptions_ftype> func,
|
||||
return_mask mask);
|
||||
typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args);
|
||||
extern int catch_exceptions_with_msg (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func,
|
||||
void *func_args,
|
||||
char **gdberrmsg,
|
||||
return_mask mask);
|
||||
|
||||
/* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
|
||||
otherwize the result from CATCH_ERRORS_FTYPE is returned. It is
|
||||
probably useful for CATCH_ERRORS_FTYPE to always return a non-zero
|
||||
value. It's unfortunate that, catch_errors() does not return an
|
||||
indication of the exact exception that it caught - quit_flag might
|
||||
help.
|
||||
|
||||
This function is superseded by catch_exceptions(). */
|
||||
|
||||
typedef int (catch_errors_ftype) (void *);
|
||||
extern int catch_errors (catch_errors_ftype *, void *,
|
||||
const char *, return_mask);
|
||||
extern int catch_exceptions_with_msg
|
||||
(struct ui_out *uiout,
|
||||
gdb::function_view<catch_exceptions_ftype> func,
|
||||
char **gdberrmsg,
|
||||
return_mask mask);
|
||||
|
||||
/* Compare two exception objects for print equality. */
|
||||
extern int exception_print_same (struct gdb_exception e1,
|
||||
|
||||
58
gdb/gdb.h
58
gdb/gdb.h
@@ -1,58 +0,0 @@
|
||||
/* Library interface into GDB.
|
||||
Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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 GDB_H
|
||||
#define GDB_H
|
||||
|
||||
struct ui_out;
|
||||
|
||||
/* Return-code (RC) from a gdb library call. (The abreviation RC is
|
||||
taken from the sim/common directory.) */
|
||||
|
||||
enum gdb_rc {
|
||||
/* The operation failed. The failure message can be fetched by
|
||||
calling ``char *error_last_message(void)''. The value is
|
||||
determined by the catch_errors() interface. The MSG parameter is
|
||||
set to a freshly allocated copy of the error message. */
|
||||
/* NOTE: Since ``defs.h:catch_errors()'' does not return an error /
|
||||
internal / quit indication it is not possible to return that
|
||||
here. */
|
||||
GDB_RC_FAIL = 0,
|
||||
/* No error occured but nothing happened. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
GDB_RC_NONE = 1,
|
||||
/* The operation was successful. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
GDB_RC_OK = 2
|
||||
};
|
||||
|
||||
|
||||
/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
|
||||
function will ``print'' the object on ``output''). */
|
||||
enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum,
|
||||
char **error_message);
|
||||
|
||||
/* Switch thread and print notification. */
|
||||
enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr,
|
||||
char **error_message);
|
||||
|
||||
/* Print a list of known thread ids. */
|
||||
enum gdb_rc gdb_list_thread_ids (struct ui_out *uiout,
|
||||
char **error_message);
|
||||
|
||||
#endif
|
||||
@@ -679,6 +679,8 @@ extern int show_thread_that_caused_stop (void);
|
||||
extern void print_selected_thread_frame (struct ui_out *uiout,
|
||||
user_selected_what selection);
|
||||
|
||||
extern void thread_select (const char *tidstr, thread_info *thr);
|
||||
|
||||
extern struct thread_info *thread_list;
|
||||
|
||||
#endif /* GDBTHREAD_H */
|
||||
|
||||
48
gdb/infrun.c
48
gdb/infrun.c
@@ -80,10 +80,6 @@ static void sig_print_header (void);
|
||||
|
||||
static void resume_cleanups (void *);
|
||||
|
||||
static int hook_stop_stub (void *);
|
||||
|
||||
static int restore_selected_frame (void *);
|
||||
|
||||
static int follow_fork (void);
|
||||
|
||||
static int follow_fork_inferior (int follow_child, int detach_fork);
|
||||
@@ -8312,8 +8308,16 @@ normal_stop (void)
|
||||
struct cleanup *old_chain
|
||||
= make_cleanup (release_stop_context_cleanup, saved_context);
|
||||
|
||||
catch_errors (hook_stop_stub, stop_command,
|
||||
"Error while running hook_stop:\n", RETURN_MASK_ALL);
|
||||
TRY
|
||||
{
|
||||
execute_cmd_pre_hook (stop_command);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error while running hook_stop:\n");
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
/* If the stop hook resumes the target, then there's no point in
|
||||
trying to notify about the previous stop; its context is
|
||||
@@ -8354,13 +8358,6 @@ normal_stop (void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hook_stop_stub (void *cmd)
|
||||
{
|
||||
execute_cmd_pre_hook ((struct cmd_list_element *) cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
signal_stop_state (int signo)
|
||||
@@ -8982,9 +8979,8 @@ save_infcall_control_state (void)
|
||||
}
|
||||
|
||||
static int
|
||||
restore_selected_frame (void *args)
|
||||
restore_selected_frame (struct frame_id *fid)
|
||||
{
|
||||
struct frame_id *fid = (struct frame_id *) args;
|
||||
struct frame_info *frame;
|
||||
|
||||
frame = frame_find_by_id (*fid);
|
||||
@@ -9029,16 +9025,22 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
|
||||
|
||||
if (target_has_stack)
|
||||
{
|
||||
/* The point of catch_errors is that if the stack is clobbered,
|
||||
/* The point of the try/catch is that if the stack is clobbered,
|
||||
walking the stack might encounter a garbage pointer and
|
||||
error() trying to dereference it. */
|
||||
if (catch_errors
|
||||
(restore_selected_frame, &inf_status->selected_frame_id,
|
||||
"Unable to restore previously selected frame:\n",
|
||||
RETURN_MASK_ERROR) == 0)
|
||||
/* Error in restoring the selected frame. Select the innermost
|
||||
frame. */
|
||||
select_frame (get_current_frame ());
|
||||
TRY
|
||||
{
|
||||
restore_selected_frame (&inf_status->selected_frame_id);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ERROR)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Unable to restore previously selected frame:\n");
|
||||
/* Error in restoring the selected frame. Select the
|
||||
innermost frame. */
|
||||
select_frame (get_current_frame ());
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
|
||||
xfree (inf_status);
|
||||
|
||||
12
gdb/main.c
12
gdb/main.c
@@ -309,7 +309,7 @@ setup_alternate_signal_stack (void)
|
||||
non-zero return status. */
|
||||
|
||||
static int
|
||||
captured_command_loop (void *data)
|
||||
captured_command_loop ()
|
||||
{
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
@@ -1147,7 +1147,15 @@ captured_main (void *data)
|
||||
change - SET_TOP_LEVEL() - has been eliminated. */
|
||||
while (1)
|
||||
{
|
||||
catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
|
||||
TRY
|
||||
{
|
||||
captured_command_loop ();
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_print (gdb_stderr, ex);
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
/* No exit -- exit is through quit_command. */
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "mi-out.h"
|
||||
#include "breakpoint.h"
|
||||
#include "mi-getopt.h"
|
||||
#include "gdb.h"
|
||||
#include "observer.h"
|
||||
#include "mi-main.h"
|
||||
#include "mi-cmd-break.h"
|
||||
@@ -53,7 +52,17 @@ static void
|
||||
breakpoint_notify (struct breakpoint *b)
|
||||
{
|
||||
if (mi_can_breakpoint_notify)
|
||||
gdb_breakpoint_query (current_uiout, b->number, NULL);
|
||||
{
|
||||
TRY
|
||||
{
|
||||
print_breakpoint (b);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_print (gdb_stdout, ex);
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
}
|
||||
|
||||
enum bp_type
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "defs.h"
|
||||
#include "arch-utils.h"
|
||||
#include "breakpoint.h"
|
||||
#include "gdb.h"
|
||||
#include "ada-lang.h"
|
||||
#include "mi-cmds.h"
|
||||
#include "mi-getopt.h"
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "observer.h"
|
||||
#include "gdbthread.h"
|
||||
#include "solist.h"
|
||||
#include "gdb.h"
|
||||
#include "objfiles.h"
|
||||
#include "tracepoint.h"
|
||||
#include "cli-out.h"
|
||||
@@ -828,6 +827,36 @@ mi_tsv_modified (const struct trace_state_variable *tsv)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mi_print_breakpoint (struct mi_interp *mi, breakpoint *bp)
|
||||
{
|
||||
ui_out *mi_uiout = interp_ui_out (mi);
|
||||
|
||||
/* We want the output from print_breakpoint to go to
|
||||
mi->event_channel. One approach would be to just call
|
||||
print_breakpoint, and then use mi_out_put to send the current
|
||||
content of mi_uiout into mi->event_channel. However, that will
|
||||
break if anything is output to mi_uiout prior to calling the
|
||||
breakpoint_created notifications. So, we use
|
||||
ui_out_redirect. */
|
||||
mi_uiout->redirect (mi->event_channel);
|
||||
|
||||
TRY
|
||||
{
|
||||
scoped_restore restore_uiout
|
||||
= make_scoped_restore (¤t_uiout, mi_uiout);
|
||||
|
||||
print_breakpoint (bp);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_print (gdb_stderr, ex);
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
mi_uiout->redirect (NULL);
|
||||
}
|
||||
|
||||
/* Emit notification about a created breakpoint. */
|
||||
|
||||
static void
|
||||
@@ -842,36 +871,16 @@ mi_breakpoint_created (struct breakpoint *b)
|
||||
SWITCH_THRU_ALL_UIS ()
|
||||
{
|
||||
struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
|
||||
struct ui_out *mi_uiout;
|
||||
|
||||
if (mi == NULL)
|
||||
continue;
|
||||
|
||||
mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
|
||||
target_terminal::scoped_restore_terminal_state term_state;
|
||||
target_terminal::ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"breakpoint-created");
|
||||
/* We want the output from gdb_breakpoint_query to go to
|
||||
mi->event_channel. One approach would be to just call
|
||||
gdb_breakpoint_query, and then use mi_out_put to send the current
|
||||
content of mi_uiout into mi->event_channel. However, that will
|
||||
break if anything is output to mi_uiout prior to calling the
|
||||
breakpoint_created notifications. So, we use
|
||||
ui_out_redirect. */
|
||||
mi_uiout->redirect (mi->event_channel);
|
||||
TRY
|
||||
{
|
||||
gdb_breakpoint_query (mi_uiout, b->number, NULL);
|
||||
}
|
||||
CATCH (e, RETURN_MASK_ERROR)
|
||||
{
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
mi_uiout->redirect (NULL);
|
||||
mi_print_breakpoint (mi, b);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
}
|
||||
@@ -927,24 +936,7 @@ mi_breakpoint_modified (struct breakpoint *b)
|
||||
target_terminal::ours_for_output ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"breakpoint-modified");
|
||||
/* We want the output from gdb_breakpoint_query to go to
|
||||
mi->event_channel. One approach would be to just call
|
||||
gdb_breakpoint_query, and then use mi_out_put to send the current
|
||||
content of mi_uiout into mi->event_channel. However, that will
|
||||
break if anything is output to mi_uiout prior to calling the
|
||||
breakpoint_created notifications. So, we use
|
||||
ui_out_redirect. */
|
||||
mi->mi_uiout->redirect (mi->event_channel);
|
||||
TRY
|
||||
{
|
||||
gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
|
||||
}
|
||||
CATCH (e, RETURN_MASK_ERROR)
|
||||
{
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
mi->mi_uiout->redirect (NULL);
|
||||
mi_print_breakpoint (mi, b);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "gdbcore.h" /* For write_memory(). */
|
||||
#include "value.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb.h"
|
||||
#include "frame.h"
|
||||
#include "mi-main.h"
|
||||
#include "mi-common.h"
|
||||
@@ -553,21 +552,17 @@ mi_cmd_target_flash_erase (const char *command, char **argv, int argc)
|
||||
void
|
||||
mi_cmd_thread_select (const char *command, char **argv, int argc)
|
||||
{
|
||||
enum gdb_rc rc;
|
||||
char *mi_error_message;
|
||||
ptid_t previous_ptid = inferior_ptid;
|
||||
|
||||
if (argc != 1)
|
||||
error (_("-thread-select: USAGE: threadnum."));
|
||||
|
||||
rc = gdb_thread_select (current_uiout, argv[0], &mi_error_message);
|
||||
int num = value_as_long (parse_and_eval (argv[0]));
|
||||
thread_info *thr = find_thread_global_id (num);
|
||||
if (thr == NULL)
|
||||
error (_("Thread ID %d not known."), num);
|
||||
|
||||
/* If thread switch did not succeed don't notify or print. */
|
||||
if (rc == GDB_RC_FAIL)
|
||||
{
|
||||
make_cleanup (xfree, mi_error_message);
|
||||
error ("%s", mi_error_message);
|
||||
}
|
||||
ptid_t previous_ptid = inferior_ptid;
|
||||
|
||||
thread_select (argv[0], thr);
|
||||
|
||||
print_selected_thread_frame (current_uiout,
|
||||
USER_SELECTED_THREAD | USER_SELECTED_FRAME);
|
||||
@@ -583,19 +578,31 @@ mi_cmd_thread_select (const char *command, char **argv, int argc)
|
||||
void
|
||||
mi_cmd_thread_list_ids (const char *command, char **argv, int argc)
|
||||
{
|
||||
enum gdb_rc rc;
|
||||
char *mi_error_message;
|
||||
|
||||
if (argc != 0)
|
||||
error (_("-thread-list-ids: No arguments required."));
|
||||
|
||||
rc = gdb_list_thread_ids (current_uiout, &mi_error_message);
|
||||
int num = 0;
|
||||
int current_thread = -1;
|
||||
|
||||
if (rc == GDB_RC_FAIL)
|
||||
{
|
||||
make_cleanup (xfree, mi_error_message);
|
||||
error ("%s", mi_error_message);
|
||||
}
|
||||
update_thread_list ();
|
||||
|
||||
{
|
||||
ui_out_emit_tuple tuple_emitter (current_uiout, "thread-ids");
|
||||
|
||||
struct thread_info *tp;
|
||||
ALL_NON_EXITED_THREADS (tp)
|
||||
{
|
||||
if (tp->ptid == inferior_ptid)
|
||||
current_thread = tp->global_num;
|
||||
|
||||
num++;
|
||||
current_uiout->field_int ("thread-id", tp->global_num);
|
||||
}
|
||||
}
|
||||
|
||||
if (current_thread != -1)
|
||||
current_uiout->field_int ("current-thread-id", current_thread);
|
||||
current_uiout->field_int ("number-of-threads", num);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1310,43 +1310,24 @@ find_objc_msgsend (void)
|
||||
* dependent modules.
|
||||
*/
|
||||
|
||||
struct objc_submethod_helper_data {
|
||||
int (*f) (CORE_ADDR, CORE_ADDR *);
|
||||
CORE_ADDR pc;
|
||||
CORE_ADDR *new_pc;
|
||||
};
|
||||
|
||||
static int
|
||||
find_objc_msgcall_submethod_helper (void * arg)
|
||||
{
|
||||
struct objc_submethod_helper_data *s =
|
||||
(struct objc_submethod_helper_data *) arg;
|
||||
|
||||
if (s->f (s->pc, s->new_pc) == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
|
||||
CORE_ADDR pc,
|
||||
CORE_ADDR *new_pc)
|
||||
{
|
||||
struct objc_submethod_helper_data s;
|
||||
TRY
|
||||
{
|
||||
if (f (pc, new_pc) == 0)
|
||||
return 1;
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Unable to determine target of "
|
||||
"Objective-C method call (ignoring):\n");
|
||||
}
|
||||
|
||||
s.f = f;
|
||||
s.pc = pc;
|
||||
s.new_pc = new_pc;
|
||||
|
||||
if (catch_errors (find_objc_msgcall_submethod_helper,
|
||||
(void *) &s,
|
||||
"Unable to determine target of "
|
||||
"Objective-C method call (ignoring):\n",
|
||||
RETURN_MASK_ALL) == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -565,7 +565,7 @@ record_full_arch_list_cleanups (void *ignore)
|
||||
record the running message of inferior and set them to
|
||||
record_full_arch_list, and add it to record_full_list. */
|
||||
|
||||
static int
|
||||
static void
|
||||
record_full_message (struct regcache *regcache, enum gdb_signal signal)
|
||||
{
|
||||
int ret;
|
||||
@@ -633,36 +633,24 @@ record_full_message (struct regcache *regcache, enum gdb_signal signal)
|
||||
record_full_list_release_first ();
|
||||
else
|
||||
record_full_insn_num++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct record_full_message_args {
|
||||
struct regcache *regcache;
|
||||
enum gdb_signal signal;
|
||||
};
|
||||
|
||||
static int
|
||||
record_full_message_wrapper (void *args)
|
||||
{
|
||||
struct record_full_message_args *record_full_args
|
||||
= (struct record_full_message_args *) args;
|
||||
|
||||
return record_full_message (record_full_args->regcache,
|
||||
record_full_args->signal);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
record_full_message_wrapper_safe (struct regcache *regcache,
|
||||
enum gdb_signal signal)
|
||||
{
|
||||
struct record_full_message_args args;
|
||||
TRY
|
||||
{
|
||||
record_full_message (regcache, signal);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_print (gdb_stderr, ex);
|
||||
return false;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
args.regcache = regcache;
|
||||
args.signal = signal;
|
||||
|
||||
return catch_errors (record_full_message_wrapper, &args, "",
|
||||
RETURN_MASK_ALL);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set to 1 if record_full_store_registers and record_full_xfer_partial
|
||||
|
||||
@@ -1118,10 +1118,9 @@ static struct {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
|
||||
static void
|
||||
do_remote_fileio_request (char *buf)
|
||||
{
|
||||
char *buf = (char *) buf_arg;
|
||||
char *c;
|
||||
int idx;
|
||||
|
||||
@@ -1135,10 +1134,10 @@ do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
|
||||
for (idx = 0; remote_fio_func_map[idx].name; ++idx)
|
||||
if (!strcmp (remote_fio_func_map[idx].name, buf))
|
||||
break;
|
||||
if (!remote_fio_func_map[idx].name) /* ERROR: No such function. */
|
||||
return RETURN_ERROR;
|
||||
remote_fio_func_map[idx].func (c);
|
||||
return 0;
|
||||
if (!remote_fio_func_map[idx].name)
|
||||
remote_fileio_reply (-1, FILEIO_ENOSYS);
|
||||
else
|
||||
remote_fio_func_map[idx].func (c);
|
||||
}
|
||||
|
||||
/* Close any open descriptors, and reinitialize the file mapping. */
|
||||
@@ -1188,19 +1187,16 @@ remote_fileio_request (char *buf, int ctrlc_pending_p)
|
||||
}
|
||||
else
|
||||
{
|
||||
ex = catch_exceptions (current_uiout,
|
||||
do_remote_fileio_request, (void *)buf,
|
||||
RETURN_MASK_ALL);
|
||||
switch (ex)
|
||||
TRY
|
||||
{
|
||||
case RETURN_ERROR:
|
||||
remote_fileio_reply (-1, FILEIO_ENOSYS);
|
||||
break;
|
||||
case RETURN_QUIT:
|
||||
remote_fileio_reply (-1, FILEIO_EINTR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
do_remote_fileio_request (buf);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
if (ex.reason == RETURN_QUIT)
|
||||
remote_fileio_reply (-1, FILEIO_EINTR);
|
||||
else
|
||||
remote_fileio_reply (-1, FILEIO_EIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -589,7 +589,7 @@ solib_aix_current_sos (void)
|
||||
/* Implement the "open_symbol_file_object" target_so_ops method. */
|
||||
|
||||
static int
|
||||
solib_aix_open_symbol_file_object (void *from_ttyp)
|
||||
solib_aix_open_symbol_file_object (int from_tty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ find_program_interpreter (void)
|
||||
Note that darwin-nat.c implements pid_to_exec_file. */
|
||||
|
||||
static int
|
||||
open_symbol_file_object (void *from_ttyp)
|
||||
open_symbol_file_object (int from_tty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -507,16 +507,10 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If no open symbol file, attempt to locate and open the main symbol
|
||||
file.
|
||||
|
||||
If FROM_TTYP dereferences to a non-zero integer, allow messages to
|
||||
be printed. This parameter is a pointer rather than an int because
|
||||
open_symbol_file_object is called via catch_errors and
|
||||
catch_errors requires a pointer argument. */
|
||||
/* See solist.h. */
|
||||
|
||||
static int
|
||||
open_symbol_file_object (void *from_ttyp)
|
||||
open_symbol_file_object (int from_tty)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return 0;
|
||||
|
||||
@@ -246,7 +246,7 @@ static int enable_break2 (void);
|
||||
/* Implement the "open_symbol_file_object" target_so_ops method. */
|
||||
|
||||
static int
|
||||
open_symbol_file_object (void *from_ttyp)
|
||||
open_symbol_file_object (int from_tty)
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return 0;
|
||||
|
||||
@@ -984,20 +984,14 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
|
||||
return (name_lm >= vaddr && name_lm < vaddr + size);
|
||||
}
|
||||
|
||||
/* Implement the "open_symbol_file_object" target_so_ops method.
|
||||
|
||||
If no open symbol file, attempt to locate and open the main symbol
|
||||
file. On SVR4 systems, this is the first link map entry. If its
|
||||
name is here, we can open it. Useful when attaching to a process
|
||||
without first loading its symbol file. */
|
||||
/* See solist.h. */
|
||||
|
||||
static int
|
||||
open_symbol_file_object (void *from_ttyp)
|
||||
open_symbol_file_object (int from_tty)
|
||||
{
|
||||
CORE_ADDR lm, l_name;
|
||||
char *filename;
|
||||
int errcode;
|
||||
int from_tty = *(int *)from_ttyp;
|
||||
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
||||
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
|
||||
int l_name_size = TYPE_LENGTH (ptr_type);
|
||||
|
||||
@@ -452,7 +452,7 @@ Could not relocate shared library \"%s\": bad offsets"), so->so_name);
|
||||
}
|
||||
|
||||
static int
|
||||
solib_target_open_symbol_file_object (void *from_ttyp)
|
||||
solib_target_open_symbol_file_object (int from_tty)
|
||||
{
|
||||
/* We can't locate the main symbol file based on the target's
|
||||
knowledge; the user has to specify it. */
|
||||
|
||||
16
gdb/solib.c
16
gdb/solib.c
@@ -760,9 +760,19 @@ update_solib_list (int from_tty)
|
||||
have not opened a symbol file, we may be able to get its
|
||||
symbols now! */
|
||||
if (inf->attach_flag && symfile_objfile == NULL)
|
||||
catch_errors (ops->open_symbol_file_object, &from_tty,
|
||||
"Error reading attached process's symbol file.\n",
|
||||
RETURN_MASK_ALL);
|
||||
{
|
||||
TRY
|
||||
{
|
||||
ops->open_symbol_file_object (from_tty);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error reading attached "
|
||||
"process's symbol file.\n");
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
}
|
||||
|
||||
/* GDB and the inferior's dynamic linker each maintain their own
|
||||
|
||||
@@ -121,11 +121,8 @@ struct target_so_ops
|
||||
struct so_list *(*current_sos) (void);
|
||||
|
||||
/* Find, open, and read the symbols for the main executable. If
|
||||
FROM_TTYP dereferences to a non-zero integer, allow messages to
|
||||
be printed. This parameter is a pointer rather than an int
|
||||
because open_symbol_file_object is called via catch_errors and
|
||||
catch_errors requires a pointer argument. */
|
||||
int (*open_symbol_file_object) (void *from_ttyp);
|
||||
FROM_TTY is non-zero, allow messages to be printed. */
|
||||
int (*open_symbol_file_object) (int from_ttyp);
|
||||
|
||||
/* Determine if PC lies in the dynamic symbol resolution code of
|
||||
the run time loader. */
|
||||
|
||||
@@ -167,31 +167,6 @@ add_symbol_file_from_memory_command (const char *args, int from_tty)
|
||||
symbol_file_add_from_memory (templ, addr, 0, NULL, from_tty);
|
||||
}
|
||||
|
||||
/* Arguments for symbol_file_add_from_memory_wrapper. */
|
||||
|
||||
struct symbol_file_add_from_memory_args
|
||||
{
|
||||
struct bfd *bfd;
|
||||
CORE_ADDR sysinfo_ehdr;
|
||||
size_t size;
|
||||
char *name;
|
||||
int from_tty;
|
||||
};
|
||||
|
||||
/* Wrapper function for symbol_file_add_from_memory, for
|
||||
catch_exceptions. */
|
||||
|
||||
static int
|
||||
symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data)
|
||||
{
|
||||
struct symbol_file_add_from_memory_args *args
|
||||
= (struct symbol_file_add_from_memory_args *) data;
|
||||
|
||||
symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->size,
|
||||
args->name, args->from_tty);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to add the symbols for the vsyscall page, if there is one.
|
||||
This function is called via the inferior_created observer. */
|
||||
|
||||
@@ -203,7 +178,6 @@ add_vsyscall_page (struct target_ops *target, int from_tty)
|
||||
if (gdbarch_vsyscall_range (target_gdbarch (), &vsyscall_range))
|
||||
{
|
||||
struct bfd *bfd;
|
||||
struct symbol_file_add_from_memory_args args;
|
||||
|
||||
if (core_bfd != NULL)
|
||||
bfd = core_bfd;
|
||||
@@ -221,18 +195,24 @@ add_vsyscall_page (struct target_ops *target, int from_tty)
|
||||
"because no executable was specified"));
|
||||
return;
|
||||
}
|
||||
args.bfd = bfd;
|
||||
args.sysinfo_ehdr = vsyscall_range.start;
|
||||
args.size = vsyscall_range.length;
|
||||
|
||||
args.name = xstrprintf ("system-supplied DSO at %s",
|
||||
paddress (target_gdbarch (), vsyscall_range.start));
|
||||
/* Pass zero for FROM_TTY, because the action of loading the
|
||||
vsyscall DSO was not triggered by the user, even if the user
|
||||
typed "run" at the TTY. */
|
||||
args.from_tty = 0;
|
||||
catch_exceptions (current_uiout, symbol_file_add_from_memory_wrapper,
|
||||
&args, RETURN_MASK_ALL);
|
||||
char *name = xstrprintf ("system-supplied DSO at %s",
|
||||
paddress (target_gdbarch (), vsyscall_range.start));
|
||||
TRY
|
||||
{
|
||||
/* Pass zero for FROM_TTY, because the action of loading the
|
||||
vsyscall DSO was not triggered by the user, even if the
|
||||
user typed "run" at the TTY. */
|
||||
symbol_file_add_from_memory (bfd,
|
||||
vsyscall_range.start,
|
||||
vsyscall_range.length,
|
||||
name,
|
||||
0 /* from_tty */);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
exception_print (gdb_stderr, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,15 +54,9 @@ FILE *std_err;
|
||||
|
||||
static int block_depth (struct block *);
|
||||
|
||||
struct print_symbol_args
|
||||
{
|
||||
struct gdbarch *gdbarch;
|
||||
struct symbol *symbol;
|
||||
int depth;
|
||||
struct ui_file *outfile;
|
||||
};
|
||||
static void print_symbol (struct gdbarch *gdbarch, struct symbol *symbol,
|
||||
int depth, struct ui_file *outfile);
|
||||
|
||||
static int print_symbol (void *);
|
||||
|
||||
|
||||
void
|
||||
@@ -357,14 +351,16 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile)
|
||||
block, not any blocks from included symtabs. */
|
||||
ALL_DICT_SYMBOLS (BLOCK_DICT (b), iter, sym)
|
||||
{
|
||||
struct print_symbol_args s;
|
||||
|
||||
s.gdbarch = gdbarch;
|
||||
s.symbol = sym;
|
||||
s.depth = depth + 1;
|
||||
s.outfile = outfile;
|
||||
catch_errors (print_symbol, &s, "Error printing symbol:\n",
|
||||
RETURN_MASK_ERROR);
|
||||
TRY
|
||||
{
|
||||
print_symbol (gdbarch, sym, depth + 1, outfile);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ERROR)
|
||||
{
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"Error printing symbol:\n");
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
}
|
||||
fprintf_filtered (outfile, "\n");
|
||||
@@ -515,18 +511,12 @@ maintenance_print_symbols (const char *args, int from_tty)
|
||||
}
|
||||
}
|
||||
|
||||
/* Print symbol ARGS->SYMBOL on ARGS->OUTFILE. ARGS->DEPTH says how
|
||||
far to indent. ARGS is really a struct print_symbol_args *, but is
|
||||
declared as char * to get it past catch_errors. Returns 0 for error,
|
||||
1 for success. */
|
||||
/* Print symbol SYMBOL on OUTFILE. DEPTH says how far to indent. */
|
||||
|
||||
static int
|
||||
print_symbol (void *args)
|
||||
static void
|
||||
print_symbol (struct gdbarch *gdbarch, struct symbol *symbol,
|
||||
int depth, struct ui_file *outfile)
|
||||
{
|
||||
struct gdbarch *gdbarch = ((struct print_symbol_args *) args)->gdbarch;
|
||||
struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
|
||||
int depth = ((struct print_symbol_args *) args)->depth;
|
||||
struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
|
||||
struct obj_section *section;
|
||||
|
||||
if (SYMBOL_OBJFILE_OWNED (symbol))
|
||||
@@ -546,7 +536,6 @@ print_symbol (void *args)
|
||||
section->the_bfd_section));
|
||||
else
|
||||
fprintf_filtered (outfile, "\n");
|
||||
return 1;
|
||||
}
|
||||
if (SYMBOL_DOMAIN (symbol) == STRUCT_DOMAIN)
|
||||
{
|
||||
@@ -694,7 +683,6 @@ print_symbol (void *args)
|
||||
}
|
||||
}
|
||||
fprintf_filtered (outfile, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
84
gdb/thread.c
84
gdb/thread.c
@@ -30,7 +30,6 @@
|
||||
#include "command.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb.h"
|
||||
#include "btrace.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -720,50 +719,6 @@ any_live_thread_of_process (int pid)
|
||||
return tp_executing;
|
||||
}
|
||||
|
||||
/* Print a list of thread ids currently known, and the total number of
|
||||
threads. To be used from within catch_errors. */
|
||||
static int
|
||||
do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
int num = 0;
|
||||
int current_thread = -1;
|
||||
|
||||
update_thread_list ();
|
||||
|
||||
{
|
||||
ui_out_emit_tuple tuple_emitter (uiout, "thread-ids");
|
||||
|
||||
for (tp = thread_list; tp; tp = tp->next)
|
||||
{
|
||||
if (tp->state == THREAD_EXITED)
|
||||
continue;
|
||||
|
||||
if (tp->ptid == inferior_ptid)
|
||||
current_thread = tp->global_num;
|
||||
|
||||
num++;
|
||||
uiout->field_int ("thread-id", tp->global_num);
|
||||
}
|
||||
}
|
||||
|
||||
if (current_thread != -1)
|
||||
uiout->field_int ("current-thread-id", current_thread);
|
||||
uiout->field_int ("number-of-threads", num);
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
||||
/* Official gdblib interface function to get a list of thread ids and
|
||||
the total number. */
|
||||
enum gdb_rc
|
||||
gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
|
||||
{
|
||||
if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
|
||||
error_message, RETURN_MASK_ALL) < 0)
|
||||
return GDB_RC_FAIL;
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
||||
/* Return true if TP is an active thread. */
|
||||
static int
|
||||
thread_alive (struct thread_info *tp)
|
||||
@@ -1885,13 +1840,8 @@ thread_command (char *tidstr, int from_tty)
|
||||
else
|
||||
{
|
||||
ptid_t previous_ptid = inferior_ptid;
|
||||
enum gdb_rc result;
|
||||
|
||||
result = gdb_thread_select (current_uiout, tidstr, NULL);
|
||||
|
||||
/* If thread switch did not succeed don't notify or print. */
|
||||
if (result == GDB_RC_FAIL)
|
||||
return;
|
||||
thread_select (tidstr, parse_thread_id (tidstr, NULL));
|
||||
|
||||
/* Print if the thread has not changed, otherwise an event will
|
||||
be sent. */
|
||||
@@ -1991,26 +1941,9 @@ show_print_thread_events (struct ui_file *file, int from_tty,
|
||||
value);
|
||||
}
|
||||
|
||||
static int
|
||||
do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
|
||||
void
|
||||
thread_select (const char *tidstr, thread_info *tp)
|
||||
{
|
||||
const char *tidstr = (const char *) tidstr_v;
|
||||
struct thread_info *tp;
|
||||
|
||||
if (uiout->is_mi_like_p ())
|
||||
{
|
||||
int num = value_as_long (parse_and_eval (tidstr));
|
||||
|
||||
tp = find_thread_global_id (num);
|
||||
if (tp == NULL)
|
||||
error (_("Thread ID %d not known."), num);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp = parse_thread_id (tidstr, NULL);
|
||||
gdb_assert (tp != NULL);
|
||||
}
|
||||
|
||||
if (!thread_alive (tp))
|
||||
error (_("Thread ID %s has terminated."), tidstr);
|
||||
|
||||
@@ -2021,8 +1954,6 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
|
||||
/* Since the current thread may have changed, see if there is any
|
||||
exited thread we can now delete. */
|
||||
prune_threads ();
|
||||
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
||||
/* Print thread and frame switch command response. */
|
||||
@@ -2067,15 +1998,6 @@ print_selected_thread_frame (struct ui_out *uiout,
|
||||
}
|
||||
}
|
||||
|
||||
enum gdb_rc
|
||||
gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
|
||||
{
|
||||
if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
|
||||
error_message, RETURN_MASK_ALL) < 0)
|
||||
return GDB_RC_FAIL;
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
||||
/* Update the 'threads_executing' global based on the threads we know
|
||||
about right now. */
|
||||
|
||||
|
||||
@@ -755,7 +755,7 @@ get_image_name (HANDLE h, void *address, int unicode)
|
||||
on how we handle DLL loading during that phase). */
|
||||
|
||||
static int
|
||||
handle_load_dll (void *dummy)
|
||||
handle_load_dll ()
|
||||
{
|
||||
LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
|
||||
char *dll_name;
|
||||
@@ -1540,7 +1540,7 @@ get_windows_debug_event (struct target_ops *ops,
|
||||
CloseHandle (current_event.u.LoadDll.hFile);
|
||||
if (saw_create != 1 || ! windows_initialization_done)
|
||||
break;
|
||||
catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
|
||||
catch_errors (handle_load_dll, (char *) "", RETURN_MASK_ALL);
|
||||
ourstatus->kind = TARGET_WAITKIND_LOADED;
|
||||
ourstatus->value.integer = 0;
|
||||
thread_id = main_thread_id;
|
||||
@@ -1553,7 +1553,7 @@ get_windows_debug_event (struct target_ops *ops,
|
||||
"UNLOAD_DLL_DEBUG_EVENT"));
|
||||
if (saw_create != 1 || ! windows_initialization_done)
|
||||
break;
|
||||
catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
|
||||
catch_errors (handle_unload_dll, (char *) "", RETURN_MASK_ALL);
|
||||
ourstatus->kind = TARGET_WAITKIND_LOADED;
|
||||
ourstatus->value.integer = 0;
|
||||
thread_id = main_thread_id;
|
||||
|
||||
Reference in New Issue
Block a user