From b31488a3449cd97297b0972c016016f1d4c60389 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Tue, 28 Jul 2020 17:29:35 +0200 Subject: [PATCH] gdb: Implement native dumpcore function Add new API for systems with native kernel support for dumping a process on demand. Wire it into the gdb's gcore functionality. gdb/ChangeLog: * target.h (supports_dumpcore, dumpcore): New function declarations. * target.c (supports_dumpcore, dumpcore): New functions. * target-delegates.c: Rebuild. * gcore.c (gcore_command): Use target_supports_dumpcore () and target_dumpcore (). --- gdb/ChangeLog | 10 +++++++++ gdb/gcore.c | 21 +++++++++++------- gdb/target-delegates.c | 50 ++++++++++++++++++++++++++++++++++++++++++ gdb/target.h | 18 +++++++++++++++ 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 261a407b0a4..038d11702ab 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2020-08-13 Kamil Rytarowski + + * target.h (supports_dumpcore, dumpcore): New + function declarations. + * target.c (supports_dumpcore, dumpcore): New + functions. + * target-delegates.c: Rebuild. + * gcore.c (gcore_command): Use target_supports_dumpcore () + and target_dumpcore (). + 2020-08-13 Aaron Merey * debuginfod-support.c: Replace global variables with user_data. diff --git a/gdb/gcore.c b/gdb/gcore.c index 7b653fb74e3..d0e36b1a708 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -145,17 +145,22 @@ gcore_command (const char *args, int from_tty) "Opening corefile '%s' for output.\n", corefilename.get ()); - /* Open the output file. */ - gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ())); + if (target_supports_dumpcore ()) + target_dumpcore (corefilename.get ()); + else + { + /* Open the output file. */ + gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ())); - /* Arrange to unlink the file on failure. */ - gdb::unlinker unlink_file (corefilename.get ()); + /* Arrange to unlink the file on failure. */ + gdb::unlinker unlink_file (corefilename.get ()); - /* Call worker function. */ - write_gcore_file (obfd.get ()); + /* Call worker function. */ + write_gcore_file (obfd.get ()); - /* Succeeded. */ - unlink_file.keep (); + /* Succeeded. */ + unlink_file.keep (); + } fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename.get ()); } diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index c28af097183..15f441edf28 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -108,6 +108,8 @@ struct dummy_target : public target_ops bool supports_disable_randomization () override; bool supports_string_tracing () override; bool supports_evaluation_of_breakpoint_conditions () override; + bool supports_dumpcore () override; + void dumpcore (const char *arg0) override; bool can_run_breakpoint_commands () override; struct gdbarch *thread_architecture (ptid_t arg0) override; struct address_space *thread_address_space (ptid_t arg0) override; @@ -277,6 +279,8 @@ struct debug_target : public target_ops bool supports_disable_randomization () override; bool supports_string_tracing () override; bool supports_evaluation_of_breakpoint_conditions () override; + bool supports_dumpcore () override; + void dumpcore (const char *arg0) override; bool can_run_breakpoint_commands () override; struct gdbarch *thread_architecture (ptid_t arg0) override; struct address_space *thread_address_space (ptid_t arg0) override; @@ -2825,6 +2829,52 @@ debug_target::supports_evaluation_of_breakpoint_conditions () return result; } +bool +target_ops::supports_dumpcore () +{ + return this->beneath ()->supports_dumpcore (); +} + +bool +dummy_target::supports_dumpcore () +{ + return false; +} + +bool +debug_target::supports_dumpcore () +{ + bool result; + fprintf_unfiltered (gdb_stdlog, "-> %s->supports_dumpcore (...)\n", this->beneath ()->shortname ()); + result = this->beneath ()->supports_dumpcore (); + fprintf_unfiltered (gdb_stdlog, "<- %s->supports_dumpcore (", this->beneath ()->shortname ()); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_bool (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + +void +target_ops::dumpcore (const char *arg0) +{ + this->beneath ()->dumpcore (arg0); +} + +void +dummy_target::dumpcore (const char *arg0) +{ +} + +void +debug_target::dumpcore (const char *arg0) +{ + fprintf_unfiltered (gdb_stdlog, "-> %s->dumpcore (...)\n", this->beneath ()->shortname ()); + this->beneath ()->dumpcore (arg0); + fprintf_unfiltered (gdb_stdlog, "<- %s->dumpcore (", this->beneath ()->shortname ()); + target_debug_print_const_char_p (arg0); + fputs_unfiltered (")\n", gdb_stdlog); +} + bool target_ops::can_run_breakpoint_commands () { diff --git a/gdb/target.h b/gdb/target.h index 4e8d4cccd5c..71d575f2917 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -881,6 +881,14 @@ struct target_ops virtual bool supports_evaluation_of_breakpoint_conditions () TARGET_DEFAULT_RETURN (false); + /* Does this target support native dumpcore API? */ + virtual bool supports_dumpcore () + TARGET_DEFAULT_RETURN (false); + + /* Generate the core file with native target API. */ + virtual void dumpcore (const char *filename) + TARGET_DEFAULT_IGNORE (); + /* Does this target support evaluation of breakpoint commands on its end? */ virtual bool can_run_breakpoint_commands () @@ -1499,6 +1507,16 @@ int target_supports_disable_randomization (void); #define target_supports_evaluation_of_breakpoint_conditions() \ (current_top_target ()->supports_evaluation_of_breakpoint_conditions) () +/* Does this target support dumpcore API? */ + +#define target_supports_dumpcore() \ + (current_top_target ()->supports_dumpcore) () + +/* Generate the core file with target API. */ + +#define target_dumpcore(x) \ + (current_top_target ()->dumpcore (x)) + /* Returns true if this target can handle breakpoint commands on its end. */ -- 2.30.2