GNU Binutils with patches for OS216
修订版 | 1eac6bea98f41ee12ba9e750a9578bd8585011c9 (tree) |
---|---|
时间 | 2017-09-12 20:55:32 |
作者 | Simon Marchi <simon.marchi@eric...> |
Commiter | Simon Marchi |
Make collect_probes return an std::vector
Change collect_probes so it returns an std::vector<bound_probe> instead
of a VEC(bound_probe_s). This allows removing some cleanups. It also
seems like enable_probes_command and disable_probes_command were not
freeing that vector.
The comparison function compare_probes needs to be updated to return a
bool indicating whether the first parameter is "less than" the second
parameter.
I defined two constructors to bound_probe. The default constructor is
needed, for example, so the instance in struct bp_location can be
constructed without parameters. The constructor with parameters is
useful so we can use emplace_back and pass the values directly.
The s390 builder on the buildbot shows a weird failure that I can't
explain:
../../binutils-gdb/gdb/elfread.c: In function void probe_key_free(bfd*, void*):
../../binutils-gdb/gdb/elfread.c:1346:8: error: types may not be defined in a for-range-declaration [-Werror]
I guess it's a bug with that specific version< of the compiler, since no
other gcc gives me that error. It is using:
Any idea about this problem?
gdb/ChangeLog:
* probe.h (struct bound_probe): Define constructors.
* probe.c (bound_probe_s): Remove typedef.
(DEF_VEC_O (bound_probe_s)): Remove VEC.
(collect_probes): Change return type to std::vector, remove
cleanup.
(compare_probes): Return bool, change parameter type. Change
semantic to "less than".
(gen_ui_out_table_header_info): Change parameter to std::vector
and update.
(exists_probe_with_pops): Likewise.
(info_probes_for_ops): Update to std::vector change.
(enable_probes_command): Likewise.
(disable_probes_command): Likewise.
@@ -1,5 +1,21 @@ | ||
1 | 1 | 2017-09-12 Simon Marchi <simon.marchi@ericsson.com> |
2 | 2 | |
3 | + * probe.h (struct bound_probe): Define constructors. | |
4 | + * probe.c (bound_probe_s): Remove typedef. | |
5 | + (DEF_VEC_O (bound_probe_s)): Remove VEC. | |
6 | + (collect_probes): Change return type to std::vector, remove | |
7 | + cleanup. | |
8 | + (compare_probes): Return bool, change parameter type. Change | |
9 | + semantic to "less than". | |
10 | + (gen_ui_out_table_header_info): Change parameter to std::vector | |
11 | + and update. | |
12 | + (exists_probe_with_pops): Likewise. | |
13 | + (info_probes_for_ops): Update to std::vector change. | |
14 | + (enable_probes_command): Likewise. | |
15 | + (disable_probes_command): Likewise. | |
16 | + | |
17 | +2017-09-12 Simon Marchi <simon.marchi@ericsson.com> | |
18 | + | |
3 | 19 | * probe.h (struct probe_ops) <get_probes>: Change parameter from |
4 | 20 | vec to std::vector. |
5 | 21 | * probe.c (parse_probes_in_pspace): Update. |
@@ -38,11 +38,6 @@ | ||
38 | 38 | #include <algorithm> |
39 | 39 | #include "common/gdb_optional.h" |
40 | 40 | |
41 | -typedef struct bound_probe bound_probe_s; | |
42 | -DEF_VEC_O (bound_probe_s); | |
43 | - | |
44 | - | |
45 | - | |
46 | 41 | /* A helper for parse_probes that decodes a probe specification in |
47 | 42 | SEARCH_PSPACE. It appends matching SALs to RESULT. */ |
48 | 43 |
@@ -267,17 +262,14 @@ find_probe_by_pc (CORE_ADDR pc) | ||
267 | 262 | If POPS is not NULL, only probes of this certain probe_ops will match. |
268 | 263 | Each argument is a regexp, or NULL, which matches anything. */ |
269 | 264 | |
270 | -static VEC (bound_probe_s) * | |
265 | +static std::vector<bound_probe> | |
271 | 266 | collect_probes (const std::string &objname, const std::string &provider, |
272 | 267 | const std::string &probe_name, const struct probe_ops *pops) |
273 | 268 | { |
274 | 269 | struct objfile *objfile; |
275 | - VEC (bound_probe_s) *result = NULL; | |
276 | - struct cleanup *cleanup; | |
270 | + std::vector<bound_probe> result; | |
277 | 271 | gdb::optional<compiled_regex> obj_pat, prov_pat, probe_pat; |
278 | 272 | |
279 | - cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result); | |
280 | - | |
281 | 273 | if (!provider.empty ()) |
282 | 274 | prov_pat.emplace (provider.c_str (), REG_NOSUB, |
283 | 275 | _("Invalid provider regexp")); |
@@ -304,8 +296,6 @@ collect_probes (const std::string &objname, const std::string &provider, | ||
304 | 296 | |
305 | 297 | for (struct probe *probe : probes) |
306 | 298 | { |
307 | - struct bound_probe bound; | |
308 | - | |
309 | 299 | if (pops != NULL && probe->pops != pops) |
310 | 300 | continue; |
311 | 301 |
@@ -317,46 +307,39 @@ collect_probes (const std::string &objname, const std::string &provider, | ||
317 | 307 | && probe_pat->exec (probe->name, 0, NULL, 0) != 0) |
318 | 308 | continue; |
319 | 309 | |
320 | - bound.objfile = objfile; | |
321 | - bound.probe = probe; | |
322 | - VEC_safe_push (bound_probe_s, result, &bound); | |
310 | + result.emplace_back (probe, objfile); | |
323 | 311 | } |
324 | 312 | } |
325 | 313 | |
326 | - discard_cleanups (cleanup); | |
327 | 314 | return result; |
328 | 315 | } |
329 | 316 | |
330 | 317 | /* A qsort comparison function for bound_probe_s objects. */ |
331 | 318 | |
332 | -static int | |
333 | -compare_probes (const void *a, const void *b) | |
319 | +static bool | |
320 | +compare_probes (const bound_probe &a, const bound_probe &b) | |
334 | 321 | { |
335 | - const struct bound_probe *pa = (const struct bound_probe *) a; | |
336 | - const struct bound_probe *pb = (const struct bound_probe *) b; | |
337 | 322 | int v; |
338 | 323 | |
339 | - v = strcmp (pa->probe->provider, pb->probe->provider); | |
340 | - if (v) | |
341 | - return v; | |
324 | + v = strcmp (a.probe->provider, b.probe->provider); | |
325 | + if (v != 0) | |
326 | + return v < 0; | |
342 | 327 | |
343 | - v = strcmp (pa->probe->name, pb->probe->name); | |
344 | - if (v) | |
345 | - return v; | |
328 | + v = strcmp (a.probe->name, b.probe->name); | |
329 | + if (v != 0) | |
330 | + return v < 0; | |
346 | 331 | |
347 | - if (pa->probe->address < pb->probe->address) | |
348 | - return -1; | |
349 | - if (pa->probe->address > pb->probe->address) | |
350 | - return 1; | |
332 | + if (a.probe->address != b.probe->address) | |
333 | + return a.probe->address < b.probe->address; | |
351 | 334 | |
352 | - return strcmp (objfile_name (pa->objfile), objfile_name (pb->objfile)); | |
335 | + return strcmp (objfile_name (a.objfile), objfile_name (b.objfile)) < 0; | |
353 | 336 | } |
354 | 337 | |
355 | 338 | /* Helper function that generate entries in the ui_out table being |
356 | 339 | crafted by `info_probes_for_ops'. */ |
357 | 340 | |
358 | 341 | static void |
359 | -gen_ui_out_table_header_info (VEC (bound_probe_s) *probes, | |
342 | +gen_ui_out_table_header_info (const std::vector<bound_probe> &probes, | |
360 | 343 | const struct probe_ops *p) |
361 | 344 | { |
362 | 345 | /* `headings' refers to the names of the columns when printing `info |
@@ -385,11 +368,9 @@ gen_ui_out_table_header_info (VEC (bound_probe_s) *probes, | ||
385 | 368 | VEC_iterate (info_probe_column_s, headings, ix, column); |
386 | 369 | ++ix) |
387 | 370 | { |
388 | - struct bound_probe *probe; | |
389 | - int jx; | |
390 | 371 | size_t size_max = strlen (column->print_name); |
391 | 372 | |
392 | - for (jx = 0; VEC_iterate (bound_probe_s, probes, jx, probe); ++jx) | |
373 | + for (const bound_probe &probe : probes) | |
393 | 374 | { |
394 | 375 | /* `probe_fields' refers to the values of each new field that this |
395 | 376 | probe will display. */ |
@@ -398,11 +379,11 @@ gen_ui_out_table_header_info (VEC (bound_probe_s) *probes, | ||
398 | 379 | const char *val; |
399 | 380 | int kx; |
400 | 381 | |
401 | - if (probe->probe->pops != p) | |
382 | + if (probe.probe->pops != p) | |
402 | 383 | continue; |
403 | 384 | |
404 | 385 | c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields); |
405 | - p->gen_info_probes_table_values (probe->probe, &probe_fields); | |
386 | + p->gen_info_probes_table_values (probe.probe, &probe_fields); | |
406 | 387 | |
407 | 388 | gdb_assert (VEC_length (const_char_ptr, probe_fields) |
408 | 389 | == headings_size); |
@@ -529,14 +510,14 @@ get_number_extra_fields (const struct probe_ops *pops) | ||
529 | 510 | featuring the given POPS. It returns 0 otherwise. */ |
530 | 511 | |
531 | 512 | static int |
532 | -exists_probe_with_pops (VEC (bound_probe_s) *probes, | |
513 | +exists_probe_with_pops (const std::vector<bound_probe> &probes, | |
533 | 514 | const struct probe_ops *pops) |
534 | 515 | { |
535 | 516 | struct bound_probe *probe; |
536 | 517 | int ix; |
537 | 518 | |
538 | - for (ix = 0; VEC_iterate (bound_probe_s, probes, ix, probe); ++ix) | |
539 | - if (probe->probe->pops == pops) | |
519 | + for (const bound_probe &probe : probes) | |
520 | + if (probe.probe->pops == pops) | |
540 | 521 | return 1; |
541 | 522 | |
542 | 523 | return 0; |
@@ -568,21 +549,19 @@ info_probes_for_ops (const char *arg, int from_tty, | ||
568 | 549 | { |
569 | 550 | std::string provider, probe_name, objname; |
570 | 551 | struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); |
571 | - VEC (bound_probe_s) *probes; | |
572 | - int i, any_found; | |
552 | + int any_found; | |
573 | 553 | int ui_out_extra_fields = 0; |
574 | 554 | size_t size_addr; |
575 | 555 | size_t size_name = strlen ("Name"); |
576 | 556 | size_t size_objname = strlen ("Object"); |
577 | 557 | size_t size_provider = strlen ("Provider"); |
578 | 558 | size_t size_type = strlen ("Type"); |
579 | - struct bound_probe *probe; | |
580 | 559 | struct gdbarch *gdbarch = get_current_arch (); |
581 | 560 | |
582 | 561 | parse_probe_linespec (arg, &provider, &probe_name, &objname); |
583 | 562 | |
584 | - probes = collect_probes (objname, provider, probe_name, pops); | |
585 | - make_cleanup (VEC_cleanup (probe_p), &probes); | |
563 | + std::vector<bound_probe> probes | |
564 | + = collect_probes (objname, provider, probe_name, pops); | |
586 | 565 | |
587 | 566 | if (pops == NULL) |
588 | 567 | { |
@@ -609,27 +588,23 @@ info_probes_for_ops (const char *arg, int from_tty, | ||
609 | 588 | { |
610 | 589 | ui_out_emit_table table_emitter (current_uiout, |
611 | 590 | 5 + ui_out_extra_fields, |
612 | - VEC_length (bound_probe_s, probes), | |
613 | - "StaticProbes"); | |
591 | + probes.size (), "StaticProbes"); | |
614 | 592 | |
615 | - if (!VEC_empty (bound_probe_s, probes)) | |
616 | - qsort (VEC_address (bound_probe_s, probes), | |
617 | - VEC_length (bound_probe_s, probes), | |
618 | - sizeof (bound_probe_s), compare_probes); | |
593 | + std::sort (probes.begin (), probes.end (), compare_probes); | |
619 | 594 | |
620 | 595 | /* What's the size of an address in our architecture? */ |
621 | 596 | size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10; |
622 | 597 | |
623 | 598 | /* Determining the maximum size of each field (`type', `provider', |
624 | 599 | `name' and `objname'). */ |
625 | - for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i) | |
600 | + for (const bound_probe &probe : probes) | |
626 | 601 | { |
627 | - const char *probe_type = probe->probe->pops->type_name (probe->probe); | |
602 | + const char *probe_type = probe.probe->pops->type_name (probe.probe); | |
628 | 603 | |
629 | 604 | size_type = std::max (strlen (probe_type), size_type); |
630 | - size_name = std::max (strlen (probe->probe->name), size_name); | |
631 | - size_provider = std::max (strlen (probe->probe->provider), size_provider); | |
632 | - size_objname = std::max (strlen (objfile_name (probe->objfile)), | |
605 | + size_name = std::max (strlen (probe.probe->name), size_name); | |
606 | + size_provider = std::max (strlen (probe.probe->provider), size_provider); | |
607 | + size_objname = std::max (strlen (objfile_name (probe.objfile)), | |
633 | 608 | size_objname); |
634 | 609 | } |
635 | 610 |
@@ -657,18 +632,18 @@ info_probes_for_ops (const char *arg, int from_tty, | ||
657 | 632 | current_uiout->table_header (size_objname, ui_left, "object", _("Object")); |
658 | 633 | current_uiout->table_body (); |
659 | 634 | |
660 | - for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i) | |
635 | + for (const bound_probe &probe : probes) | |
661 | 636 | { |
662 | - const char *probe_type = probe->probe->pops->type_name (probe->probe); | |
637 | + const char *probe_type = probe.probe->pops->type_name (probe.probe); | |
663 | 638 | |
664 | 639 | ui_out_emit_tuple tuple_emitter (current_uiout, "probe"); |
665 | 640 | |
666 | 641 | current_uiout->field_string ("type",probe_type); |
667 | - current_uiout->field_string ("provider", probe->probe->provider); | |
668 | - current_uiout->field_string ("name", probe->probe->name); | |
669 | - current_uiout->field_core_addr ( | |
670 | - "addr", probe->probe->arch, | |
671 | - get_probe_address (probe->probe, probe->objfile)); | |
642 | + current_uiout->field_string ("provider", probe.probe->provider); | |
643 | + current_uiout->field_string ("name", probe.probe->name); | |
644 | + current_uiout->field_core_addr ("addr", probe.probe->arch, | |
645 | + get_probe_address (probe.probe, | |
646 | + probe.objfile)); | |
672 | 647 | |
673 | 648 | if (pops == NULL) |
674 | 649 | { |
@@ -677,20 +652,20 @@ info_probes_for_ops (const char *arg, int from_tty, | ||
677 | 652 | |
678 | 653 | for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); |
679 | 654 | ++ix) |
680 | - if (probe->probe->pops == po) | |
681 | - print_ui_out_info (probe->probe); | |
655 | + if (probe.probe->pops == po) | |
656 | + print_ui_out_info (probe.probe); | |
682 | 657 | else if (exists_probe_with_pops (probes, po)) |
683 | 658 | print_ui_out_not_applicables (po); |
684 | 659 | } |
685 | 660 | else |
686 | - print_ui_out_info (probe->probe); | |
661 | + print_ui_out_info (probe.probe); | |
687 | 662 | |
688 | 663 | current_uiout->field_string ("object", |
689 | - objfile_name (probe->objfile)); | |
664 | + objfile_name (probe.objfile)); | |
690 | 665 | current_uiout->text ("\n"); |
691 | 666 | } |
692 | 667 | |
693 | - any_found = !VEC_empty (bound_probe_s, probes); | |
668 | + any_found = !probes.empty (); | |
694 | 669 | } |
695 | 670 | do_cleanups (cleanup); |
696 | 671 |
@@ -713,14 +688,12 @@ enable_probes_command (char *arg, int from_tty) | ||
713 | 688 | { |
714 | 689 | std::string provider, probe_name, objname; |
715 | 690 | struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); |
716 | - VEC (bound_probe_s) *probes; | |
717 | - struct bound_probe *probe; | |
718 | - int i; | |
719 | 691 | |
720 | 692 | parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname); |
721 | 693 | |
722 | - probes = collect_probes (objname, provider, probe_name, NULL); | |
723 | - if (VEC_empty (bound_probe_s, probes)) | |
694 | + std::vector<bound_probe> probes | |
695 | + = collect_probes (objname, provider, probe_name, NULL); | |
696 | + if (probes.empty ()) | |
724 | 697 | { |
725 | 698 | current_uiout->message (_("No probes matched.\n")); |
726 | 699 | do_cleanups (cleanup); |
@@ -729,19 +702,19 @@ enable_probes_command (char *arg, int from_tty) | ||
729 | 702 | |
730 | 703 | /* Enable the selected probes, provided their backends support the |
731 | 704 | notion of enabling a probe. */ |
732 | - for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i) | |
705 | + for (const bound_probe &probe: probes) | |
733 | 706 | { |
734 | - const struct probe_ops *pops = probe->probe->pops; | |
707 | + const struct probe_ops *pops = probe.probe->pops; | |
735 | 708 | |
736 | 709 | if (pops->enable_probe != NULL) |
737 | 710 | { |
738 | - pops->enable_probe (probe->probe); | |
711 | + pops->enable_probe (probe.probe); | |
739 | 712 | current_uiout->message (_("Probe %s:%s enabled.\n"), |
740 | - probe->probe->provider, probe->probe->name); | |
713 | + probe.probe->provider, probe.probe->name); | |
741 | 714 | } |
742 | 715 | else |
743 | 716 | current_uiout->message (_("Probe %s:%s cannot be enabled.\n"), |
744 | - probe->probe->provider, probe->probe->name); | |
717 | + probe.probe->provider, probe.probe->name); | |
745 | 718 | } |
746 | 719 | |
747 | 720 | do_cleanups (cleanup); |
@@ -754,14 +727,12 @@ disable_probes_command (char *arg, int from_tty) | ||
754 | 727 | { |
755 | 728 | std::string provider, probe_name, objname; |
756 | 729 | struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); |
757 | - VEC (bound_probe_s) *probes; | |
758 | - struct bound_probe *probe; | |
759 | - int i; | |
760 | 730 | |
761 | 731 | parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname); |
762 | 732 | |
763 | - probes = collect_probes (objname, provider, probe_name, NULL /* pops */); | |
764 | - if (VEC_empty (bound_probe_s, probes)) | |
733 | + std::vector<bound_probe> probes | |
734 | + = collect_probes (objname, provider, probe_name, NULL /* pops */); | |
735 | + if (probes.empty ()) | |
765 | 736 | { |
766 | 737 | current_uiout->message (_("No probes matched.\n")); |
767 | 738 | do_cleanups (cleanup); |
@@ -770,19 +741,19 @@ disable_probes_command (char *arg, int from_tty) | ||
770 | 741 | |
771 | 742 | /* Disable the selected probes, provided their backends support the |
772 | 743 | notion of enabling a probe. */ |
773 | - for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i) | |
744 | + for (const bound_probe &probe : probes) | |
774 | 745 | { |
775 | - const struct probe_ops *pops = probe->probe->pops; | |
746 | + const struct probe_ops *pops = probe.probe->pops; | |
776 | 747 | |
777 | 748 | if (pops->disable_probe != NULL) |
778 | 749 | { |
779 | - pops->disable_probe (probe->probe); | |
750 | + pops->disable_probe (probe.probe); | |
780 | 751 | current_uiout->message (_("Probe %s:%s disabled.\n"), |
781 | - probe->probe->provider, probe->probe->name); | |
752 | + probe.probe->provider, probe.probe->name); | |
782 | 753 | } |
783 | 754 | else |
784 | 755 | current_uiout->message (_("Probe %s:%s cannot be disabled.\n"), |
785 | - probe->probe->provider, probe->probe->name); | |
756 | + probe.probe->provider, probe.probe->name); | |
786 | 757 | } |
787 | 758 | |
788 | 759 | do_cleanups (cleanup); |
@@ -214,15 +214,26 @@ struct probe | ||
214 | 214 | their point of use. */ |
215 | 215 | |
216 | 216 | struct bound_probe |
217 | - { | |
218 | - /* The probe. */ | |
217 | +{ | |
218 | + /* Create an empty bound_probe object. */ | |
219 | 219 | |
220 | - struct probe *probe; | |
220 | + bound_probe () | |
221 | + {} | |
221 | 222 | |
222 | - /* The objfile in which the probe originated. */ | |
223 | + /* Create and initialize a bound_probe object using PROBE and OBJFILE. */ | |
223 | 224 | |
224 | - struct objfile *objfile; | |
225 | - }; | |
225 | + bound_probe (struct probe *probe_, struct objfile *objfile_) | |
226 | + : probe (probe_), objfile (objfile_) | |
227 | + {} | |
228 | + | |
229 | + /* The probe. */ | |
230 | + | |
231 | + struct probe *probe = NULL; | |
232 | + | |
233 | + /* The objfile in which the probe originated. */ | |
234 | + | |
235 | + struct objfile *objfile = NULL; | |
236 | +}; | |
226 | 237 | |
227 | 238 | /* A helper for linespec that decodes a probe specification. It |
228 | 239 | returns a std::vector<symtab_and_line> object and updates LOC or |