pmcstat.c (169069) | pmcstat.c (174396) |
---|---|
1/*- 2 * Copyright (c) 2003-2007, Joseph Koshy | 1/*- 2 * Copyright (c) 2003-2007, Joseph Koshy |
3 * Copyright (c) 2007 The FreeBSD Foundation |
|
3 * All rights reserved. 4 * | 4 * All rights reserved. 5 * |
6 * Portions of this software were developed by A. Joseph Koshy under 7 * sponsorship from the FreeBSD Foundation and Google, Inc. 8 * |
|
5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. --- 7 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. --- 7 unchanged lines hidden (view full) --- 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/usr.sbin/pmcstat/pmcstat.c 169069 2007-04-27 12:09:31Z jkoshy $"); | 32__FBSDID("$FreeBSD: head/usr.sbin/pmcstat/pmcstat.c 174396 2007-12-07 08:26:21Z jkoshy $"); |
29 30#include <sys/types.h> 31#include <sys/event.h> 32#include <sys/param.h> 33#include <sys/queue.h> 34#include <sys/socket.h> 35#include <sys/stat.h> 36#include <sys/sysctl.h> --- 444 unchanged lines hidden (view full) --- 481 errx(EX_USAGE, 482 "[options] [commandline]\n" 483 "\t Measure process and/or system performance using hardware\n" 484 "\t performance monitoring counters.\n" 485 "\t Options include:\n" 486 "\t -C\t\t (toggle) show cumulative counts\n" 487 "\t -D path\t create profiles in directory \"path\"\n" 488 "\t -E\t\t (toggle) show counts at process exit\n" | 33 34#include <sys/types.h> 35#include <sys/event.h> 36#include <sys/param.h> 37#include <sys/queue.h> 38#include <sys/socket.h> 39#include <sys/stat.h> 40#include <sys/sysctl.h> --- 444 unchanged lines hidden (view full) --- 485 errx(EX_USAGE, 486 "[options] [commandline]\n" 487 "\t Measure process and/or system performance using hardware\n" 488 "\t performance monitoring counters.\n" 489 "\t Options include:\n" 490 "\t -C\t\t (toggle) show cumulative counts\n" 491 "\t -D path\t create profiles in directory \"path\"\n" 492 "\t -E\t\t (toggle) show counts at process exit\n" |
493 "\t -G file\t write a system-wide callgraph to \"file\"\n" |
|
489 "\t -M file\t print executable/gmon file map to \"file\"\n" | 494 "\t -M file\t print executable/gmon file map to \"file\"\n" |
495 "\t -N\t\t (toggle) capture callchains\n" |
|
490 "\t -O file\t send log output to \"file\"\n" 491 "\t -P spec\t allocate a process-private sampling PMC\n" 492 "\t -R file\t read events from \"file\"\n" 493 "\t -S spec\t allocate a system-wide sampling PMC\n" 494 "\t -W\t\t (toggle) show counts per context switch\n" 495 "\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n" 496 "\t -d\t\t (toggle) track descendants\n" 497 "\t -g\t\t produce gprof(1) compatible profiles\n" 498 "\t -k dir\t\t set the path to the kernel\n" 499 "\t -n rate\t set sampling rate\n" 500 "\t -o file\t send print output to \"file\"\n" 501 "\t -p spec\t allocate a process-private counting PMC\n" 502 "\t -q\t\t suppress verbosity\n" 503 "\t -r fsroot\t specify FS root directory\n" 504 "\t -s spec\t allocate a system-wide counting PMC\n" 505 "\t -t pid\t\t attach to running process with pid \"pid\"\n" 506 "\t -v\t\t increase verbosity\n" | 496 "\t -O file\t send log output to \"file\"\n" 497 "\t -P spec\t allocate a process-private sampling PMC\n" 498 "\t -R file\t read events from \"file\"\n" 499 "\t -S spec\t allocate a system-wide sampling PMC\n" 500 "\t -W\t\t (toggle) show counts per context switch\n" 501 "\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n" 502 "\t -d\t\t (toggle) track descendants\n" 503 "\t -g\t\t produce gprof(1) compatible profiles\n" 504 "\t -k dir\t\t set the path to the kernel\n" 505 "\t -n rate\t set sampling rate\n" 506 "\t -o file\t send print output to \"file\"\n" 507 "\t -p spec\t allocate a process-private counting PMC\n" 508 "\t -q\t\t suppress verbosity\n" 509 "\t -r fsroot\t specify FS root directory\n" 510 "\t -s spec\t allocate a system-wide counting PMC\n" 511 "\t -t pid\t\t attach to running process with pid \"pid\"\n" 512 "\t -v\t\t increase verbosity\n" |
507 "\t -w secs\t set printing time interval" | 513 "\t -w secs\t set printing time interval\n" 514 "\t -z depth\t limit callchain display depth" |
508 ); 509} 510 511/* 512 * Main 513 */ 514 515int 516main(int argc, char **argv) 517{ 518 double interval; | 515 ); 516} 517 518/* 519 * Main 520 */ 521 522int 523main(int argc, char **argv) 524{ 525 double interval; |
519 int option, npmc, ncpu; | 526 int option, npmc, ncpu, haltedcpus; |
520 int c, check_driver_stats, current_cpu, current_sampling_count; | 527 int c, check_driver_stats, current_cpu, current_sampling_count; |
521 int do_print, do_descendants; 522 int do_logproccsw, do_logprocexit; | 528 int do_callchain, do_descendants, do_logproccsw, do_logprocexit; 529 int do_print; |
523 size_t dummy; | 530 size_t dummy; |
531 int graphdepth; |
|
524 int pipefd[2]; 525 int use_cumulative_counts; 526 uint32_t cpumask; 527 char *end, *tmp; | 532 int pipefd[2]; 533 int use_cumulative_counts; 534 uint32_t cpumask; 535 char *end, *tmp; |
528 const char *errmsg; | 536 const char *errmsg, *graphfilename; |
529 enum pmcstat_state runstate; 530 struct pmc_driverstats ds_start, ds_end; 531 struct pmcstat_ev *ev; 532 struct sigaction sa; 533 struct kevent kev; 534 struct winsize ws; 535 struct stat sb; 536 char buffer[PATH_MAX]; 537 538 check_driver_stats = 0; 539 current_cpu = 0; 540 current_sampling_count = DEFAULT_SAMPLE_COUNT; | 537 enum pmcstat_state runstate; 538 struct pmc_driverstats ds_start, ds_end; 539 struct pmcstat_ev *ev; 540 struct sigaction sa; 541 struct kevent kev; 542 struct winsize ws; 543 struct stat sb; 544 char buffer[PATH_MAX]; 545 546 check_driver_stats = 0; 547 current_cpu = 0; 548 current_sampling_count = DEFAULT_SAMPLE_COUNT; |
549 do_callchain = 1; |
|
541 do_descendants = 0; 542 do_logproccsw = 0; 543 do_logprocexit = 0; 544 use_cumulative_counts = 0; | 550 do_descendants = 0; 551 do_logproccsw = 0; 552 do_logprocexit = 0; 553 use_cumulative_counts = 0; |
554 graphfilename = "-"; |
|
545 args.pa_required = 0; 546 args.pa_flags = 0; 547 args.pa_verbosity = 1; 548 args.pa_logfd = -1; 549 args.pa_fsroot = ""; 550 args.pa_kernel = strdup("/boot/kernel"); 551 args.pa_samplesdir = "."; 552 args.pa_printfile = stderr; | 555 args.pa_required = 0; 556 args.pa_flags = 0; 557 args.pa_verbosity = 1; 558 args.pa_logfd = -1; 559 args.pa_fsroot = ""; 560 args.pa_kernel = strdup("/boot/kernel"); 561 args.pa_samplesdir = "."; 562 args.pa_printfile = stderr; |
563 args.pa_graphdepth = DEFAULT_CALLGRAPH_DEPTH; 564 args.pa_graphfile = NULL; |
|
553 args.pa_interval = DEFAULT_WAIT_INTERVAL; 554 args.pa_mapfilename = NULL; | 565 args.pa_interval = DEFAULT_WAIT_INTERVAL; 566 args.pa_mapfilename = NULL; |
567 args.pa_inputpath = NULL; 568 args.pa_outputpath = NULL; |
|
555 STAILQ_INIT(&args.pa_events); 556 SLIST_INIT(&args.pa_targets); 557 bzero(&ds_start, sizeof(ds_start)); 558 bzero(&ds_end, sizeof(ds_end)); 559 ev = NULL; 560 | 569 STAILQ_INIT(&args.pa_events); 570 SLIST_INIT(&args.pa_targets); 571 bzero(&ds_start, sizeof(ds_start)); 572 bzero(&ds_end, sizeof(ds_end)); 573 ev = NULL; 574 |
561 dummy = sizeof(ncpu); | 575 /* 576 * The initial CPU mask specifies all non-halted CPUS in the 577 * system. 578 */ 579 dummy = sizeof(int); |
562 if (sysctlbyname("hw.ncpu", &ncpu, &dummy, NULL, 0) < 0) | 580 if (sysctlbyname("hw.ncpu", &ncpu, &dummy, NULL, 0) < 0) |
563 err(EX_OSERR, "ERROR: Cannot determine #cpus"); | 581 err(EX_OSERR, "ERROR: Cannot determine the number of CPUs"); |
564 cpumask = (1 << ncpu) - 1; | 582 cpumask = (1 << ncpu) - 1; |
583 if (sysctlbyname("machdep.hlt_cpus", &haltedcpus, &dummy, 584 NULL, 0) < 0) 585 err(EX_OSERR, "ERROR: Cannot determine which CPUs are halted"); 586 cpumask &= ~haltedcpus; |
|
565 566 while ((option = getopt(argc, argv, | 587 588 while ((option = getopt(argc, argv, |
567 "CD:EM:O:P:R:S:Wc:dgk:n:o:p:qr:s:t:vw:")) != -1) | 589 "CD:EG:M:NO:P:R:S:Wc:dgk:n:o:p:qr:s:t:vw:z:")) != -1) |
568 switch (option) { 569 case 'C': /* cumulative values */ 570 use_cumulative_counts = !use_cumulative_counts; 571 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 572 break; 573 574 case 'c': /* CPU */ 575 --- 17 unchanged lines hidden (view full) --- 593 args.pa_required |= FLAG_DO_GPROF; 594 break; 595 596 case 'd': /* toggle descendents */ 597 do_descendants = !do_descendants; 598 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 599 break; 600 | 590 switch (option) { 591 case 'C': /* cumulative values */ 592 use_cumulative_counts = !use_cumulative_counts; 593 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 594 break; 595 596 case 'c': /* CPU */ 597 --- 17 unchanged lines hidden (view full) --- 615 args.pa_required |= FLAG_DO_GPROF; 616 break; 617 618 case 'd': /* toggle descendents */ 619 do_descendants = !do_descendants; 620 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 621 break; 622 |
623 case 'G': /* produce a system-wide callgraph */ 624 args.pa_flags |= FLAG_DO_CALLGRAPHS; 625 graphfilename = optarg; 626 break; 627 |
|
601 case 'g': /* produce gprof compatible profiles */ 602 args.pa_flags |= FLAG_DO_GPROF; 603 break; 604 605 case 'k': /* pathname to the kernel */ 606 free(args.pa_kernel); 607 args.pa_kernel = strdup(optarg); | 628 case 'g': /* produce gprof compatible profiles */ 629 args.pa_flags |= FLAG_DO_GPROF; 630 break; 631 632 case 'k': /* pathname to the kernel */ 633 free(args.pa_kernel); 634 args.pa_kernel = strdup(optarg); |
608 args.pa_required |= FLAG_DO_GPROF; | 635 args.pa_required |= FLAG_DO_ANALYSIS; |
609 args.pa_flags |= FLAG_HAS_KERNELPATH; 610 break; 611 612 case 'E': /* log process exit */ 613 do_logprocexit = !do_logprocexit; 614 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 615 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 616 break; 617 618 case 'M': /* mapfile */ 619 args.pa_mapfilename = optarg; 620 break; 621 | 636 args.pa_flags |= FLAG_HAS_KERNELPATH; 637 break; 638 639 case 'E': /* log process exit */ 640 do_logprocexit = !do_logprocexit; 641 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 642 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 643 break; 644 645 case 'M': /* mapfile */ 646 args.pa_mapfilename = optarg; 647 break; 648 |
649 case 'N': 650 do_callchain = !do_callchain; 651 args.pa_required |= FLAG_HAS_SAMPLING_PMCS; 652 break; 653 |
|
622 case 'p': /* process virtual counting PMC */ 623 case 's': /* system-wide counting PMC */ 624 case 'P': /* process virtual sampling PMC */ 625 case 'S': /* system-wide sampling PMC */ 626 if ((ev = malloc(sizeof(*ev))) == NULL) 627 errx(EX_SOFTWARE, "ERROR: Out of memory."); 628 629 switch (option) { --- 29 unchanged lines hidden (view full) --- 659 ev->ev_count = -1; 660 661 if (option == 'S' || option == 's') 662 ev->ev_cpu = ffs(cpumask) - 1; 663 else 664 ev->ev_cpu = PMC_CPU_ANY; 665 666 ev->ev_flags = 0; | 654 case 'p': /* process virtual counting PMC */ 655 case 's': /* system-wide counting PMC */ 656 case 'P': /* process virtual sampling PMC */ 657 case 'S': /* system-wide sampling PMC */ 658 if ((ev = malloc(sizeof(*ev))) == NULL) 659 errx(EX_SOFTWARE, "ERROR: Out of memory."); 660 661 switch (option) { --- 29 unchanged lines hidden (view full) --- 691 ev->ev_count = -1; 692 693 if (option == 'S' || option == 's') 694 ev->ev_cpu = ffs(cpumask) - 1; 695 else 696 ev->ev_cpu = PMC_CPU_ANY; 697 698 ev->ev_flags = 0; |
699 if (do_callchain) 700 ev->ev_flags |= PMC_F_CALLCHAIN; |
|
667 if (do_descendants) 668 ev->ev_flags |= PMC_F_DESCENDANTS; 669 if (do_logprocexit) 670 ev->ev_flags |= PMC_F_LOG_PROCEXIT; 671 if (do_logproccsw) 672 ev->ev_flags |= PMC_F_LOG_PROCCSW; 673 674 ev->ev_cumulative = use_cumulative_counts; --- 45 unchanged lines hidden (view full) --- 720 args.pa_verbosity = 0; 721 break; 722 723 case 'r': /* root FS path */ 724 args.pa_fsroot = optarg; 725 break; 726 727 case 'R': /* read an existing log file */ | 701 if (do_descendants) 702 ev->ev_flags |= PMC_F_DESCENDANTS; 703 if (do_logprocexit) 704 ev->ev_flags |= PMC_F_LOG_PROCEXIT; 705 if (do_logproccsw) 706 ev->ev_flags |= PMC_F_LOG_PROCCSW; 707 708 ev->ev_cumulative = use_cumulative_counts; --- 45 unchanged lines hidden (view full) --- 754 args.pa_verbosity = 0; 755 break; 756 757 case 'r': /* root FS path */ 758 args.pa_fsroot = optarg; 759 break; 760 761 case 'R': /* read an existing log file */ |
728 if (args.pa_logparser != NULL) | 762 if (args.pa_inputpath != NULL) |
729 errx(EX_USAGE, "ERROR: option -R may only be " 730 "specified once."); 731 args.pa_inputpath = optarg; 732 if (args.pa_printfile == stderr) 733 args.pa_printfile = stdout; 734 args.pa_flags |= FLAG_READ_LOGFILE; 735 break; 736 --- 19 unchanged lines hidden (view full) --- 756 break; 757 758 case 'W': /* toggle LOG_CSW */ 759 do_logproccsw = !do_logproccsw; 760 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 761 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 762 break; 763 | 763 errx(EX_USAGE, "ERROR: option -R may only be " 764 "specified once."); 765 args.pa_inputpath = optarg; 766 if (args.pa_printfile == stderr) 767 args.pa_printfile = stdout; 768 args.pa_flags |= FLAG_READ_LOGFILE; 769 break; 770 --- 19 unchanged lines hidden (view full) --- 790 break; 791 792 case 'W': /* toggle LOG_CSW */ 793 do_logproccsw = !do_logproccsw; 794 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 795 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 796 break; 797 |
798 case 'z': 799 graphdepth = strtod(optarg, &end); 800 if (*end != '\0' || graphdepth <= 0) 801 errx(EX_USAGE, "ERROR: Illegal callchain " 802 "depth \"%s\".", optarg); 803 args.pa_graphdepth = graphdepth; 804 args.pa_required |= FLAG_DO_CALLGRAPHS; 805 break; 806 |
|
764 case '?': 765 default: 766 pmcstat_show_usage(); 767 break; 768 769 } 770 771 args.pa_argc = (argc -= optind); 772 args.pa_argv = (argv += optind); 773 | 807 case '?': 808 default: 809 pmcstat_show_usage(); 810 break; 811 812 } 813 814 args.pa_argc = (argc -= optind); 815 args.pa_argv = (argv += optind); 816 |
817 args.pa_cpumask = cpumask; /* For selecting CPUs using -R. */ 818 |
|
774 if (argc) /* command line present */ 775 args.pa_flags |= FLAG_HAS_COMMANDLINE; 776 | 819 if (argc) /* command line present */ 820 args.pa_flags |= FLAG_HAS_COMMANDLINE; 821 |
822 if (args.pa_flags & (FLAG_DO_GPROF | FLAG_DO_CALLGRAPHS)) 823 args.pa_flags |= FLAG_DO_ANALYSIS; 824 |
|
777 /* 778 * Check invocation syntax. 779 */ 780 781 /* disallow -O and -R together */ 782 if (args.pa_outputpath && args.pa_inputpath) 783 errx(EX_USAGE, "ERROR: options -O and -R are mutually " 784 "exclusive."); --- 32 unchanged lines hidden (view full) --- 817 "target process or a command line."); 818 819 /* check for process-mode options without a process-mode PMC */ 820 if ((args.pa_required & FLAG_HAS_PROCESS_PMCS) && 821 (args.pa_flags & FLAG_HAS_PROCESS_PMCS) == 0) 822 errx(EX_USAGE, "ERROR: options -d, -E, and -W require a " 823 "process mode PMC to be specified."); 824 | 825 /* 826 * Check invocation syntax. 827 */ 828 829 /* disallow -O and -R together */ 830 if (args.pa_outputpath && args.pa_inputpath) 831 errx(EX_USAGE, "ERROR: options -O and -R are mutually " 832 "exclusive."); --- 32 unchanged lines hidden (view full) --- 865 "target process or a command line."); 866 867 /* check for process-mode options without a process-mode PMC */ 868 if ((args.pa_required & FLAG_HAS_PROCESS_PMCS) && 869 (args.pa_flags & FLAG_HAS_PROCESS_PMCS) == 0) 870 errx(EX_USAGE, "ERROR: options -d, -E, and -W require a " 871 "process mode PMC to be specified."); 872 |
825 /* check for -c cpu and not system mode PMCs */ | 873 /* check for -c cpu with no system mode PMCs or logfile. */ |
826 if ((args.pa_required & FLAG_HAS_SYSTEM_PMCS) && | 874 if ((args.pa_required & FLAG_HAS_SYSTEM_PMCS) && |
827 (args.pa_flags & FLAG_HAS_SYSTEM_PMCS) == 0) | 875 (args.pa_flags & FLAG_HAS_SYSTEM_PMCS) == 0 && 876 (args.pa_flags & FLAG_READ_LOGFILE) == 0) |
828 errx(EX_USAGE, "ERROR: option -c requires at least one " 829 "system mode PMC to be specified."); 830 831 /* check for counting mode options without a counting PMC */ 832 if ((args.pa_required & FLAG_HAS_COUNTING_PMCS) && 833 (args.pa_flags & FLAG_HAS_COUNTING_PMCS) == 0) 834 errx(EX_USAGE, "ERROR: options -C, -W, -o and -w require at " 835 "least one counting mode PMC to be specified."); 836 837 /* check for sampling mode options without a sampling PMC spec */ 838 if ((args.pa_required & FLAG_HAS_SAMPLING_PMCS) && 839 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) == 0) | 877 errx(EX_USAGE, "ERROR: option -c requires at least one " 878 "system mode PMC to be specified."); 879 880 /* check for counting mode options without a counting PMC */ 881 if ((args.pa_required & FLAG_HAS_COUNTING_PMCS) && 882 (args.pa_flags & FLAG_HAS_COUNTING_PMCS) == 0) 883 errx(EX_USAGE, "ERROR: options -C, -W, -o and -w require at " 884 "least one counting mode PMC to be specified."); 885 886 /* check for sampling mode options without a sampling PMC spec */ 887 if ((args.pa_required & FLAG_HAS_SAMPLING_PMCS) && 888 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) == 0) |
840 errx(EX_USAGE, "ERROR: options -n and -O require at least " 841 "one sampling mode PMC to be specified."); | 889 errx(EX_USAGE, "ERROR: options -N, -n and -O require at " 890 "least one sampling mode PMC to be specified."); |
842 | 891 |
843 /* check if -g is being used correctly */ 844 if ((args.pa_flags & FLAG_DO_GPROF) && | 892 /* check if -g/-G are being used correctly */ 893 if ((args.pa_flags & FLAG_DO_ANALYSIS) && |
845 !(args.pa_flags & (FLAG_HAS_SAMPLING_PMCS|FLAG_READ_LOGFILE))) | 894 !(args.pa_flags & (FLAG_HAS_SAMPLING_PMCS|FLAG_READ_LOGFILE))) |
846 errx(EX_USAGE, "ERROR: option -g requires sampling PMCs or -R " 847 "to be specified."); | 895 errx(EX_USAGE, "ERROR: options -g/-G require sampling PMCs " 896 "or -R to be specified."); |
848 849 /* check if -O was spuriously specified */ 850 if ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) && 851 (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) 852 errx(EX_USAGE, 853 "ERROR: option -O is used only with options " 854 "-E, -P, -S and -W."); 855 | 897 898 /* check if -O was spuriously specified */ 899 if ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) && 900 (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) 901 errx(EX_USAGE, 902 "ERROR: option -O is used only with options " 903 "-E, -P, -S and -W."); 904 |
856 /* -D dir and -k kernel path require -g or -R */ | 905 /* -k kernel path require -g/-G or -R */ |
857 if ((args.pa_flags & FLAG_HAS_KERNELPATH) && | 906 if ((args.pa_flags & FLAG_HAS_KERNELPATH) && |
858 (args.pa_flags & FLAG_DO_GPROF) == 0 && | 907 (args.pa_flags & FLAG_DO_ANALYSIS) == 0 && |
859 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 860 errx(EX_USAGE, "ERROR: option -k is only used with -g/-R."); 861 | 908 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 909 errx(EX_USAGE, "ERROR: option -k is only used with -g/-R."); 910 |
911 /* -D only applies to gprof output mode (-g) */ |
|
862 if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) && | 912 if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) && |
863 (args.pa_flags & FLAG_DO_GPROF) == 0 && 864 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 865 errx(EX_USAGE, "ERROR: option -D is only used with -g/-R."); | 913 (args.pa_flags & FLAG_DO_GPROF) == 0) 914 errx(EX_USAGE, "ERROR: option -D is only used with -g."); |
866 867 /* -M mapfile requires -g or -R */ 868 if (args.pa_mapfilename != NULL && 869 (args.pa_flags & FLAG_DO_GPROF) == 0 && 870 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 871 errx(EX_USAGE, "ERROR: option -M is only used with -g/-R."); 872 873 /* 874 * Disallow textual output of sampling PMCs if counting PMCs 875 * have also been asked for, mostly because the combined output 876 * is difficult to make sense of. 877 */ 878 if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) && 879 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) && 880 ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) == 0)) 881 errx(EX_USAGE, "ERROR: option -O is required if counting and " 882 "sampling PMCs are specified together."); 883 884 /* | 915 916 /* -M mapfile requires -g or -R */ 917 if (args.pa_mapfilename != NULL && 918 (args.pa_flags & FLAG_DO_GPROF) == 0 && 919 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 920 errx(EX_USAGE, "ERROR: option -M is only used with -g/-R."); 921 922 /* 923 * Disallow textual output of sampling PMCs if counting PMCs 924 * have also been asked for, mostly because the combined output 925 * is difficult to make sense of. 926 */ 927 if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) && 928 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) && 929 ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) == 0)) 930 errx(EX_USAGE, "ERROR: option -O is required if counting and " 931 "sampling PMCs are specified together."); 932 933 /* |
885 * Check if "-k kerneldir" was specified, and if whether 'kerneldir' 886 * actually refers to a a file. If so, use `dirname path` to determine 887 * the kernel directory. | 934 * Check if "-k kerneldir" was specified, and if whether 935 * 'kerneldir' actually refers to a a file. If so, use 936 * `dirname path` to determine the kernel directory. |
888 */ 889 if (args.pa_flags & FLAG_HAS_KERNELPATH) { 890 (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, 891 args.pa_kernel); 892 if (stat(buffer, &sb) < 0) 893 err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", 894 buffer); 895 if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) --- 9 unchanged lines hidden (view full) --- 905 err(EX_OSERR, "ERROR: Cannot stat \"%s\"", 906 buffer); 907 if (!S_ISDIR(sb.st_mode)) 908 errx(EX_USAGE, "ERROR: \"%s\" is not a " 909 "directory.", buffer); 910 } 911 } 912 | 937 */ 938 if (args.pa_flags & FLAG_HAS_KERNELPATH) { 939 (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, 940 args.pa_kernel); 941 if (stat(buffer, &sb) < 0) 942 err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", 943 buffer); 944 if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) --- 9 unchanged lines hidden (view full) --- 954 err(EX_OSERR, "ERROR: Cannot stat \"%s\"", 955 buffer); 956 if (!S_ISDIR(sb.st_mode)) 957 errx(EX_USAGE, "ERROR: \"%s\" is not a " 958 "directory.", buffer); 959 } 960 } 961 |
962 /* 963 * If we have a callgraph be created, select the outputfile. 964 */ 965 if (args.pa_flags & FLAG_DO_CALLGRAPHS) { 966 if (strcmp(graphfilename, "-") == 0) 967 args.pa_graphfile = args.pa_printfile; 968 else { 969 args.pa_graphfile = fopen(graphfilename, "w"); 970 if (args.pa_graphfile == NULL) 971 err(EX_OSERR, "ERROR: cannot open \"%s\" " 972 "for writing", graphfilename); 973 } 974 } 975 |
|
913 /* if we've been asked to process a log file, do that and exit */ 914 if (args.pa_flags & FLAG_READ_LOGFILE) { 915 /* 916 * Print the log in textual form if we haven't been | 976 /* if we've been asked to process a log file, do that and exit */ 977 if (args.pa_flags & FLAG_READ_LOGFILE) { 978 /* 979 * Print the log in textual form if we haven't been |
917 * asked to generate gmon.out files. | 980 * asked to generate profiling information. |
918 */ | 981 */ |
919 if ((args.pa_flags & FLAG_DO_GPROF) == 0) | 982 if ((args.pa_flags & FLAG_DO_ANALYSIS) == 0) |
920 args.pa_flags |= FLAG_DO_PRINT; 921 922 pmcstat_initialize_logging(&args); 923 args.pa_logfd = pmcstat_open_log(args.pa_inputpath, 924 PMCSTAT_OPEN_FOR_READ); 925 if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL) 926 err(EX_OSERR, "ERROR: Cannot create parser"); 927 pmcstat_process_log(&args); --- 229 unchanged lines hidden (view full) --- 1157 * We get a SIGIO if a PMC loses all 1158 * of its targets, or if logfile 1159 * writes encounter an error. 1160 */ 1161 if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | 1162 FLAG_HAS_PIPE)) { 1163 runstate = pmcstat_close_log(&args); 1164 if (args.pa_flags & | 983 args.pa_flags |= FLAG_DO_PRINT; 984 985 pmcstat_initialize_logging(&args); 986 args.pa_logfd = pmcstat_open_log(args.pa_inputpath, 987 PMCSTAT_OPEN_FOR_READ); 988 if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL) 989 err(EX_OSERR, "ERROR: Cannot create parser"); 990 pmcstat_process_log(&args); --- 229 unchanged lines hidden (view full) --- 1220 * We get a SIGIO if a PMC loses all 1221 * of its targets, or if logfile 1222 * writes encounter an error. 1223 */ 1224 if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | 1225 FLAG_HAS_PIPE)) { 1226 runstate = pmcstat_close_log(&args); 1227 if (args.pa_flags & |
1165 (FLAG_DO_PRINT|FLAG_DO_GPROF)) | 1228 (FLAG_DO_PRINT|FLAG_DO_ANALYSIS)) |
1166 pmcstat_process_log(&args); 1167 } 1168 do_print = 1; /* print PMCs at exit */ 1169 runstate = PMCSTAT_FINISHED; 1170 } else if (kev.ident == SIGINT) { 1171 /* Kill the child process if we started it */ 1172 if (args.pa_flags & FLAG_HAS_COMMANDLINE) 1173 pmcstat_kill_process(&args); --- 57 unchanged lines hidden --- | 1229 pmcstat_process_log(&args); 1230 } 1231 do_print = 1; /* print PMCs at exit */ 1232 runstate = PMCSTAT_FINISHED; 1233 } else if (kev.ident == SIGINT) { 1234 /* Kill the child process if we started it */ 1235 if (args.pa_flags & FLAG_HAS_COMMANDLINE) 1236 pmcstat_kill_process(&args); --- 57 unchanged lines hidden --- |