+ global_symbol_searcher spec (FUNCTIONS_DOMAIN, regex);
+ SCOPE_EXIT {
+ for (const char *elem : spec.filenames)
+ xfree ((void *) elem);
+ };
+
+ /* The "symtabs" keyword is any Python iterable object that returns
+ a gdb.Symtab on each iteration. If specified, iterate through
+ the provided gdb.Symtabs and extract their full path. As
+ python_string_to_target_string returns a
+ gdb::unique_xmalloc_ptr<char> and a vector containing these types
+ cannot be coerced to a const char **p[] via the vector.data call,
+ release the value from the unique_xmalloc_ptr and place it in a
+ simple type symtab_list_type (which holds the vector and a
+ destructor that frees the contents of the allocated strings. */
+ if (symtab_list != NULL)
+ {
+ gdbpy_ref<> iter (PyObject_GetIter (symtab_list));
+
+ if (iter == NULL)
+ return NULL;
+
+ while (true)
+ {
+ gdbpy_ref<> next (PyIter_Next (iter.get ()));
+
+ if (next == NULL)
+ {
+ if (PyErr_Occurred ())
+ return NULL;
+ break;
+ }
+
+ gdbpy_ref<> obj_name (PyObject_GetAttrString (next.get (),
+ "filename"));
+
+ if (obj_name == NULL)
+ return NULL;
+
+ /* Is the object file still valid? */
+ if (obj_name == Py_None)
+ continue;
+
+ gdb::unique_xmalloc_ptr<char> filename =
+ python_string_to_target_string (obj_name.get ());
+
+ if (filename == NULL)
+ return NULL;
+
+ /* Make sure there is a definite place to store the value of
+ filename before it is released. */
+ spec.filenames.push_back (nullptr);
+ spec.filenames.back () = filename.release ();
+ }
+ }
+
+ /* The search spec. */
+ symbols = spec.search ();
+
+ /* Count the number of symbols (both symbols and optionally minimal
+ symbols) so we can correctly check the throttle limit. */
+ for (const symbol_search &p : symbols)
+ {
+ /* Minimal symbols included? */
+ if (minsyms_p)
+ {
+ if (p.msymbol.minsym != NULL)
+ count++;
+ }
+
+ if (p.symbol != NULL)
+ count++;
+ }
+
+ /* Check throttle bounds and exit if in excess. */
+ if (throttle != 0 && count > throttle)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Number of breakpoints exceeds throttled maximum."));
+ return NULL;
+ }
+
+ gdbpy_ref<> return_list (PyList_New (0));
+
+ if (return_list == NULL)
+ return NULL;
+
+ /* Construct full path names for symbols and call the Python
+ breakpoint constructor on the resulting names. Be tolerant of
+ individual breakpoint failures. */
+ for (const symbol_search &p : symbols)
+ {
+ std::string symbol_name;
+
+ /* Skipping minimal symbols? */
+ if (minsyms_p == 0)
+ if (p.msymbol.minsym != NULL)
+ continue;
+
+ if (p.msymbol.minsym == NULL)
+ {
+ struct symtab *symtab = symbol_symtab (p.symbol);
+ const char *fullname = symtab_to_fullname (symtab);
+
+ symbol_name = fullname;
+ symbol_name += ":";
+ symbol_name += p.symbol->linkage_name ();
+ }
+ else
+ symbol_name = p.msymbol.minsym->linkage_name ();
+
+ gdbpy_ref<> argList (Py_BuildValue("(s)", symbol_name.c_str ()));
+ gdbpy_ref<> obj (PyObject_CallObject ((PyObject *)
+ &breakpoint_object_type,
+ argList.get ()));
+
+ /* Tolerate individual breakpoint failures. */
+ if (obj == NULL)
+ gdbpy_print_stack ();
+ else
+ {
+ if (PyList_Append (return_list.get (), obj.get ()) == -1)
+ return NULL;
+ }
+ }
+ return return_list.release ();