Commit | Line | Data |
---|---|---|
8a1ea21f DE |
1 | /* GDB routines for supporting auto-loaded scripts. |
2 | ||
0b302171 | 3 | Copyright (C) 2010-2012 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; | |
e97a38f7 | 257 | struct cleanup *back_to; |
8a1ea21f DE |
258 | |
259 | if (*p != 1) | |
260 | { | |
261 | warning (_("Invalid entry in %s section"), GDBPY_AUTO_SECTION_NAME); | |
262 | /* We could try various heuristics to find the next valid entry, | |
263 | but it's safer to just punt. */ | |
264 | break; | |
265 | } | |
266 | file = ++p; | |
267 | ||
268 | while (p < end && *p != '\0') | |
269 | ++p; | |
270 | if (p == end) | |
271 | { | |
272 | char *buf = alloca (p - file + 1); | |
d59b6f6c | 273 | |
8a1ea21f DE |
274 | memcpy (buf, file, p - file); |
275 | buf[p - file] = '\0'; | |
276 | warning (_("Non-null-terminated path in %s: %s"), | |
277 | source_name, buf); | |
278 | /* Don't load it. */ | |
279 | break; | |
280 | } | |
281 | if (p == file) | |
282 | { | |
283 | warning (_("Empty path in %s"), source_name); | |
284 | continue; | |
285 | } | |
286 | ||
287 | opened = find_and_open_script (file, 1 /*search_path*/, | |
288 | &stream, &full_path); | |
289 | ||
e97a38f7 JK |
290 | back_to = make_cleanup (null_cleanup, NULL); |
291 | if (opened) | |
292 | { | |
293 | make_cleanup_fclose (stream); | |
294 | make_cleanup (xfree, full_path); | |
295 | } | |
296 | ||
dbaefcf7 DE |
297 | /* If one script isn't found it's not uncommon for more to not be |
298 | found either. We don't want to print an error message for each | |
299 | script, too much noise. Instead, we print the warning once and tell | |
300 | the user how to find the list of scripts that weren't loaded. | |
8a1ea21f | 301 | |
dbaefcf7 | 302 | IWBN if complaints.c were more general-purpose. */ |
8a1ea21f | 303 | |
dbaefcf7 DE |
304 | in_hash_table = maybe_add_script (pspace_info->loaded_scripts, file, |
305 | opened ? full_path : NULL); | |
8a1ea21f | 306 | |
8a1ea21f DE |
307 | if (! opened) |
308 | { | |
dbaefcf7 DE |
309 | /* We don't throw an error, the program is still debuggable. */ |
310 | if (! pspace_info->script_not_found_warning_printed) | |
311 | { | |
fd20d931 DE |
312 | warning (_("Missing auto-load scripts referenced in section %s\n\ |
313 | of file %s\n\ | |
dbaefcf7 | 314 | Use `info auto-load-scripts [REGEXP]' to list them."), |
fd20d931 | 315 | GDBPY_AUTO_SECTION_NAME, objfile->name); |
dbaefcf7 DE |
316 | pspace_info->script_not_found_warning_printed = TRUE; |
317 | } | |
8a1ea21f | 318 | } |
562f943b DE |
319 | else |
320 | { | |
321 | /* If this file is not currently loaded, load it. */ | |
322 | if (! in_hash_table) | |
4c63965b | 323 | source_python_script_for_objfile (objfile, stream, full_path); |
562f943b | 324 | } |
e97a38f7 JK |
325 | |
326 | do_cleanups (back_to); | |
8a1ea21f DE |
327 | } |
328 | } | |
329 | ||
330 | /* Load scripts specified in section SECTION_NAME of OBJFILE. */ | |
331 | ||
332 | static void | |
333 | auto_load_section_scripts (struct objfile *objfile, const char *section_name) | |
334 | { | |
335 | bfd *abfd = objfile->obfd; | |
336 | asection *scripts_sect; | |
337 | bfd_size_type size; | |
338 | char *p; | |
339 | struct cleanup *cleanups; | |
340 | ||
341 | scripts_sect = bfd_get_section_by_name (abfd, section_name); | |
342 | if (scripts_sect == NULL) | |
343 | return; | |
344 | ||
345 | size = bfd_get_section_size (scripts_sect); | |
346 | p = xmalloc (size); | |
347 | ||
348 | cleanups = make_cleanup (xfree, p); | |
349 | ||
350 | if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size)) | |
351 | source_section_scripts (objfile, section_name, p, p + size); | |
352 | else | |
353 | warning (_("Couldn't read %s section of %s"), | |
354 | section_name, bfd_get_filename (abfd)); | |
355 | ||
356 | do_cleanups (cleanups); | |
357 | } | |
358 | ||
359 | /* Clear the table of loaded section scripts. */ | |
360 | ||
361 | static void | |
362 | clear_section_scripts (void) | |
363 | { | |
364 | struct program_space *pspace = current_program_space; | |
365 | struct auto_load_pspace_info *info; | |
366 | ||
367 | info = program_space_data (pspace, auto_load_pspace_data); | |
368 | if (info != NULL && info->loaded_scripts != NULL) | |
369 | { | |
370 | htab_delete (info->loaded_scripts); | |
371 | info->loaded_scripts = NULL; | |
dbaefcf7 | 372 | info->script_not_found_warning_printed = FALSE; |
8a1ea21f DE |
373 | } |
374 | } | |
375 | ||
376 | /* Look for the auto-load script associated with OBJFILE and load it. */ | |
377 | ||
378 | static void | |
379 | auto_load_objfile_script (struct objfile *objfile, const char *suffix) | |
380 | { | |
381 | char *realname; | |
382 | char *filename, *debugfile; | |
383 | int len; | |
384 | FILE *input; | |
385 | struct cleanup *cleanups; | |
386 | ||
387 | realname = gdb_realpath (objfile->name); | |
388 | len = strlen (realname); | |
389 | filename = xmalloc (len + strlen (suffix) + 1); | |
390 | memcpy (filename, realname, len); | |
391 | strcpy (filename + len, suffix); | |
392 | ||
393 | cleanups = make_cleanup (xfree, filename); | |
394 | make_cleanup (xfree, realname); | |
395 | ||
396 | input = fopen (filename, "r"); | |
397 | debugfile = filename; | |
398 | ||
399 | if (!input && debug_file_directory) | |
400 | { | |
401 | /* Also try the same file in the separate debug info directory. */ | |
402 | debugfile = xmalloc (strlen (filename) | |
403 | + strlen (debug_file_directory) + 1); | |
404 | strcpy (debugfile, debug_file_directory); | |
405 | /* FILENAME is absolute, so we don't need a "/" here. */ | |
406 | strcat (debugfile, filename); | |
407 | ||
408 | make_cleanup (xfree, debugfile); | |
409 | input = fopen (debugfile, "r"); | |
410 | } | |
411 | ||
412 | if (!input && gdb_datadir) | |
413 | { | |
414 | /* Also try the same file in a subdirectory of gdb's data | |
415 | directory. */ | |
416 | debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) | |
417 | + strlen ("/auto-load") + 1); | |
418 | strcpy (debugfile, gdb_datadir); | |
419 | strcat (debugfile, "/auto-load"); | |
420 | /* FILENAME is absolute, so we don't need a "/" here. */ | |
421 | strcat (debugfile, filename); | |
422 | ||
423 | make_cleanup (xfree, debugfile); | |
424 | input = fopen (debugfile, "r"); | |
425 | } | |
426 | ||
427 | if (input) | |
428 | { | |
dbaefcf7 DE |
429 | struct auto_load_pspace_info *pspace_info; |
430 | ||
e97a38f7 JK |
431 | make_cleanup_fclose (input); |
432 | ||
dbaefcf7 DE |
433 | /* Add this script to the hash table too so "info auto-load-scripts" |
434 | can print it. */ | |
435 | pspace_info = | |
436 | get_auto_load_pspace_data_for_loading (current_program_space); | |
437 | maybe_add_script (pspace_info->loaded_scripts, debugfile, debugfile); | |
438 | ||
439 | /* To preserve existing behaviour we don't check for whether the | |
440 | script was already in the table, and always load it. | |
441 | It's highly unlikely that we'd ever load it twice, | |
442 | and these scripts are required to be idempotent under multiple | |
443 | loads anyway. */ | |
4c63965b | 444 | source_python_script_for_objfile (objfile, input, debugfile); |
8a1ea21f DE |
445 | } |
446 | ||
447 | do_cleanups (cleanups); | |
448 | } | |
449 | ||
450 | /* This is a new_objfile observer callback to auto-load scripts. | |
451 | ||
452 | Two flavors of auto-loaded scripts are supported. | |
453 | 1) based on the path to the objfile | |
454 | 2) from .debug_gdb_scripts section */ | |
455 | ||
456 | static void | |
457 | auto_load_new_objfile (struct objfile *objfile) | |
458 | { | |
459 | if (!objfile) | |
460 | { | |
461 | /* OBJFILE is NULL when loading a new "main" symbol-file. */ | |
462 | clear_section_scripts (); | |
463 | return; | |
464 | } | |
8a1ea21f | 465 | |
88a1906b DE |
466 | load_auto_scripts_for_objfile (objfile); |
467 | } | |
468 | ||
469 | /* Load any auto-loaded scripts for OBJFILE. */ | |
470 | ||
471 | void | |
472 | load_auto_scripts_for_objfile (struct objfile *objfile) | |
473 | { | |
a86caf66 | 474 | if (auto_load_scripts && gdbpy_global_auto_load) |
8a1ea21f DE |
475 | { |
476 | auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME); | |
477 | auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME); | |
478 | } | |
479 | } | |
480 | \f | |
dbaefcf7 DE |
481 | /* Collect scripts to be printed in a vec. */ |
482 | ||
483 | typedef struct loaded_script *loaded_script_ptr; | |
484 | DEF_VEC_P (loaded_script_ptr); | |
485 | ||
8a1ea21f | 486 | /* Traversal function for htab_traverse. |
dbaefcf7 | 487 | Collect the entry if it matches the regexp. */ |
8a1ea21f DE |
488 | |
489 | static int | |
dbaefcf7 DE |
490 | collect_matching_scripts (void **slot, void *info) |
491 | { | |
492 | struct loaded_script *script = *slot; | |
87c31f06 | 493 | VEC (loaded_script_ptr) **scripts_ptr = info; |
dbaefcf7 DE |
494 | |
495 | if (re_exec (script->name)) | |
87c31f06 | 496 | VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); |
dbaefcf7 DE |
497 | |
498 | return 1; | |
499 | } | |
500 | ||
501 | /* Print SCRIPT. */ | |
502 | ||
503 | static void | |
504 | print_script (struct loaded_script *script) | |
8a1ea21f | 505 | { |
79a45e25 | 506 | struct ui_out *uiout = current_uiout; |
dbaefcf7 | 507 | struct cleanup *chain; |
8a1ea21f | 508 | |
dbaefcf7 DE |
509 | chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
510 | ||
75fc9810 | 511 | ui_out_field_string (uiout, "loaded", script->full_path ? "Yes" : "Missing"); |
dbaefcf7 DE |
512 | ui_out_field_string (uiout, "script", script->name); |
513 | ui_out_text (uiout, "\n"); | |
514 | ||
515 | /* If the name isn't the full path, print it too. */ | |
516 | if (script->full_path != NULL | |
517 | && strcmp (script->name, script->full_path) != 0) | |
8a1ea21f | 518 | { |
dbaefcf7 DE |
519 | ui_out_text (uiout, "\tfull name: "); |
520 | ui_out_field_string (uiout, "full_path", script->full_path); | |
521 | ui_out_text (uiout, "\n"); | |
8a1ea21f DE |
522 | } |
523 | ||
dbaefcf7 DE |
524 | do_cleanups (chain); |
525 | } | |
526 | ||
527 | /* Helper for info_auto_load_scripts to sort the scripts by name. */ | |
528 | ||
529 | static int | |
530 | sort_scripts_by_name (const void *ap, const void *bp) | |
531 | { | |
532 | const struct loaded_script *a = *(const struct loaded_script **) ap; | |
533 | const struct loaded_script *b = *(const struct loaded_script **) bp; | |
534 | ||
535 | return FILENAME_CMP (a->name, b->name); | |
8a1ea21f DE |
536 | } |
537 | ||
dbaefcf7 | 538 | /* "info auto-load-scripts" command. */ |
8a1ea21f DE |
539 | |
540 | static void | |
dbaefcf7 | 541 | info_auto_load_scripts (char *pattern, int from_tty) |
8a1ea21f | 542 | { |
79a45e25 | 543 | struct ui_out *uiout = current_uiout; |
8a1ea21f | 544 | struct auto_load_pspace_info *pspace_info; |
dbaefcf7 DE |
545 | struct cleanup *script_chain; |
546 | VEC (loaded_script_ptr) *scripts; | |
547 | int nr_scripts; | |
8a1ea21f DE |
548 | |
549 | dont_repeat (); | |
550 | ||
dbaefcf7 DE |
551 | pspace_info = get_auto_load_pspace_data (current_program_space); |
552 | ||
8a1ea21f DE |
553 | if (pattern && *pattern) |
554 | { | |
555 | char *re_err = re_comp (pattern); | |
556 | ||
557 | if (re_err) | |
558 | error (_("Invalid regexp: %s"), re_err); | |
8a1ea21f DE |
559 | } |
560 | else | |
561 | { | |
562 | re_comp (""); | |
8a1ea21f DE |
563 | } |
564 | ||
dbaefcf7 DE |
565 | /* We need to know the number of rows before we build the table. |
566 | Plus we want to sort the scripts by name. | |
567 | So first traverse the hash table collecting the matching scripts. */ | |
568 | ||
569 | scripts = VEC_alloc (loaded_script_ptr, 10); | |
570 | script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &scripts); | |
571 | ||
572 | if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) | |
573 | { | |
574 | immediate_quit++; | |
87c31f06 | 575 | /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ |
dbaefcf7 | 576 | htab_traverse_noresize (pspace_info->loaded_scripts, |
87c31f06 | 577 | collect_matching_scripts, &scripts); |
dbaefcf7 DE |
578 | immediate_quit--; |
579 | } | |
8a1ea21f | 580 | |
dbaefcf7 DE |
581 | nr_scripts = VEC_length (loaded_script_ptr, scripts); |
582 | make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, | |
583 | "AutoLoadedScriptsTable"); | |
584 | ||
75fc9810 | 585 | ui_out_table_header (uiout, 7, ui_left, "loaded", "Loaded"); |
dbaefcf7 DE |
586 | ui_out_table_header (uiout, 70, ui_left, "script", "Script"); |
587 | ui_out_table_body (uiout); | |
588 | ||
589 | if (nr_scripts > 0) | |
590 | { | |
591 | int i; | |
592 | loaded_script_ptr script; | |
593 | ||
594 | qsort (VEC_address (loaded_script_ptr, scripts), | |
595 | VEC_length (loaded_script_ptr, scripts), | |
596 | sizeof (loaded_script_ptr), sort_scripts_by_name); | |
597 | for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i) | |
598 | print_script (script); | |
599 | } | |
600 | ||
601 | do_cleanups (script_chain); | |
602 | ||
603 | if (nr_scripts == 0) | |
604 | { | |
605 | if (pattern && *pattern) | |
606 | ui_out_message (uiout, 0, "No auto-load scripts matching %s.\n", | |
607 | pattern); | |
608 | else | |
609 | ui_out_message (uiout, 0, "No auto-load scripts.\n"); | |
610 | } | |
8a1ea21f DE |
611 | } |
612 | \f | |
613 | void | |
614 | gdbpy_initialize_auto_load (void) | |
615 | { | |
616 | auto_load_pspace_data | |
617 | = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup); | |
618 | ||
619 | observer_attach_new_objfile (auto_load_new_objfile); | |
620 | ||
a86caf66 DE |
621 | add_setshow_boolean_cmd ("auto-load-scripts", class_support, |
622 | &auto_load_scripts, _("\ | |
623 | Set the debugger's behaviour regarding auto-loaded scripts."), _("\ | |
624 | Show the debugger's behaviour regarding auto-loaded scripts."), _("\ | |
625 | If enabled, auto-loaded scripts are loaded when the debugger reads\n\ | |
626 | an executable or shared library."), | |
8a1ea21f | 627 | NULL, NULL, |
a86caf66 DE |
628 | &setlist, |
629 | &showlist); | |
8a1ea21f | 630 | |
dbaefcf7 DE |
631 | add_info ("auto-load-scripts", |
632 | info_auto_load_scripts, | |
633 | _("Print the list of automatically loaded scripts.\n\ | |
634 | Usage: info auto-load-scripts [REGEXP]")); | |
8a1ea21f | 635 | } |
88a1906b DE |
636 | |
637 | #else /* ! HAVE_PYTHON */ | |
638 | ||
639 | void | |
640 | load_auto_scripts_for_objfile (struct objfile *objfile) | |
641 | { | |
642 | } | |
643 | ||
644 | #endif /* ! HAVE_PYTHON */ |