xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/gcore.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Generate a core file for the inferior process.
2 
3    Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "elf-bfd.h"
22 #include "infcall.h"
23 #include "inferior.h"
24 #include "gdbcore.h"
25 #include "objfiles.h"
26 #include "solib.h"
27 #include "symfile.h"
28 #include "arch-utils.h"
29 #include "completer.h"
30 #include "gcore.h"
31 #include "cli/cli-decode.h"
32 #include <fcntl.h>
33 #include "regcache.h"
34 #include "regset.h"
35 #include "gdb_bfd.h"
36 #include "readline/tilde.h"
37 #include <algorithm>
38 #include "gdbsupport/gdb_unlinker.h"
39 #include "gdbsupport/byte-vector.h"
40 #include "gdbsupport/scope-exit.h"
41 
42 /* The largest amount of memory to read from the target at once.  We
43    must throttle it to limit the amount of memory used by GDB during
44    generate-core-file for programs with large resident data.  */
45 #define MAX_COPY_BYTES (1024 * 1024)
46 
47 static const char *default_gcore_target (void);
48 static enum bfd_architecture default_gcore_arch (void);
49 static int gcore_memory_sections (bfd *);
50 
51 /* create_gcore_bfd -- helper for gcore_command (exported).
52    Open a new bfd core file for output, and return the handle.  */
53 
54 gdb_bfd_ref_ptr
55 create_gcore_bfd (const char *filename)
56 {
57   gdb_bfd_ref_ptr obfd (gdb_bfd_openw (filename, default_gcore_target ()));
58 
59   if (obfd == NULL)
60     error (_("Failed to open '%s' for output."), filename);
61   bfd_set_format (obfd.get (), bfd_core);
62   bfd_set_arch_mach (obfd.get (), default_gcore_arch (), 0);
63   return obfd;
64 }
65 
66 /* write_gcore_file_1 -- do the actual work of write_gcore_file.  */
67 
68 static void
69 write_gcore_file_1 (bfd *obfd)
70 {
71   gdb::unique_xmalloc_ptr<char> note_data;
72   int note_size = 0;
73   asection *note_sec = NULL;
74 
75   /* An external target method must build the notes section.  */
76   /* FIXME: uweigand/2011-10-06: All architectures that support core file
77      generation should be converted to gdbarch_make_corefile_notes; at that
78      point, the target vector method can be removed.  */
79   if (!gdbarch_make_corefile_notes_p (target_gdbarch ()))
80     note_data = target_make_corefile_notes (obfd, &note_size);
81   else
82     note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd,
83 					     &note_size);
84 
85   if (note_data == NULL || note_size == 0)
86     error (_("Target does not support core file generation."));
87 
88   /* Create the note section.  */
89   note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
90 						 SEC_HAS_CONTENTS
91 						 | SEC_READONLY
92 						 | SEC_ALLOC);
93   if (note_sec == NULL)
94     error (_("Failed to create 'note' section for corefile: %s"),
95 	   bfd_errmsg (bfd_get_error ()));
96 
97   bfd_set_section_vma (note_sec, 0);
98   bfd_set_section_alignment (note_sec, 0);
99   bfd_set_section_size (note_sec, note_size);
100 
101   /* Now create the memory/load sections.  */
102   if (gcore_memory_sections (obfd) == 0)
103     error (_("gcore: failed to get corefile memory sections from target."));
104 
105   /* Write out the contents of the note section.  */
106   if (!bfd_set_section_contents (obfd, note_sec, note_data.get (), 0,
107 				 note_size))
108     warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
109 }
110 
111 /* write_gcore_file -- helper for gcore_command (exported).
112    Compose and write the corefile data to the core file.  */
113 
114 void
115 write_gcore_file (bfd *obfd)
116 {
117   target_prepare_to_generate_core ();
118   SCOPE_EXIT { target_done_generating_core (); };
119   write_gcore_file_1 (obfd);
120 }
121 
122 /* gcore_command -- implements the 'gcore' command.
123    Generate a core file from the inferior process.  */
124 
125 static void
126 gcore_command (const char *args, int from_tty)
127 {
128   gdb::unique_xmalloc_ptr<char> corefilename;
129 
130   /* No use generating a corefile without a target process.  */
131   if (!target_has_execution ())
132     noprocess ();
133 
134   if (args && *args)
135     corefilename.reset (tilde_expand (args));
136   else
137     {
138       /* Default corefile name is "core.PID".  */
139       corefilename = xstrprintf ("core.%d", inferior_ptid.pid ());
140     }
141 
142   if (info_verbose)
143     gdb_printf ("Opening corefile '%s' for output.\n",
144 		corefilename.get ());
145 
146   if (target_supports_dumpcore ())
147     target_dumpcore (corefilename.get ());
148   else
149     {
150       /* Open the output file.  */
151       gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ()));
152 
153       /* Arrange to unlink the file on failure.  */
154       gdb::unlinker unlink_file (corefilename.get ());
155 
156       /* Call worker function.  */
157       write_gcore_file (obfd.get ());
158 
159       /* Succeeded.  */
160       unlink_file.keep ();
161     }
162 
163   gdb_printf ("Saved corefile %s\n", corefilename.get ());
164 }
165 
166 static enum bfd_architecture
167 default_gcore_arch (void)
168 {
169   const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ());
170 
171   if (bfdarch != NULL)
172     return bfdarch->arch;
173   if (current_program_space->exec_bfd () == NULL)
174     error (_("Can't find bfd architecture for corefile (need execfile)."));
175 
176   return bfd_get_arch (current_program_space->exec_bfd ());
177 }
178 
179 static const char *
180 default_gcore_target (void)
181 {
182   /* The gdbarch may define a target to use for core files.  */
183   if (gdbarch_gcore_bfd_target_p (target_gdbarch ()))
184     return gdbarch_gcore_bfd_target (target_gdbarch ());
185 
186   /* Otherwise, try to fall back to the exec target.  This will probably
187      not work for non-ELF targets.  */
188   if (current_program_space->exec_bfd () == NULL)
189     return NULL;
190   else
191     return bfd_get_target (current_program_space->exec_bfd ());
192 }
193 
194 /* Derive a reasonable stack segment by unwinding the target stack,
195    and store its limits in *BOTTOM and *TOP.  Return non-zero if
196    successful.  */
197 
198 static int
199 derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
200 {
201   frame_info_ptr fi, tmp_fi;
202 
203   gdb_assert (bottom);
204   gdb_assert (top);
205 
206   /* Can't succeed without stack and registers.  */
207   if (!target_has_stack () || !target_has_registers ())
208     return 0;
209 
210   /* Can't succeed without current frame.  */
211   fi = get_current_frame ();
212   if (fi == NULL)
213     return 0;
214 
215   /* Save frame pointer of TOS frame.  */
216   *top = get_frame_base (fi);
217   /* If current stack pointer is more "inner", use that instead.  */
218   if (gdbarch_inner_than (get_frame_arch (fi), get_frame_sp (fi), *top))
219     *top = get_frame_sp (fi);
220 
221   /* Find prev-most frame.  */
222   while ((tmp_fi = get_prev_frame (fi)) != NULL)
223     fi = tmp_fi;
224 
225   /* Save frame pointer of prev-most frame.  */
226   *bottom = get_frame_base (fi);
227 
228   /* Now canonicalize their order, so that BOTTOM is a lower address
229      (as opposed to a lower stack frame).  */
230   if (*bottom > *top)
231     {
232       bfd_vma tmp_vma;
233 
234       tmp_vma = *top;
235       *top = *bottom;
236       *bottom = tmp_vma;
237     }
238 
239   return 1;
240 }
241 
242 /* call_target_sbrk --
243    helper function for derive_heap_segment.  */
244 
245 static bfd_vma
246 call_target_sbrk (int sbrk_arg)
247 {
248   struct objfile *sbrk_objf;
249   struct gdbarch *gdbarch;
250   bfd_vma top_of_heap;
251   struct value *target_sbrk_arg;
252   struct value *sbrk_fn, *ret;
253   bfd_vma tmp;
254 
255   if (lookup_minimal_symbol ("sbrk", NULL, NULL).minsym != NULL)
256     {
257       sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf);
258       if (sbrk_fn == NULL)
259 	return (bfd_vma) 0;
260     }
261   else if (lookup_minimal_symbol ("_sbrk", NULL, NULL).minsym != NULL)
262     {
263       sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf);
264       if (sbrk_fn == NULL)
265 	return (bfd_vma) 0;
266     }
267   else
268     return (bfd_vma) 0;
269 
270   gdbarch = sbrk_objf->arch ();
271   target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int,
272 					sbrk_arg);
273   gdb_assert (target_sbrk_arg);
274   ret = call_function_by_hand (sbrk_fn, NULL, target_sbrk_arg);
275   if (ret == NULL)
276     return (bfd_vma) 0;
277 
278   tmp = value_as_long (ret);
279   if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff)
280     return (bfd_vma) 0;
281 
282   top_of_heap = tmp;
283   return top_of_heap;
284 }
285 
286 /* Derive a reasonable heap segment for ABFD by looking at sbrk and
287    the static data sections.  Store its limits in *BOTTOM and *TOP.
288    Return non-zero if successful.  */
289 
290 static int
291 derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
292 {
293   bfd_vma top_of_data_memory = 0;
294   bfd_vma top_of_heap = 0;
295   bfd_size_type sec_size;
296   bfd_vma sec_vaddr;
297   asection *sec;
298 
299   gdb_assert (bottom);
300   gdb_assert (top);
301 
302   /* This function depends on being able to call a function in the
303      inferior.  */
304   if (!target_has_execution ())
305     return 0;
306 
307   /* The following code assumes that the link map is arranged as
308      follows (low to high addresses):
309 
310      ---------------------------------
311      | text sections                 |
312      ---------------------------------
313      | data sections (including bss) |
314      ---------------------------------
315      | heap                          |
316      --------------------------------- */
317 
318   for (sec = abfd->sections; sec; sec = sec->next)
319     {
320       if (bfd_section_flags (sec) & SEC_DATA
321 	  || strcmp (".bss", bfd_section_name (sec)) == 0)
322 	{
323 	  sec_vaddr = bfd_section_vma (sec);
324 	  sec_size = bfd_section_size (sec);
325 	  if (sec_vaddr + sec_size > top_of_data_memory)
326 	    top_of_data_memory = sec_vaddr + sec_size;
327 	}
328     }
329 
330   top_of_heap = call_target_sbrk (0);
331   if (top_of_heap == (bfd_vma) 0)
332     return 0;
333 
334   /* Return results.  */
335   if (top_of_heap > top_of_data_memory)
336     {
337       *bottom = top_of_data_memory;
338       *top = top_of_heap;
339       return 1;
340     }
341 
342   /* No additional heap space needs to be saved.  */
343   return 0;
344 }
345 
346 static void
347 make_output_phdrs (bfd *obfd, asection *osec)
348 {
349   int p_flags = 0;
350   int p_type = 0;
351 
352   /* Memory tag segments have already been handled by the architecture, as
353      those contain arch-specific information.  If we have one of those, just
354      return.  */
355   if (startswith (bfd_section_name (osec), "memtag"))
356     return;
357 
358   /* FIXME: these constants may only be applicable for ELF.  */
359   if (startswith (bfd_section_name (osec), "load"))
360     p_type = PT_LOAD;
361   else if (startswith (bfd_section_name (osec), "note"))
362     p_type = PT_NOTE;
363   else
364     p_type = PT_NULL;
365 
366   p_flags |= PF_R;	/* Segment is readable.  */
367   if (!(bfd_section_flags (osec) & SEC_READONLY))
368     p_flags |= PF_W;	/* Segment is writable.  */
369   if (bfd_section_flags (osec) & SEC_CODE)
370     p_flags |= PF_X;	/* Segment is executable.  */
371 
372   bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
373 }
374 
375 /* find_memory_region_ftype implementation.
376 
377    MEMORY_TAGGED is true if the memory region contains memory tags, false
378    otherwise.
379 
380    DATA is 'bfd *' for the core file GDB is creating.  */
381 
382 static int
383 gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read,
384 		       int write, int exec, int modified, bool memory_tagged,
385 		       void *data)
386 {
387   bfd *obfd = (bfd *) data;
388   asection *osec;
389   flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
390 
391   /* If the memory segment has no permissions set, ignore it, otherwise
392      when we later try to access it for read/write, we'll get an error
393      or jam the kernel.  */
394   if (read == 0 && write == 0 && exec == 0 && modified == 0)
395     {
396       if (info_verbose)
397 	{
398 	  gdb_printf ("Ignore segment, %s bytes at %s\n",
399 		      plongest (size), paddress (target_gdbarch (), vaddr));
400 	}
401 
402       return 0;
403     }
404 
405   if (write == 0 && modified == 0 && !solib_keep_data_in_core (vaddr, size))
406     {
407       /* See if this region of memory lies inside a known file on disk.
408 	 If so, we can avoid copying its contents by clearing SEC_LOAD.  */
409       struct obj_section *objsec;
410 
411       for (objfile *objfile : current_program_space->objfiles ())
412 	ALL_OBJFILE_OSECTIONS (objfile, objsec)
413 	  {
414 	    bfd *abfd = objfile->obfd.get ();
415 	    asection *asec = objsec->the_bfd_section;
416 	    bfd_vma align = (bfd_vma) 1 << bfd_section_alignment (asec);
417 	    bfd_vma start = objsec->addr () & -align;
418 	    bfd_vma end = (objsec->endaddr () + align - 1) & -align;
419 
420 	    /* Match if either the entire memory region lies inside the
421 	       section (i.e. a mapping covering some pages of a large
422 	       segment) or the entire section lies inside the memory region
423 	       (i.e. a mapping covering multiple small sections).
424 
425 	       This BFD was synthesized from reading target memory,
426 	       we don't want to omit that.  */
427 	    if (objfile->separate_debug_objfile_backlink == NULL
428 		&& ((vaddr >= start && vaddr + size <= end)
429 		    || (start >= vaddr && end <= vaddr + size))
430 		&& !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
431 	      {
432 		flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
433 		goto keep;	/* Break out of two nested for loops.  */
434 	      }
435 	  }
436 
437     keep:;
438     }
439 
440   if (write == 0)
441     flags |= SEC_READONLY;
442 
443   if (exec)
444     flags |= SEC_CODE;
445   else
446     flags |= SEC_DATA;
447 
448   osec = bfd_make_section_anyway_with_flags (obfd, "load", flags);
449   if (osec == NULL)
450     {
451       warning (_("Couldn't make gcore segment: %s"),
452 	       bfd_errmsg (bfd_get_error ()));
453       return 1;
454     }
455 
456   if (info_verbose)
457     {
458       gdb_printf ("Save segment, %s bytes at %s\n",
459 		  plongest (size), paddress (target_gdbarch (), vaddr));
460     }
461 
462   bfd_set_section_size (osec, size);
463   bfd_set_section_vma (osec, vaddr);
464   bfd_set_section_lma (osec, 0);
465   return 0;
466 }
467 
468 /* gdbarch_find_memory_region callback for creating a memory tag section.
469 
470    MEMORY_TAGGED is true if the memory region contains memory tags, false
471    otherwise.
472 
473    DATA is 'bfd *' for the core file GDB is creating.  */
474 
475 static int
476 gcore_create_memtag_section_callback (CORE_ADDR vaddr, unsigned long size,
477 				      int read, int write, int exec,
478 				      int modified, bool memory_tagged,
479 				      void *data)
480 {
481   /* Are there memory tags in this particular memory map entry?  */
482   if (!memory_tagged)
483     return 0;
484 
485   bfd *obfd = (bfd *) data;
486 
487   /* Ask the architecture to create a memory tag section for this particular
488      memory map entry.  It will be populated with contents later, as we can't
489      start writing the contents before we have all the sections sorted out.  */
490   asection *memtag_section
491     = gdbarch_create_memtag_section (target_gdbarch (), obfd, vaddr, size);
492 
493   if (memtag_section == nullptr)
494     {
495       warning (_("Couldn't make gcore memory tag segment: %s"),
496 	       bfd_errmsg (bfd_get_error ()));
497       return 1;
498     }
499 
500   if (info_verbose)
501     {
502       gdb_printf (gdb_stdout, "Saved memory tag segment, %s bytes "
503 			      "at %s\n",
504 		  plongest (bfd_section_size (memtag_section)),
505 		  paddress (target_gdbarch (), vaddr));
506     }
507 
508   return 0;
509 }
510 
511 int
512 objfile_find_memory_regions (struct target_ops *self,
513 			     find_memory_region_ftype func, void *obfd)
514 {
515   /* Use objfile data to create memory sections.  */
516   struct obj_section *objsec;
517   bfd_vma temp_bottom, temp_top;
518 
519   /* Call callback function for each objfile section.  */
520   for (objfile *objfile : current_program_space->objfiles ())
521     ALL_OBJFILE_OSECTIONS (objfile, objsec)
522       {
523 	asection *isec = objsec->the_bfd_section;
524 	flagword flags = bfd_section_flags (isec);
525 
526 	/* Separate debug info files are irrelevant for gcore.  */
527 	if (objfile->separate_debug_objfile_backlink != NULL)
528 	  continue;
529 
530 	if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
531 	  {
532 	    int size = bfd_section_size (isec);
533 	    int ret;
534 
535 	    ret = (*func) (objsec->addr (), size,
536 			   1, /* All sections will be readable.  */
537 			   (flags & SEC_READONLY) == 0, /* Writable.  */
538 			   (flags & SEC_CODE) != 0, /* Executable.  */
539 			   1, /* MODIFIED is unknown, pass it as true.  */
540 			   false, /* No memory tags in the object file.  */
541 			   obfd);
542 	    if (ret != 0)
543 	      return ret;
544 	  }
545       }
546 
547   /* Make a stack segment.  */
548   if (derive_stack_segment (&temp_bottom, &temp_top))
549     (*func) (temp_bottom, temp_top - temp_bottom,
550 	     1, /* Stack section will be readable.  */
551 	     1, /* Stack section will be writable.  */
552 	     0, /* Stack section will not be executable.  */
553 	     1, /* Stack section will be modified.  */
554 	     false, /* No memory tags in the object file.  */
555 	     obfd);
556 
557   /* Make a heap segment.  */
558   if (derive_heap_segment (current_program_space->exec_bfd (), &temp_bottom,
559 			   &temp_top))
560     (*func) (temp_bottom, temp_top - temp_bottom,
561 	     1, /* Heap section will be readable.  */
562 	     1, /* Heap section will be writable.  */
563 	     0, /* Heap section will not be executable.  */
564 	     1, /* Heap section will be modified.  */
565 	     false, /* No memory tags in the object file.  */
566 	     obfd);
567 
568   return 0;
569 }
570 
571 static void
572 gcore_copy_callback (bfd *obfd, asection *osec)
573 {
574   bfd_size_type size, total_size = bfd_section_size (osec);
575   file_ptr offset = 0;
576 
577   /* Read-only sections are marked; we don't have to copy their contents.  */
578   if ((bfd_section_flags (osec) & SEC_LOAD) == 0)
579     return;
580 
581   /* Only interested in "load" sections.  */
582   if (!startswith (bfd_section_name (osec), "load"))
583     return;
584 
585   size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES);
586   gdb::byte_vector memhunk (size);
587 
588   while (total_size > 0)
589     {
590       if (size > total_size)
591 	size = total_size;
592 
593       if (target_read_memory (bfd_section_vma (osec) + offset,
594 			      memhunk.data (), size) != 0)
595 	{
596 	  warning (_("Memory read failed for corefile "
597 		     "section, %s bytes at %s."),
598 		   plongest (size),
599 		   paddress (target_gdbarch (), bfd_section_vma (osec)));
600 	  break;
601 	}
602       if (!bfd_set_section_contents (obfd, osec, memhunk.data (),
603 				     offset, size))
604 	{
605 	  warning (_("Failed to write corefile contents (%s)."),
606 		   bfd_errmsg (bfd_get_error ()));
607 	  break;
608 	}
609 
610       total_size -= size;
611       offset += size;
612     }
613 }
614 
615 /* Callback to copy contents to a particular memory tag section.  */
616 
617 static void
618 gcore_copy_memtag_section_callback (bfd *obfd, asection *osec)
619 {
620   /* We are only interested in "memtag" sections.  */
621   if (!startswith (bfd_section_name (osec), "memtag"))
622     return;
623 
624   /* Fill the section with memory tag contents.  */
625   if (!gdbarch_fill_memtag_section (target_gdbarch (), osec))
626     error (_("Failed to fill memory tag section for core file."));
627 }
628 
629 static int
630 gcore_memory_sections (bfd *obfd)
631 {
632   /* Try gdbarch method first, then fall back to target method.  */
633   if (!gdbarch_find_memory_regions_p (target_gdbarch ())
634       || gdbarch_find_memory_regions (target_gdbarch (),
635 				      gcore_create_callback, obfd) != 0)
636     {
637       if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
638 	return 0;			/* FIXME: error return/msg?  */
639     }
640 
641   /* Take care of dumping memory tags, if there are any.  */
642   if (!gdbarch_find_memory_regions_p (target_gdbarch ())
643       || gdbarch_find_memory_regions (target_gdbarch (),
644 				      gcore_create_memtag_section_callback,
645 				      obfd) != 0)
646     {
647       if (target_find_memory_regions (gcore_create_memtag_section_callback,
648 				      obfd) != 0)
649 	return 0;
650     }
651 
652   /* Record phdrs for section-to-segment mapping.  */
653   for (asection *sect : gdb_bfd_sections (obfd))
654     make_output_phdrs (obfd, sect);
655 
656   /* Copy memory region and memory tag contents.  */
657   for (asection *sect : gdb_bfd_sections (obfd))
658     {
659       gcore_copy_callback (obfd, sect);
660       gcore_copy_memtag_section_callback (obfd, sect);
661     }
662 
663   return 1;
664 }
665 
666 /* See gcore.h.  */
667 
668 thread_info *
669 gcore_find_signalled_thread ()
670 {
671   thread_info *curr_thr = inferior_thread ();
672   if (curr_thr->state != THREAD_EXITED
673       && curr_thr->stop_signal () != GDB_SIGNAL_0)
674     return curr_thr;
675 
676   for (thread_info *thr : current_inferior ()->non_exited_threads ())
677     if (thr->stop_signal () != GDB_SIGNAL_0)
678       return thr;
679 
680   /* Default to the current thread, unless it has exited.  */
681   if (curr_thr->state != THREAD_EXITED)
682     return curr_thr;
683 
684   return nullptr;
685 }
686 
687 void _initialize_gcore ();
688 void
689 _initialize_gcore ()
690 {
691   cmd_list_element *generate_core_file_cmd
692     = add_com ("generate-core-file", class_files, gcore_command, _("\
693 Save a core file with the current state of the debugged process.\n\
694 Usage: generate-core-file [FILENAME]\n\
695 Argument is optional filename.  Default filename is 'core.PROCESS_ID'."));
696 
697   add_com_alias ("gcore", generate_core_file_cmd, class_files, 1);
698 }
699