aboutsummaryrefslogtreecommitdiff
path: root/gprofng
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2024-08-08 21:30:08 -0700
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>2024-08-12 15:54:59 -0700
commit6a60060d3e7b39868ca2fbb2c8ef1c593fd00313 (patch)
tree80129c581623d83441d8924efcc9470ba1c2e018 /gprofng
parentc412d3f5d9ec6c9493232df9c91e17361af775f0 (diff)
downloadgdb-6a60060d3e7b39868ca2fbb2c8ef1c593fd00313.zip
gdb-6a60060d3e7b39868ca2fbb2c8ef1c593fd00313.tar.gz
gdb-6a60060d3e7b39868ca2fbb2c8ef1c593fd00313.tar.bz2
gprofng: specify the heap data collection range
Extend the -H option: -H {off|on|N1[-N2]} disable , or enable heap tracing, or specify the heap data collection range. The default is "-H off". gprofng/ChangeLog 2024-08-08 Vladimir Mezentsev <vladimir.mezentsev@oracle.com> * libcollector/heaptrace.c: Read the range in the -H option. Do not collect data if the allocated memory is out of range. * src/collctrl.h (heaptrace_mode): Define as char * value. * src/envsets.cc: Updated since heaptrace_mode is changed. * src/collctrl.cc: Accept the extended -H option. * src/gp-collect-app.cc: Accept the extended -H option. Remove unused code.
Diffstat (limited to 'gprofng')
-rw-r--r--gprofng/libcollector/heaptrace.c42
-rw-r--r--gprofng/src/collctrl.cc90
-rw-r--r--gprofng/src/collctrl.h10
-rw-r--r--gprofng/src/envsets.cc2
-rw-r--r--gprofng/src/gp-collect-app.cc83
5 files changed, 90 insertions, 137 deletions
diff --git a/gprofng/libcollector/heaptrace.c b/gprofng/libcollector/heaptrace.c
index cf39d12..985fb69 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 ("<profile name=\"%s\">\n", SP_JCMD_HEAPTRACE);
collector_interface->writeLog (" <profdata fname=\"%s\"/>\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 ece01d1..7838e8a 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)
- {
- heaptrace_enabled = 0;
- return NULL;
- }
-#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)
+ else
+ return dbe_sprintf (GTXT ("Unrecognized heap tracing parameter `%s'\n"),
+ string);
+ char *ret = check_consistency ();
+ if (ret != NULL)
{
- /* set to check for over/underruns, and store patterns */
- heaptrace_checkenabled = 2;
- heaptrace_enabled = 1;
- return NULL;
+ free (heaptrace_mode);
+ heaptrace_mode = NULL;
+ return ret;
}
-#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 a416474..788df7a 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 9cef745..70510fb 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 5a3653f..c80c1b0 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 <args> target <target-args>\n"),
- whoami);
- writeStr (usage_fd, s);
- free (s);
- writeStr (usage_fd, GTXT (" -p {lo|on|hi|off|<value>}\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<value> 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 <ctr_def>...[,<ctr_n_def>]\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 <threshold>[,<scope>]\tspecify synchronization wait tracing\n"));
- writeStr (usage_fd, GTXT ("\t<scope> 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 <lib>\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 <java-args>\tspecify arguments to Java for Java profiling\n"));
- writeStr (usage_fd, GTXT (" -t <duration>\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 <signal>[,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|=<regex>}\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|<seconds>}\t Set the interval for periodic sampling of process-wide resource utilization\n"));
- writeStr (usage_fd, GTXT (" -l <signal>\tspecify signal that will trigger a sample of process-wide resource utilization\n"));
- writeStr (usage_fd, GTXT (" -o <expt>\tspecify experiment name\n"));
- writeStr (usage_fd, GTXT (" --verbose\tprint expanded log of processing\n"));
- writeStr (usage_fd, GTXT (" -C <label>\tspecify comment label (up to 10 may appear)\n"));
- writeStr (usage_fd, GTXT (" -V|--version\tprint version number and exit\n"));
-*/
- /* don't document this feature */
- // writeStr (usage_fd, GTXT(" -Z\tPreload mem.so, and launch target [no experiment]\n") );
-/*
- writeStr (usage_fd, GTXT ("\n See the gp-collect(1) man page for more information\n"));
-*/
-
-#if 0
- /* print an extended usage message */
- /* find a Java for Java profiling, set Java on to check Java */
- find_java ();
- cc->set_java_mode (NTXT ("on"));
-
- /* check for variable-clock rate */
- unsigned char mode = COL_CPUFREQ_NONE;
- get_cpu_frequency (&mode);
- if (mode != COL_CPUFREQ_NONE)
- writeStr (usage_fd, GTXT ("NOTE: system has variable clock frequency, which may cause variable program run times.\n"));
-
- /* show the experiment that would be run */
- writeStr (usage_fd, GTXT ("\n Default experiment:\n"));
- char *ccret = cc->setup_experiment ();
- if (ccret != NULL)
- {
- writeStr (usage_fd, ccret);
- free (ccret);
- exit (1);
- }
- cc->delete_expt ();
- ccret = cc->show (1);
- if (ccret != NULL)
- {
- writeStr (usage_fd, ccret);
- free (ccret);
- }
-#endif
}
void