mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
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.
This commit is contained in:
parent
c412d3f5d9
commit
6a60060d3e
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user