diff --git a/gprofng/libcollector/heaptrace.c b/gprofng/libcollector/heaptrace.c index cf39d12cc69..985fb69e783 100644 --- a/gprofng/libcollector/heaptrace.c +++ b/gprofng/libcollector/heaptrace.c @@ -61,6 +61,8 @@ static ModuleInterface module_interface = { static CollectorInterface *collector_interface = NULL; static int heap_mode = 0; +static size_t start_range = 0; +static size_t end_range = SIZE_MAX; static CollectorModule heap_hndl = COLLECTOR_MODULE_ERR; static const Heap_packet heap_packet0 = { .comm.tsize = sizeof ( Heap_packet) }; static __thread int reentrance = 0; @@ -132,6 +134,15 @@ open_experiment (const char *exp) if (params == NULL) /* Heap data collection not specified */ return COL_ERROR_HEAPINIT; + if (*params != 'o') // Not -H on. Read a range. + { + char *s; + start_range = (size_t) CALL_UTIL (strtoull) (params, &s, 0); + if (*s == '-') + end_range = (size_t) CALL_UTIL (strtoull) (s + 1, &s, 0); + fprintf(stderr, "Range: %lld - %lld\n", (long long) start_range, (long long) end_range); + } + collector_interface->writeLog ("\n", SP_JCMD_HEAPTRACE); collector_interface->writeLog (" \n", module_interface.description); @@ -264,6 +275,12 @@ malloc (size_t size) return ret; } PUSH_REENTRANCE; + if (size < start_range || size >= end_range) + { + ret = (void *) CALL_REAL (malloc)(size); + POP_REENTRANCE; + return ret; + } Heap_packet hpacket = heap_packet0; hpacket.comm.tstamp = gethrtime (); ret = (void *) CALL_REAL (malloc)(size); @@ -333,6 +350,12 @@ realloc (void *ptr, size_t size) return ret; } PUSH_REENTRANCE; + if (size < start_range || size >= end_range) + { + ret = (void *) CALL_REAL (realloc)(ptr, size); + POP_REENTRANCE; + return ret; + } Heap_packet hpacket = heap_packet0; hpacket.comm.tstamp = gethrtime (); ret = (void *) CALL_REAL (realloc)(ptr, size); @@ -359,6 +382,12 @@ memalign (size_t align, size_t size) return ret; } PUSH_REENTRANCE; + if (size < start_range || size >= end_range) + { + ret = (void *) CALL_REAL (memalign)(align, size); + POP_REENTRANCE; + return ret; + } Heap_packet hpacket = heap_packet0; hpacket.comm.tstamp = gethrtime (); ret = (void *) CALL_REAL (memalign)(align, size); @@ -386,6 +415,12 @@ valloc (size_t size) return ret; } PUSH_REENTRANCE; + if (size < start_range || size >= end_range) + { + ret = (void *) CALL_REAL (valloc)(size); + POP_REENTRANCE; + return ret; + } Heap_packet hpacket = heap_packet0; hpacket.comm.tstamp = gethrtime (); ret = (void *) CALL_REAL (valloc)(size); @@ -416,6 +451,13 @@ calloc (size_t size, size_t esize) return ret; } PUSH_REENTRANCE; + size_t sz = size * esize; + if (sz < start_range || sz >= end_range) + { + ret = (void *) CALL_REAL (calloc)(size, esize); + POP_REENTRANCE; + return ret; + } Heap_packet hpacket = heap_packet0; hpacket.comm.tstamp = gethrtime (); ret = (void *) CALL_REAL (calloc)(size, esize); diff --git a/gprofng/src/collctrl.cc b/gprofng/src/collctrl.cc index ece01d17f32..7838e8a83a7 100644 --- a/gprofng/src/collctrl.cc +++ b/gprofng/src/collctrl.cc @@ -227,8 +227,7 @@ Coll_Ctrl::Coll_Ctrl (int _interactive, bool _defHWC, bool _kernelHWC) synctrace_enabled = 0; synctrace_thresh = -1; synctrace_scope = 0; - heaptrace_enabled = 0; - heaptrace_checkenabled = 0; + heaptrace_mode = NULL; iotrace_enabled = 0; count_enabled = 0; Iflag = 0; @@ -300,8 +299,7 @@ Coll_Ctrl::Coll_Ctrl (Coll_Ctrl * cc) synctrace_enabled = cc->synctrace_enabled; synctrace_thresh = cc->synctrace_thresh; synctrace_scope = cc->synctrace_scope; - heaptrace_enabled = cc->heaptrace_enabled; - heaptrace_checkenabled = cc->heaptrace_checkenabled; + heaptrace_mode = dbe_strdup(cc->heaptrace_mode); iotrace_enabled = cc->iotrace_enabled; count_enabled = cc->count_enabled; Iflag = cc->Iflag; @@ -365,6 +363,7 @@ Coll_Ctrl::~Coll_Ctrl () free (hwc_string); free (project_home); free (java_path); + free (heaptrace_mode); hwcprof_enabled_cnt = 0; } @@ -452,7 +451,7 @@ Coll_Ctrl::check_consistency () if (count_enabled != 0 && ((clkprof_default != 1 && clkprof_enabled != 0) || hwcprof_enabled_cnt != 0 || synctrace_enabled != 0 - || heaptrace_enabled != 0 || iotrace_enabled != 0)) + || heaptrace_mode != NULL || iotrace_enabled != 0)) return strdup (GTXT ("Count data cannot be collected along with any other data.\n")); /* if count data, various other options are not allowed */ @@ -478,12 +477,12 @@ Coll_Ctrl::check_expt (char **warn) if (ret != NULL) /* something is wrong, return the error */ return ret; /* check for heaptrace and java -- warn that it covers native allocations only */ - if (heaptrace_enabled == 1 && java_mode == 1 && java_default == 0) + if (heaptrace_mode != NULL && java_mode == 1 && java_default == 0) *warn = strdup (GTXT ("Note: Heap profiling will only trace native allocations, not Java allocations.\n")); /* if no profiling data selected, warn the user */ if (clkprof_enabled == 0 && hwcprof_enabled_cnt == 0 && synctrace_enabled == 0 - && heaptrace_enabled == 0 && iotrace_enabled == 0 && count_enabled == 0) + && heaptrace_mode == NULL && iotrace_enabled == 0 && count_enabled == 0) *warn = strdup (GTXT ("Warning: No function level data requested; only statistics will be collected.\n\n")); build_data_desc (); @@ -564,15 +563,8 @@ Coll_Ctrl::show (int i) sb.appendf ("\t %u. %s\n", ii + 1, hwc_hwcentry_specd_string (ctrbuf, sizeof (ctrbuf), &hwctr[ii])); } - if (heaptrace_enabled != 0) - { - if (heaptrace_checkenabled == 0) - sb.append (GTXT ("\theap tracing enabled, no checking\n")); - else if (heaptrace_checkenabled == 1) - sb.append (GTXT ("\theap tracing enabled, over/underrun checking\n")); - else - sb.append (GTXT ("\theap tracing enabled, over/underrun checking and pattern storing\n")); - } + if (heaptrace_mode != NULL) + sb.append (GTXT ("\theap tracing enabled\n")); if (iotrace_enabled != 0) sb.append (GTXT ("\tI/O tracing enabled\n")); switch (count_enabled) @@ -712,10 +704,10 @@ Coll_Ctrl::get_collect_args () } *p++ = sb.toString (); } - if (heaptrace_enabled != 0) + if (heaptrace_mode != NULL) { *p++ = strdup ("-H"); - *p++ = strdup ("on"); + *p++ = strdup (heaptrace_mode); } if (iotrace_enabled != 0) { @@ -1048,39 +1040,40 @@ Coll_Ctrl::set_heaptrace (const char *string) { if (opened == 1) return strdup (GTXT ("Experiment is active; command ignored.\n")); + free(heaptrace_mode); + heaptrace_mode = NULL; // Same as "off" + if (string != NULL && strcmp (string, "off") == 0) + return NULL; + if (string == NULL || strlen (string) == 0 || strcmp (string, "on") == 0) + heaptrace_mode = strdup ("on"); + else if (isdigit (*string)) { - heaptrace_enabled = 1; - char *ret = check_consistency (); - if (ret != NULL) + char *s; + unsigned long long n = strtoull (string, &s, 0); + if (*s == '-' && isdigit (s[1])) { - heaptrace_enabled = 0; - return ret; + unsigned long long n1 = strtoull (s + 1, &s, 0); + if (n1 < n) + return dbe_sprintf ( + GTXT ("Incorrect range in heap trace parameter '%s'\n"), string); } - return NULL; + if (*s != 0) + return dbe_sprintf ( + GTXT ("Incorrect range in heap trace parameter '%s'\n"), string); + heaptrace_mode = strdup (string); } - if (strcmp (string, "off") == 0) + else + return dbe_sprintf (GTXT ("Unrecognized heap tracing parameter `%s'\n"), + string); + char *ret = check_consistency (); + if (ret != NULL) { - heaptrace_enabled = 0; - return NULL; + free (heaptrace_mode); + heaptrace_mode = NULL; + return ret; } -#if 0 - if (strcmp (string, "check") == 0) - { - /* set to check for over/underruns */ - heaptrace_checkenabled = 1; - heaptrace_enabled = 1; - return NULL; - } - if (strcmp (string, "clear") == 0) - { - /* set to check for over/underruns, and store patterns */ - heaptrace_checkenabled = 2; - heaptrace_enabled = 1; - return NULL; - } -#endif - return dbe_sprintf (GTXT ("Unrecognized heap tracing parameter `%s'\n"), string); + return NULL; } char * @@ -1675,8 +1668,8 @@ Coll_Ctrl::build_data_desc () sb.appendf ("p:%d;", clkprof_timer); if (synctrace_enabled == 1) sb.appendf ("s:%d,%d;", synctrace_thresh, synctrace_scope); - if (heaptrace_enabled == 1) - sb.appendf ("H:%d;", heaptrace_checkenabled); + if (heaptrace_mode != NULL && strcmp (heaptrace_mode, "off") != 0) + sb.appendf ("H:%s;", heaptrace_mode); if (iotrace_enabled == 1) sb.append ("i:;"); if (hwcprof_enabled_cnt > 0) @@ -2834,7 +2827,7 @@ Coll_Ctrl::get (char * control) } if (!strncmp (control, ipc_str_heaptrace, len)) { - if ((heaptrace_enabled == 0)) + if (heaptrace_mode == NULL) return strdup (ipc_str_off); return strdup (ipc_str_on); } @@ -3019,7 +3012,8 @@ Coll_Ctrl::unset (char * control) } if (!strncmp (control, ipc_str_heaptrace, len)) { - heaptrace_enabled = 0; + free (heaptrace_mode); + heaptrace_mode = NULL; return NULL; } if (!strncmp (control, ipc_str_iotrace, len)) diff --git a/gprofng/src/collctrl.h b/gprofng/src/collctrl.h index a41647440ac..788df7a421f 100644 --- a/gprofng/src/collctrl.h +++ b/gprofng/src/collctrl.h @@ -101,8 +101,7 @@ public: /* set the parameters for heap tracing */ char *set_heaptrace(const char *); - int get_heaptrace_mode() { return heaptrace_enabled; }; - int get_heaptrace_checkmode() { return heaptrace_checkenabled; }; + char *get_heaptrace_mode() { return heaptrace_mode; }; /* set the parameters for I/O tracing */ char *set_iotrace(const char *); @@ -342,12 +341,7 @@ private: /* definitions in data_pckts.h */ int synctrace_scope; - int heaptrace_enabled; /* T if heap tracing */ - /* if 0 no checking; - * if 1, check for over- and under-write - * if 2, also set patterns in malloc'd and free'd areas - */ - int heaptrace_checkenabled; + char *heaptrace_mode; /* NULL, or on, or off, or range */ int iotrace_enabled; /* T if I/O tracing */ /* count controls */ diff --git a/gprofng/src/envsets.cc b/gprofng/src/envsets.cc index 9cef7452df7..70510fbd4bd 100644 --- a/gprofng/src/envsets.cc +++ b/gprofng/src/envsets.cc @@ -107,7 +107,7 @@ collect::putenv_libcollector_ld_preloads () // for those data types that get extra libs LD_PRELOAD'd, add them if (cc->get_synctrace_mode () != 0) add_ld_preload ("libgp-sync.so"); - if (cc->get_heaptrace_mode () != 0) + if (cc->get_heaptrace_mode () != NULL) add_ld_preload ("libgp-heap.so"); if (cc->get_iotrace_mode () != 0) add_ld_preload ("libgp-iotrace.so"); diff --git a/gprofng/src/gp-collect-app.cc b/gprofng/src/gp-collect-app.cc index 5a3653f0966..c80c1b0bbee 100644 --- a/gprofng/src/gp-collect-app.cc +++ b/gprofng/src/gp-collect-app.cc @@ -1403,7 +1403,7 @@ collect::usage () end of this long list. */ printf ( GTXT ( - "Usage: gprofng collect app [OPTION(S)] TARGET [TARGET_ARGUMENTS]\n")), + "Usage: gprofng collect app [OPTION(S)] TARGET [TARGET_ARGUMENTS]\n")); /* ------------------------------------------------------------------------------- @@ -1481,7 +1481,8 @@ collect::usage () " \"n\" selects native/Pthreads, \"j\" selects Java, and \"nj\" selects both;\n" " the default is \"-s off\".\n" "\n" - " -H {off|on} disable (off), or enable (on) heap tracing; the default is \"-H off\".\n" + " -H {off|on|N1[-N2]} disable (off), or enable (on) heap tracing, or\n" + " specify the heap data collection range. The default is \"-H off\".\n" "\n" " -i {off|on} disable (off), or enable (on) I/O tracing; the default is \"-i off\".\n" "\n" @@ -1494,84 +1495,6 @@ collect::usage () "See also:\n" "\n" "gprofng(1), gp-archive(1), gp-display-html(1), gp-display-src(1), gp-display-text(1)\n")); -/* - char *s = dbe_sprintf (GTXT ("Usage: %s target \n"), - whoami); - writeStr (usage_fd, s); - free (s); - writeStr (usage_fd, GTXT (" -p {lo|on|hi|off|}\tspecify clock-profiling\n")); - writeStr (usage_fd, GTXT ("\t`lo' per-thread rate of ~10 samples/second\n")); - writeStr (usage_fd, GTXT ("\t`on' per-thread rate of ~100 samples/second (default)\n")); - writeStr (usage_fd, GTXT ("\t`hi' per-thread rate of ~1000 samples/second\n")); - writeStr (usage_fd, GTXT ("\t`off' disable clock profiling\n")); - writeStr (usage_fd, GTXT ("\t specify profile timer period in millisec.\n")); - s = dbe_sprintf (GTXT ("\t\t\tRange on this system is from %.3f to %.3f millisec.\n\t\t\tResolution is %.3f millisec.\n"), - (double) cc->get_clk_min () / 1000., - (double) cc->get_clk_max () / 1000., - (double) cc->get_clk_res () / 1000.); - writeStr (usage_fd, s); - free (s); - writeStr (usage_fd, GTXT (" -h ...[,]\tspecify HW counter profiling\n")); - s = dbe_sprintf (GTXT ("\tto see the supported HW counters on this machine, run \"%s -h\" with no other arguments\n"), - whoami); - writeStr (usage_fd, s); - free (s); - writeStr (usage_fd, GTXT (" -s [,]\tspecify synchronization wait tracing\n")); - writeStr (usage_fd, GTXT ("\t is \"j\" for tracing Java-APIs, \"n\" for tracing native-APIs, or \"nj\" for tracing both\n")); - writeStr (usage_fd, GTXT (" -H {on|off}\tspecify heap tracing\n")); - writeStr (usage_fd, GTXT (" -i {on|off}\tspecify I/O tracing\n")); - writeStr (usage_fd, GTXT (" -N \tspecify library to exclude count from instrumentation (requires -c also)\n")); - writeStr (usage_fd, GTXT (" \tmultiple -N arguments can be provided\n")); - writeStr (usage_fd, GTXT (" -j {on|off|path}\tspecify Java profiling\n")); - writeStr (usage_fd, GTXT (" -J \tspecify arguments to Java for Java profiling\n")); - writeStr (usage_fd, GTXT (" -t \tspecify time over which to record data\n")); - writeStr (usage_fd, GTXT (" -n\tdry run -- don't run target or collect performance data\n")); - writeStr (usage_fd, GTXT (" -y [,r]\tspecify delayed initialization and pause/resume signal\n")); - writeStr (usage_fd, GTXT ("\tWhen set, the target starts in paused mode;\n\t if the optional r is provided, it starts in resumed mode\n")); - writeStr (usage_fd, GTXT (" -F {on|off|=}\tspecify following descendant processes\n")); - writeStr (usage_fd, GTXT (" -a {on|ldobjects|src|usedldobjects|usedsrc|off}\tspecify archiving of binaries and other files;\n")); - writeStr (usage_fd, GTXT (" -S {on|off|}\t Set the interval for periodic sampling of process-wide resource utilization\n")); - writeStr (usage_fd, GTXT (" -l \tspecify signal that will trigger a sample of process-wide resource utilization\n")); - writeStr (usage_fd, GTXT (" -o \tspecify experiment name\n")); - writeStr (usage_fd, GTXT (" --verbose\tprint expanded log of processing\n")); - writeStr (usage_fd, GTXT (" -C