static void find_command (char *args, int from_tty) { struct gdbarch *gdbarch = get_current_arch (); bfd_boolean big_p = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG; /* Command line parameters. These are initialized to avoid uninitialized warnings from -Wall. */ ULONGEST max_count = 0; char *pattern_buf = 0; ULONGEST pattern_len = 0; CORE_ADDR start_addr = 0; ULONGEST search_space_len = 0; /* End of command line parameters. */ unsigned int found_count; CORE_ADDR last_found_addr; struct cleanup *old_cleanups; parse_find_args (args, &max_count, &pattern_buf, &pattern_len, &start_addr, &search_space_len, big_p); old_cleanups = make_cleanup (free_current_contents, &pattern_buf); /* Perform the search. */ found_count = 0; last_found_addr = 0; while (search_space_len >= pattern_len && found_count < max_count) { /* Offset from start of this iteration to the next iteration. */ ULONGEST next_iter_incr; CORE_ADDR found_addr; int found = target_search_memory (start_addr, search_space_len, pattern_buf, pattern_len, &found_addr); if (found <= 0) break; print_address (gdbarch, found_addr, gdb_stdout); printf_filtered ("\n"); ++found_count; last_found_addr = found_addr; /* Begin next iteration at one byte past this match. */ next_iter_incr = (found_addr - start_addr) + 1; /* For robustness, we don't let search_space_len go -ve here. */ if (search_space_len >= next_iter_incr) search_space_len -= next_iter_incr; else search_space_len = 0; start_addr += next_iter_incr; } /* Record and print the results. */ set_internalvar_integer (lookup_internalvar ("numfound"), found_count); if (found_count > 0) { struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; set_internalvar (lookup_internalvar ("_"), value_from_pointer (ptr_type, last_found_addr)); } if (found_count == 0) printf_filtered ("Pattern not found.\n"); else printf_filtered ("%d pattern%s found.\n", found_count, found_count > 1 ? "s" : ""); do_cleanups (old_cleanups); }
static void core_open (char *filename, int from_tty) { const char *p; int siggy; struct cleanup *old_chain; char *temp; bfd *temp_bfd; int scratch_chan; int flags; volatile struct gdb_exception except; target_preopen (from_tty); if (!filename) { if (core_bfd) error (_("No core file specified. (Use `detach' " "to stop debugging a core file.)")); else error (_("No core file specified.")); } filename = tilde_expand (filename); if (!IS_ABSOLUTE_PATH (filename)) { temp = concat (current_directory, "/", filename, (char *) NULL); xfree (filename); filename = temp; } old_chain = make_cleanup (xfree, filename); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; scratch_chan = gdb_open_cloexec (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); temp_bfd = gdb_bfd_fopen (filename, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan); if (temp_bfd == NULL) perror_with_name (filename); if (!bfd_check_format (temp_bfd, bfd_core) && !gdb_check_format (temp_bfd)) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ make_cleanup_bfd_unref (temp_bfd); error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } /* Looks semi-reasonable. Toss the old core file and work on the new. */ do_cleanups (old_chain); unpush_target (&core_ops); core_bfd = temp_bfd; old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); core_gdbarch = gdbarch_from_bfd (core_bfd); /* Find a suitable core file handler to munch on core_bfd */ core_vec = sniff_core_bfd (core_bfd); validate_files (); core_data = XZALLOC (struct target_section_table); /* Find the data section */ if (build_section_table (core_bfd, &core_data->sections, &core_data->sections_end)) error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); /* If we have no exec file, try to set the architecture from the core file. We don't do this unconditionally since an exec file typically contains more information that helps us determine the architecture than a core file. */ if (!exec_bfd) set_gdbarch_from_file (core_bfd); push_target (&core_ops); discard_cleanups (old_chain); /* Do this before acknowledging the inferior, so if post_create_inferior throws (can happen easilly if you're loading a core file with the wrong exec), we aren't left with threads from the previous inferior. */ init_thread_list (); inferior_ptid = null_ptid; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the last debug session --- e.g., b foo; run; gcore core1; step; gcore core2; core core1; core core2 --- then there's potential for get_current_regcache to return the cached regcache of the previous session, and the frame cache being stale. */ registers_changed (); /* Build up thread list from BFD sections, and possibly set the current thread to the .reg/NN section matching the .reg section. */ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); if (ptid_equal (inferior_ptid, null_ptid)) { /* Either we found no .reg/NN section, and hence we have a non-threaded core (single-threaded, from gdb's perspective), or for some reason add_to_thread_list couldn't determine which was the "main" thread. The latter case shouldn't usually happen, but we're dealing with input here, which can always be broken in different ways. */ struct thread_info *thread = first_thread_of_process (-1); if (thread == NULL) { inferior_appeared (current_inferior (), CORELOW_PID); inferior_ptid = pid_to_ptid (CORELOW_PID); add_thread_silent (inferior_ptid); } else switch_to_thread (thread->ptid); } post_create_inferior (&core_ops, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ TRY_CATCH (except, RETURN_MASK_ERROR) { target_find_new_threads (); } if (except.reason < 0) exception_print (gdb_stderr, except); p = bfd_core_file_failing_command (core_bfd); if (p) printf_filtered (_("Core was generated by `%s'.\n"), p); /* Clearing any previous state of convenience variables. */ clear_exit_convenience_vars (); siggy = bfd_core_file_failing_signal (core_bfd); if (siggy > 0) { /* If we don't have a CORE_GDBARCH to work with, assume a native core (map gdb_signal from host signals). If we do have CORE_GDBARCH to work with, but no gdb_signal_from_target implementation for that gdbarch, as a fallback measure, assume the host signal mapping. It'll be correct for native cores, but most likely incorrect for cross-cores. */ enum gdb_signal sig = (core_gdbarch != NULL && gdbarch_gdb_signal_from_target_p (core_gdbarch) ? gdbarch_gdb_signal_from_target (core_gdbarch, siggy) : gdb_signal_from_host (siggy)); printf_filtered (_("Program terminated with signal %s, %s.\n"), gdb_signal_to_name (sig), gdb_signal_to_string (sig)); /* Set the value of the internal variable $_exitsignal, which holds the signal uncaught by the inferior. */ set_internalvar_integer (lookup_internalvar ("_exitsignal"), siggy); } /* Fetch all registers from core file. */ target_fetch_registers (get_current_regcache (), -1); /* Now, set up the frame cache, and print the top of stack. */ reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); }
void core_target_open (const char *arg, int from_tty) { const char *p; int siggy; int scratch_chan; int flags; target_preopen (from_tty); if (!arg) { if (core_bfd) error (_("No core file specified. (Use `detach' " "to stop debugging a core file.)")); else error (_("No core file specified.")); } gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg)); if (!IS_ABSOLUTE_PATH (filename.get ())) filename.reset (concat (current_directory, "/", filename.get (), (char *) NULL)); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; scratch_chan = gdb_open_cloexec (filename.get (), flags, 0); if (scratch_chan < 0) perror_with_name (filename.get ()); gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename.get (), gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan)); if (temp_bfd == NULL) perror_with_name (filename.get ()); if (!bfd_check_format (temp_bfd.get (), bfd_core) && !gdb_check_format (temp_bfd.get ())) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ error (_("\"%s\" is not a core dump: %s"), filename.get (), bfd_errmsg (bfd_get_error ())); } current_program_space->cbfd = std::move (temp_bfd); core_target *target = new core_target (); /* Own the target until it is successfully pushed. */ target_ops_up target_holder (target); validate_files (); /* If we have no exec file, try to set the architecture from the core file. We don't do this unconditionally since an exec file typically contains more information that helps us determine the architecture than a core file. */ if (!exec_bfd) set_gdbarch_from_file (core_bfd); push_target (std::move (target_holder)); inferior_ptid = null_ptid; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the last debug session --- e.g., b foo; run; gcore core1; step; gcore core2; core core1; core core2 --- then there's potential for get_current_regcache to return the cached regcache of the previous session, and the frame cache being stale. */ registers_changed (); /* Build up thread list from BFD sections, and possibly set the current thread to the .reg/NN section matching the .reg section. */ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); if (inferior_ptid == null_ptid) { /* Either we found no .reg/NN section, and hence we have a non-threaded core (single-threaded, from gdb's perspective), or for some reason add_to_thread_list couldn't determine which was the "main" thread. The latter case shouldn't usually happen, but we're dealing with input here, which can always be broken in different ways. */ thread_info *thread = first_thread_of_inferior (current_inferior ()); if (thread == NULL) { inferior_appeared (current_inferior (), CORELOW_PID); inferior_ptid = ptid_t (CORELOW_PID); add_thread_silent (inferior_ptid); } else switch_to_thread (thread); } post_create_inferior (target, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ try { target_update_thread_list (); } catch (const gdb_exception_error &except) { exception_print (gdb_stderr, except); } p = bfd_core_file_failing_command (core_bfd); if (p) printf_filtered (_("Core was generated by `%s'.\n"), p); /* Clearing any previous state of convenience variables. */ clear_exit_convenience_vars (); siggy = bfd_core_file_failing_signal (core_bfd); if (siggy > 0) { gdbarch *core_gdbarch = target->core_gdbarch (); /* If we don't have a CORE_GDBARCH to work with, assume a native core (map gdb_signal from host signals). If we do have CORE_GDBARCH to work with, but no gdb_signal_from_target implementation for that gdbarch, as a fallback measure, assume the host signal mapping. It'll be correct for native cores, but most likely incorrect for cross-cores. */ enum gdb_signal sig = (core_gdbarch != NULL && gdbarch_gdb_signal_from_target_p (core_gdbarch) ? gdbarch_gdb_signal_from_target (core_gdbarch, siggy) : gdb_signal_from_host (siggy)); printf_filtered (_("Program terminated with signal %s, %s.\n"), gdb_signal_to_name (sig), gdb_signal_to_string (sig)); /* Set the value of the internal variable $_exitsignal, which holds the signal uncaught by the inferior. */ set_internalvar_integer (lookup_internalvar ("_exitsignal"), siggy); } /* Fetch all registers from core file. */ target_fetch_registers (get_current_regcache (), -1); /* Now, set up the frame cache, and print the top of stack. */ reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); /* Current thread should be NUM 1 but the user does not know that. If a program is single threaded gdb in general does not mention anything about threads. That is why the test is >= 2. */ if (thread_count () >= 2) { try { thread_command (NULL, from_tty); } catch (const gdb_exception_error &except) { exception_print (gdb_stderr, except); } } }