Commit | Line | Data |
---|---|---|
8a1ea21f DE |
1 | /* GDB routines for supporting auto-loaded scripts. |
2 | ||
7b6bb8da | 3 | Copyright (C) 2010, 2011 Free Software Foundation, Inc. |
8a1ea21f DE |
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" | |
dbaefcf7 | 21 | #include "filenames.h" |
8a1ea21f DE |
22 | #include "gdb_string.h" |
23 | #include "gdb_regex.h" | |
24 | #include "top.h" | |
25 | #include "exceptions.h" | |
26 | #include "command.h" | |
27 | #include "gdbcmd.h" | |
28 | #include "observer.h" | |
29 | #include "progspace.h" | |
30 | #include "objfiles.h" | |
31 | #include "python.h" | |
8a1ea21f DE |
32 | #include "cli/cli-cmds.h" |
33 | ||
88a1906b DE |
34 | /* Internal-use flag to enable/disable auto-loading. |
35 | This is true if we should auto-load python code when an objfile is opened, | |
36 | false otherwise. | |
37 | ||
a86caf66 | 38 | Both auto_load_scripts && gdbpy_global_auto_load must be true to enable |
88a1906b DE |
39 | auto-loading. |
40 | ||
41 | This flag exists to facilitate deferring auto-loading during start-up | |
42 | until after ./.gdbinit has been read; it may augment the search directories | |
43 | used to find the scripts. */ | |
44 | int gdbpy_global_auto_load = 1; | |
45 | ||
46 | #ifdef HAVE_PYTHON | |
47 | ||
48 | #include "python-internal.h" | |
49 | ||
8a1ea21f DE |
50 | /* NOTE: It's trivial to also support auto-loading normal gdb scripts. |
51 | There has yet to be a need so it's not implemented. */ | |
52 | ||
53 | /* The suffix of per-objfile scripts to auto-load. | |
54 | E.g. When the program loads libfoo.so, look for libfoo-gdb.py. */ | |
55 | #define GDBPY_AUTO_FILE_NAME "-gdb.py" | |
56 | ||
57 | /* The section to look for scripts (in file formats that support sections). | |
58 | Each entry in this section is a byte of value 1, and then the nul-terminated | |
59 | name of the script. The script name may include a directory. | |
60 | The leading byte is to allow upward compatible extensions. */ | |
61 | #define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts" | |
62 | ||
63 | /* For scripts specified in .debug_gdb_scripts, multiple objfiles may load | |
64 | the same script. There's no point in loading the script multiple times, | |
65 | and there can be a lot of objfiles and scripts, so we keep track of scripts | |
66 | loaded this way. */ | |
67 | ||
68 | struct auto_load_pspace_info | |
69 | { | |
70 | /* For each program space we keep track of loaded scripts. */ | |
71 | struct htab *loaded_scripts; | |
dbaefcf7 DE |
72 | |
73 | /* Non-zero if we've issued the warning about an auto-load script not being | |
74 | found. We only want to issue this warning once. */ | |
75 | int script_not_found_warning_printed; | |
8a1ea21f DE |
76 | }; |
77 | ||
78 | /* Objects of this type are stored in the loaded script hash table. */ | |
79 | ||
dbaefcf7 | 80 | struct loaded_script |
8a1ea21f DE |
81 | { |
82 | /* Name as provided by the objfile. */ | |
83 | const char *name; | |
84 | /* Full path name or NULL if script wasn't found (or was otherwise | |
85 | inaccessible). */ | |
86 | const char *full_path; | |
87 | }; | |
88 | ||
88a1906b | 89 | /* User-settable option to enable/disable auto-loading: |
a86caf66 DE |
90 | set auto-load-scripts on|off |
91 | This is true if we should auto-load associated scripts when an objfile | |
92 | is opened, false otherwise. | |
93 | At the moment, this only affects python scripts, but there's no reason | |
94 | one couldn't also have other kinds of auto-loaded scripts, and there's | |
95 | no reason to have them each controlled by a separate flag. | |
96 | So we elide "python" from the name here and in the option. | |
97 | The fact that it lives here is just an implementation detail. */ | |
98 | static int auto_load_scripts = 1; | |
8a1ea21f DE |
99 | |
100 | /* Per-program-space data key. */ | |
101 | static const struct program_space_data *auto_load_pspace_data; | |
102 | ||
103 | static void | |
104 | auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg) | |
105 | { | |
106 | struct auto_load_pspace_info *info; | |
107 | ||
108 | info = program_space_data (pspace, auto_load_pspace_data); | |
109 | if (info != NULL) | |
110 | { | |
111 | if (info->loaded_scripts) | |
112 | htab_delete (info->loaded_scripts); | |
113 | xfree (info); | |
114 | } | |
115 | } | |
116 | ||
117 | /* Get the current autoload data. If none is found yet, add it now. This | |
118 | function always returns a valid object. */ | |
119 | ||
120 | static struct auto_load_pspace_info * | |
121 | get_auto_load_pspace_data (struct program_space *pspace) | |
122 | { | |
123 | struct auto_load_pspace_info *info; | |
124 | ||
125 | info = program_space_data (pspace, auto_load_pspace_data); | |
126 | if (info == NULL) | |
127 | { | |
128 | info = XZALLOC (struct auto_load_pspace_info); | |
129 | set_program_space_data (pspace, auto_load_pspace_data, info); | |
130 | } | |
131 | ||
132 | return info; | |
133 | } | |
134 | ||
135 | /* Hash function for the loaded script hash. */ | |
136 | ||
137 | static hashval_t | |
138 | hash_loaded_script_entry (const void *data) | |
139 | { | |
dbaefcf7 | 140 | const struct loaded_script *e = data; |
d59b6f6c | 141 | |
8a1ea21f DE |
142 | return htab_hash_string (e->name); |
143 | } | |
144 | ||
145 | /* Equality function for the loaded script hash. */ | |
146 | ||
147 | static int | |
148 | eq_loaded_script_entry (const void *a, const void *b) | |
149 | { | |
dbaefcf7 DE |
150 | const struct loaded_script *ea = a; |
151 | const struct loaded_script *eb = b; | |
d59b6f6c | 152 | |
8a1ea21f DE |
153 | return strcmp (ea->name, eb->name) == 0; |
154 | } | |
155 | ||
dbaefcf7 | 156 | /* Initialize the table to track loaded scripts. |
8a1ea21f DE |
157 | Each entry is hashed by the full path name. */ |
158 | ||
159 | static void | |
dbaefcf7 | 160 | init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info) |
8a1ea21f DE |
161 | { |
162 | /* Choose 31 as the starting size of the hash table, somewhat arbitrarily. | |
163 | Space for each entry is obtained with one malloc so we can free them | |
164 | easily. */ | |
165 | ||
166 | pspace_info->loaded_scripts = htab_create (31, | |
167 | hash_loaded_script_entry, | |
168 | eq_loaded_script_entry, | |
169 | xfree); | |
dbaefcf7 DE |
170 | |
171 | pspace_info->script_not_found_warning_printed = FALSE; | |
172 | } | |
173 | ||
174 | /* Wrapper on get_auto_load_pspace_data to also allocate the hash table | |
175 | for loading scripts. */ | |
176 | ||
177 | static struct auto_load_pspace_info * | |
178 | get_auto_load_pspace_data_for_loading (struct program_space *pspace) | |
179 | { | |
180 | struct auto_load_pspace_info *info; | |
181 | ||
182 | info = get_auto_load_pspace_data (pspace); | |
183 | if (info->loaded_scripts == NULL) | |
184 | init_loaded_scripts_info (info); | |
185 | ||
186 | return info; | |
187 | } | |
188 | ||
189 | /* Add script NAME to hash table HTAB. | |
190 | FULL_PATH is NULL if the script wasn't found. | |
191 | The result is true if the script was already in the hash table. */ | |
192 | ||
193 | static int | |
194 | maybe_add_script (struct htab *htab, const char *name, const char *full_path) | |
195 | { | |
196 | struct loaded_script **slot, entry; | |
197 | int in_hash_table; | |
198 | ||
199 | entry.name = name; | |
200 | entry.full_path = full_path; | |
201 | slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT); | |
202 | in_hash_table = *slot != NULL; | |
203 | ||
204 | /* If this script is not in the hash table, add it. */ | |
205 | ||
206 | if (! in_hash_table) | |
207 | { | |
208 | char *p; | |
209 | ||
210 | /* Allocate all space in one chunk so it's easier to free. */ | |
211 | *slot = xmalloc (sizeof (**slot) | |
212 | + strlen (name) + 1 | |
213 | + (full_path != NULL ? (strlen (full_path) + 1) : 0)); | |
214 | p = ((char*) *slot) + sizeof (**slot); | |
215 | strcpy (p, name); | |
216 | (*slot)->name = p; | |
217 | if (full_path != NULL) | |
218 | { | |
219 | p += strlen (p) + 1; | |
220 | strcpy (p, full_path); | |
221 | (*slot)->full_path = p; | |
222 | } | |
223 | else | |
224 | (*slot)->full_path = NULL; | |
225 | } | |
226 | ||
227 | return in_hash_table; | |
8a1ea21f DE |
228 | } |
229 | ||
230 | /* Load scripts specified in OBJFILE. | |
231 | START,END delimit a buffer containing a list of nul-terminated | |
232 | file names. | |
233 | SOURCE_NAME is used in error messages. | |
234 | ||
235 | Scripts are found per normal "source -s" command processing. | |
236 | First the script is looked for in $cwd. If not found there the | |
237 | source search path is used. | |
238 | ||
239 | The section contains a list of path names of files containing | |
240 | python code to load. Each path is null-terminated. */ | |
241 | ||
242 | static void | |
243 | source_section_scripts (struct objfile *objfile, const char *source_name, | |
244 | const char *start, const char *end) | |
245 | { | |
246 | const char *p; | |
247 | struct auto_load_pspace_info *pspace_info; | |
8a1ea21f | 248 | |
dbaefcf7 | 249 | pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); |
8a1ea21f DE |
250 | |
251 | for (p = start; p < end; ++p) | |
252 | { | |
253 | const char *file; | |
254 | FILE *stream; | |
255 | char *full_path; | |
256 | int opened, in_hash_table; | |
257 | ||
258 | if (*p != 1) | |
259 | { | |
260 | warning (_("Invalid entry in %s section"), GDBPY_AUTO_SECTION_NAME); | |
261 | /* We could try various heuristics to find the next valid entry, | |
262 | but it's safer to just punt. */ | |
263 | break; | |
264 | } | |
265 | file = ++p; | |
266 | ||
267 | while (p < end && *p != '\0') | |
268 | ++p; | |
269 | if (p == end) | |
270 | { | |
271 | char *buf = alloca (p - file + 1); | |
d59b6f6c | 272 | |
8a1ea21f DE |
273 | memcpy (buf, file, p - file); |
274 | buf[p - file] = '\0'; | |
275 | warning (_("Non-null-terminated path in %s: %s"), | |
276 | source_name, buf); | |
277 | /* Don't load it. */ | |
278 | break; | |
279 | } | |
280 | if (p == file) | |
281 | { | |
282 | warning (_("Empty path in %s"), source_name); | |
283 | continue; | |
284 | } | |
285 | ||
286 | opened = find_and_open_script (file, 1 /*search_path*/, | |
287 | &stream, &full_path); | |
288 | ||
dbaefcf7 DE |
289 | /* If one script isn't found it's not uncommon for more to not be |
290 | found either. We don't want to print an error message for each | |
291 | script, too much noise. Instead, we print the warning once and tell | |
292 | the user how to find the list of scripts that weren't loaded. | |
8a1ea21f | 293 | |
dbaefcf7 | 294 | IWBN if complaints.c were more general-purpose. */ |
8a1ea21f | 295 | |
dbaefcf7 DE |
296 | in_hash_table = maybe_add_script (pspace_info->loaded_scripts, file, |
297 | opened ? full_path : NULL); | |
8a1ea21f | 298 | |
8a1ea21f DE |
299 | if (! opened) |
300 | { | |
dbaefcf7 DE |
301 | /* We don't throw an error, the program is still debuggable. */ |
302 | if (! pspace_info->script_not_found_warning_printed) | |
303 | { | |
fd20d931 DE |
304 | warning (_("Missing auto-load scripts referenced in section %s\n\ |
305 | of file %s\n\ | |
dbaefcf7 | 306 | Use `info auto-load-scripts [REGEXP]' to list them."), |
fd20d931 | 307 | GDBPY_AUTO_SECTION_NAME, objfile->name); |
dbaefcf7 DE |
308 | pspace_info->script_not_found_warning_printed = TRUE; |
309 | } | |
8a1ea21f | 310 | } |
562f943b DE |
311 | else |
312 | { | |
313 | /* If this file is not currently loaded, load it. */ | |
314 | if (! in_hash_table) | |
d234ef5c | 315 | source_python_script_for_objfile (objfile, full_path); |
562f943b | 316 | fclose (stream); |
d200ab1e | 317 | xfree (full_path); |
562f943b | 318 | } |
8a1ea21f DE |
319 | } |
320 | } | |
321 | ||
322 | /* Load scripts specified in section SECTION_NAME of OBJFILE. */ | |
323 | ||
324 | static void | |
325 | auto_load_section_scripts (struct objfile *objfile, const char *section_name) | |
326 | { | |
327 | bfd *abfd = objfile->obfd; | |
328 | asection *scripts_sect; | |
329 | bfd_size_type size; | |
330 | char *p; | |
331 | struct cleanup *cleanups; | |
332 | ||
333 | scripts_sect = bfd_get_section_by_name (abfd, section_name); | |
334 | if (scripts_sect == NULL) | |
335 | return; | |
336 | ||
337 | size = bfd_get_section_size (scripts_sect); | |
338 | p = xmalloc (size); | |
339 | ||
340 | cleanups = make_cleanup (xfree, p); | |
341 | ||
342 | if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size)) | |
343 | source_section_scripts (objfile, section_name, p, p + size); | |
344 | else | |
345 | warning (_("Couldn't read %s section of %s"), | |
346 | section_name, bfd_get_filename (abfd)); | |
347 | ||
348 | do_cleanups (cleanups); | |
349 | } | |
350 | ||
351 | /* Clear the table of loaded section scripts. */ | |
352 | ||
353 | static void | |
354 | clear_section_scripts (void) | |
355 | { | |
356 | struct program_space *pspace = current_program_space; | |
357 | struct auto_load_pspace_info *info; | |
358 | ||
359 | info = program_space_data (pspace, auto_load_pspace_data); | |
360 | if (info != NULL && info->loaded_scripts != NULL) | |
361 | { | |
362 | htab_delete (info->loaded_scripts); | |
363 | info->loaded_scripts = NULL; | |
dbaefcf7 | 364 | info->script_not_found_warning_printed = FALSE; |
8a1ea21f DE |
365 | } |
366 | } | |
367 | ||
368 | /* Look for the auto-load script associated with OBJFILE and load it. */ | |
369 | ||
370 | static void | |
371 | auto_load_objfile_script (struct objfile *objfile, const char *suffix) | |
372 | { | |
373 | char *realname; | |
374 | char *filename, *debugfile; | |
375 | int len; | |
376 | FILE *input; | |
377 | struct cleanup *cleanups; | |
378 | ||
379 | realname = gdb_realpath (objfile->name); | |
380 | len = strlen (realname); | |
381 | filename = xmalloc (len + strlen (suffix) + 1); | |
382 | memcpy (filename, realname, len); | |
383 | strcpy (filename + len, suffix); | |
384 | ||
385 | cleanups = make_cleanup (xfree, filename); | |
386 | make_cleanup (xfree, realname); | |
387 | ||
388 | input = fopen (filename, "r"); | |
389 | debugfile = filename; | |
390 | ||
391 | if (!input && debug_file_directory) | |
392 | { | |
393 | /* Also try the same file in the separate debug info directory. */ | |
394 | debugfile = xmalloc (strlen (filename) | |
395 | + strlen (debug_file_directory) + 1); | |
396 | strcpy (debugfile, debug_file_directory); | |
397 | /* FILENAME is absolute, so we don't need a "/" here. */ | |
398 | strcat (debugfile, filename); | |
399 | ||
400 | make_cleanup (xfree, debugfile); | |
401 | input = fopen (debugfile, "r"); | |
402 | } | |
403 | ||
404 | if (!input && gdb_datadir) | |
405 | { | |
406 | /* Also try the same file in a subdirectory of gdb's data | |
407 | directory. */ | |
408 | debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) | |
409 | + strlen ("/auto-load") + 1); | |
410 | strcpy (debugfile, gdb_datadir); | |
411 | strcat (debugfile, "/auto-load"); | |
412 | /* FILENAME is absolute, so we don't need a "/" here. */ | |
413 | strcat (debugfile, filename); | |
414 | ||
415 | make_cleanup (xfree, debugfile); | |
416 | input = fopen (debugfile, "r"); | |
417 | } | |
418 | ||
419 | if (input) | |
420 | { | |
dbaefcf7 DE |
421 | struct auto_load_pspace_info *pspace_info; |
422 | ||
423 | /* Add this script to the hash table too so "info auto-load-scripts" | |
424 | can print it. */ | |
425 | pspace_info = | |
426 | get_auto_load_pspace_data_for_loading (current_program_space); | |
427 | maybe_add_script (pspace_info->loaded_scripts, debugfile, debugfile); | |
428 | ||
429 | /* To preserve existing behaviour we don't check for whether the | |
430 | script was already in the table, and always load it. | |
431 | It's highly unlikely that we'd ever load it twice, | |
432 | and these scripts are required to be idempotent under multiple | |
433 | loads anyway. */ | |
d234ef5c | 434 | source_python_script_for_objfile (objfile, debugfile); |
8a1ea21f DE |
435 | fclose (input); |
436 | } | |
437 | ||
438 | do_cleanups (cleanups); | |
439 | } | |
440 | ||
441 | /* This is a new_objfile observer callback to auto-load scripts. | |
442 | ||
443 | Two flavors of auto-loaded scripts are supported. | |
444 | 1) based on the path to the objfile | |
445 | 2) from .debug_gdb_scripts section */ | |
446 | ||
447 | static void | |
448 | auto_load_new_objfile (struct objfile *objfile) | |
449 | { | |
450 | if (!objfile) | |
451 | { | |
452 | /* OBJFILE is NULL when loading a new "main" symbol-file. */ | |
453 | clear_section_scripts (); | |
454 | return; | |
455 | } | |
8a1ea21f | 456 | |
88a1906b DE |
457 | load_auto_scripts_for_objfile (objfile); |
458 | } | |
459 | ||
460 | /* Load any auto-loaded scripts for OBJFILE. */ | |
461 | ||
462 | void | |
463 | load_auto_scripts_for_objfile (struct objfile *objfile) | |
464 | { | |
a86caf66 | 465 | if (auto_load_scripts && gdbpy_global_auto_load) |
8a1ea21f DE |
466 | { |
467 | auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME); | |
468 | auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME); | |
469 | } | |
470 | } | |
471 | \f | |
dbaefcf7 DE |
472 | /* Collect scripts to be printed in a vec. */ |
473 | ||
474 | typedef struct loaded_script *loaded_script_ptr; | |
475 | DEF_VEC_P (loaded_script_ptr); | |
476 | ||
8a1ea21f | 477 | /* Traversal function for htab_traverse. |
dbaefcf7 | 478 | Collect the entry if it matches the regexp. */ |
8a1ea21f DE |
479 | |
480 | static int | |
dbaefcf7 DE |
481 | collect_matching_scripts (void **slot, void *info) |
482 | { | |
483 | struct loaded_script *script = *slot; | |
87c31f06 | 484 | VEC (loaded_script_ptr) **scripts_ptr = info; |
dbaefcf7 DE |
485 | |
486 | if (re_exec (script->name)) | |
87c31f06 | 487 | VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); |
dbaefcf7 DE |
488 | |
489 | return 1; | |
490 | } | |
491 | ||
492 | /* Print SCRIPT. */ | |
493 | ||
494 | static void | |
495 | print_script (struct loaded_script *script) | |
8a1ea21f | 496 | { |
79a45e25 | 497 | struct ui_out *uiout = current_uiout; |
dbaefcf7 | 498 | struct cleanup *chain; |
8a1ea21f | 499 | |
dbaefcf7 DE |
500 | chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
501 | ||
75fc9810 | 502 | ui_out_field_string (uiout, "loaded", script->full_path ? "Yes" : "Missing"); |
dbaefcf7 DE |
503 | ui_out_field_string (uiout, "script", script->name); |
504 | ui_out_text (uiout, "\n"); | |
505 | ||
506 | /* If the name isn't the full path, print it too. */ | |
507 | if (script->full_path != NULL | |
508 | && strcmp (script->name, script->full_path) != 0) | |
8a1ea21f | 509 | { |
dbaefcf7 DE |
510 | ui_out_text (uiout, "\tfull name: "); |
511 | ui_out_field_string (uiout, "full_path", script->full_path); | |
512 | ui_out_text (uiout, "\n"); | |
8a1ea21f DE |
513 | } |
514 | ||
dbaefcf7 DE |
515 | do_cleanups (chain); |
516 | } | |
517 | ||
518 | /* Helper for info_auto_load_scripts to sort the scripts by name. */ | |
519 | ||
520 | static int | |
521 | sort_scripts_by_name (const void *ap, const void *bp) | |
522 | { | |
523 | const struct loaded_script *a = *(const struct loaded_script **) ap; | |
524 | const struct loaded_script *b = *(const struct loaded_script **) bp; | |
525 | ||
526 | return FILENAME_CMP (a->name, b->name); | |
8a1ea21f DE |
527 | } |
528 | ||
dbaefcf7 | 529 | /* "info auto-load-scripts" command. */ |
8a1ea21f DE |
530 | |
531 | static void | |
dbaefcf7 | 532 | info_auto_load_scripts (char *pattern, int from_tty) |
8a1ea21f | 533 | { |
79a45e25 | 534 | struct ui_out *uiout = current_uiout; |
8a1ea21f | 535 | struct auto_load_pspace_info *pspace_info; |
dbaefcf7 DE |
536 | struct cleanup *script_chain; |
537 | VEC (loaded_script_ptr) *scripts; | |
538 | int nr_scripts; | |
8a1ea21f DE |
539 | |
540 | dont_repeat (); | |
541 | ||
dbaefcf7 DE |
542 | pspace_info = get_auto_load_pspace_data (current_program_space); |
543 | ||
8a1ea21f DE |
544 | if (pattern && *pattern) |
545 | { | |
546 | char *re_err = re_comp (pattern); | |
547 | ||
548 | if (re_err) | |
549 | error (_("Invalid regexp: %s"), re_err); | |
8a1ea21f DE |
550 | } |
551 | else | |
552 | { | |
553 | re_comp (""); | |
8a1ea21f DE |
554 | } |
555 | ||
dbaefcf7 DE |
556 | /* We need to know the number of rows before we build the table. |
557 | Plus we want to sort the scripts by name. | |
558 | So first traverse the hash table collecting the matching scripts. */ | |
559 | ||
560 | scripts = VEC_alloc (loaded_script_ptr, 10); | |
561 | script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &scripts); | |
562 | ||
563 | if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) | |
564 | { | |
565 | immediate_quit++; | |
87c31f06 | 566 | /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ |
dbaefcf7 | 567 | htab_traverse_noresize (pspace_info->loaded_scripts, |
87c31f06 | 568 | collect_matching_scripts, &scripts); |
dbaefcf7 DE |
569 | immediate_quit--; |
570 | } | |
8a1ea21f | 571 | |
dbaefcf7 DE |
572 | nr_scripts = VEC_length (loaded_script_ptr, scripts); |
573 | make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, | |
574 | "AutoLoadedScriptsTable"); | |
575 | ||
75fc9810 | 576 | ui_out_table_header (uiout, 7, ui_left, "loaded", "Loaded"); |
dbaefcf7 DE |
577 | ui_out_table_header (uiout, 70, ui_left, "script", "Script"); |
578 | ui_out_table_body (uiout); | |
579 | ||
580 | if (nr_scripts > 0) | |
581 | { | |
582 | int i; | |
583 | loaded_script_ptr script; | |
584 | ||
585 | qsort (VEC_address (loaded_script_ptr, scripts), | |
586 | VEC_length (loaded_script_ptr, scripts), | |
587 | sizeof (loaded_script_ptr), sort_scripts_by_name); | |
588 | for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i) | |
589 | print_script (script); | |
590 | } | |
591 | ||
592 | do_cleanups (script_chain); | |
593 | ||
594 | if (nr_scripts == 0) | |
595 | { | |
596 | if (pattern && *pattern) | |
597 | ui_out_message (uiout, 0, "No auto-load scripts matching %s.\n", | |
598 | pattern); | |
599 | else | |
600 | ui_out_message (uiout, 0, "No auto-load scripts.\n"); | |
601 | } | |
8a1ea21f DE |
602 | } |
603 | \f | |
604 | void | |
605 | gdbpy_initialize_auto_load (void) | |
606 | { | |
607 | auto_load_pspace_data | |
608 | = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup); | |
609 | ||
610 | observer_attach_new_objfile (auto_load_new_objfile); | |
611 | ||
a86caf66 DE |
612 | add_setshow_boolean_cmd ("auto-load-scripts", class_support, |
613 | &auto_load_scripts, _("\ | |
614 | Set the debugger's behaviour regarding auto-loaded scripts."), _("\ | |
615 | Show the debugger's behaviour regarding auto-loaded scripts."), _("\ | |
616 | If enabled, auto-loaded scripts are loaded when the debugger reads\n\ | |
617 | an executable or shared library."), | |
8a1ea21f | 618 | NULL, NULL, |
a86caf66 DE |
619 | &setlist, |
620 | &showlist); | |
8a1ea21f | 621 | |
dbaefcf7 DE |
622 | add_info ("auto-load-scripts", |
623 | info_auto_load_scripts, | |
624 | _("Print the list of automatically loaded scripts.\n\ | |
625 | Usage: info auto-load-scripts [REGEXP]")); | |
8a1ea21f | 626 | } |
88a1906b DE |
627 | |
628 | #else /* ! HAVE_PYTHON */ | |
629 | ||
630 | void | |
631 | load_auto_scripts_for_objfile (struct objfile *objfile) | |
632 | { | |
633 | } | |
634 | ||
635 | #endif /* ! HAVE_PYTHON */ |