diff options
Diffstat (limited to 'gprofng/src/Emsg.cc')
-rw-r--r-- | gprofng/src/Emsg.cc | 614 |
1 files changed, 614 insertions, 0 deletions
diff --git a/gprofng/src/Emsg.cc b/gprofng/src/Emsg.cc new file mode 100644 index 00000000000..11bad97d1b7 --- /dev/null +++ b/gprofng/src/Emsg.cc @@ -0,0 +1,614 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" +#include <stdarg.h> + +#include "util.h" +#include "Emsg.h" +#include "StringBuilder.h" + +// The Emsg, experiment message, has as objects I18N'd messages +// in a structure suitable for attaching to and fetching +// from a queue of such messages. It is intended to +// be used for collector errors, collector warnings, parser +// errors, and er_archive errors that are encountered when +// reading an experiment + +// ----------------------- Message -------------------------- + +Emsg::Emsg (Cmsg_warn w, const char *i18n_text) +{ + warn = w; + flavor = 0; + par = NULL; + text = strdup (i18n_text); + next = NULL; +} + +Emsg::Emsg (Cmsg_warn w, StringBuilder& sb) +{ + warn = w; + flavor = 0; + par = NULL; + text = sb.toString (); + next = NULL; +} + +Emsg::Emsg (Cmsg_warn w, int f, const char *param) +{ + char *type; + warn = w; + flavor = f; + if (param != NULL) + par = dbe_strdup (param); + else + par = dbe_strdup (""); + next = NULL; + + // determine type + switch (warn) + { + case CMSG_WARN: + type = GTXT ("*** Collector Warning"); + break; + case CMSG_ERROR: + type = GTXT ("*** Collector Error"); + break; + case CMSG_FATAL: + type = GTXT ("*** Collector Fatal Error"); + break; + case CMSG_COMMENT: + type = GTXT ("Comment"); + break; + case CMSG_PARSER: + type = GTXT ("*** Log Error"); + break; + case CMSG_ARCHIVE: + type = GTXT ("*** Archive Error"); + break; + default: + type = GTXT ("*** Internal Error"); + break; + }; + + // now convert the message to its I18N'd string + switch (flavor) + { + case COL_ERROR_NONE: + text = dbe_sprintf (GTXT ("%s: No error"), type); + break; + case COL_ERROR_ARGS2BIG: + text = dbe_sprintf (GTXT ("%s: Data argument too long"), type); + break; + case COL_ERROR_BADDIR: + text = dbe_sprintf (GTXT ("%s: Bad experiment directory name"), type); + break; + case COL_ERROR_ARGS: + text = dbe_sprintf (GTXT ("%s: Data argument format error `%s'"), type, par); + break; + case COL_ERROR_PROFARGS: + text = dbe_sprintf (GTXT ("%s: [UNUSED] Bad clock-profiling argument"), type); + break; + case COL_ERROR_SYNCARGS: + text = dbe_sprintf (GTXT ("%s: [UNUSED] Bad synchronization tracing argument"), type); + break; + case COL_ERROR_HWCARGS: + text = dbe_sprintf (GTXT ("%s: Bad hardware counter profiling argument"), type); + break; + case COL_ERROR_DIRPERM: + text = dbe_sprintf (GTXT ("%s: Experiment directory is not writeable; check umask and permissions"), type); + break; + case COL_ERROR_NOMSACCT: + text = dbe_sprintf (GTXT ("%s: Turning on microstate accounting failed"), type); + break; + case COL_ERROR_PROFINIT: + text = dbe_sprintf (GTXT ("%s: Initializing clock-profiling failed"), type); + break; + case COL_ERROR_SYNCINIT: + text = dbe_sprintf (GTXT ("%s: Initializing synchronization tracing failed"), type); + break; + case COL_ERROR_HWCINIT: + text = dbe_sprintf (GTXT ("%s: Initializing hardware counter profiling failed -- %s"), type, par); + break; + case COL_ERROR_HWCFAIL: + text = dbe_sprintf (GTXT ("%s: HW counter data collection failed; likely cause is that another process preempted the counters"), type); + break; + case COL_ERROR_EXPOPEN: + text = dbe_sprintf (GTXT ("%s: Experiment initialization failed, %s"), type, par); + break; + case COL_ERROR_SIZELIM: + text = dbe_sprintf (GTXT ("%s: Experiment size limit exceeded, writing %s"), type, par); + break; + case COL_ERROR_SYSINFO: + text = dbe_sprintf (GTXT ("%s: system name can not be determined"), type); + break; + case COL_ERROR_OVWOPEN: + text = dbe_sprintf (GTXT ("%s: Can't open overview %s"), type, par); + break; + case COL_ERROR_OVWWRITE: + text = dbe_sprintf (GTXT ("%s: Can't write overview %s"), type, par); + break; + case COL_ERROR_OVWREAD: + text = dbe_sprintf (GTXT ("%s: Can't read overview data for %s"), type, par); + break; + case COL_ERROR_NOZMEM: + text = dbe_sprintf (GTXT ("%s: Open of /dev/zero failed: %s"), type, par); + break; + case COL_ERROR_NOZMEMMAP: + text = dbe_sprintf (GTXT ("%s: Mmap of /dev/zero failed: %s"), type, par); + break; + case COL_ERROR_NOHNDL: + text = dbe_sprintf (GTXT ("%s: Out of data handles for %s"), type, par); + break; + case COL_ERROR_FILEOPN: + text = dbe_sprintf (GTXT ("%s: Open failed %s"), type, par); + break; + case COL_ERROR_FILETRNC: + text = dbe_sprintf (GTXT ("%s: Truncate failed for file %s"), type, par); + break; + case COL_ERROR_FILEMAP: + text = dbe_sprintf (GTXT ("%s: Mmap failed %s"), type, par); + break; + case COL_ERROR_HEAPINIT: + text = dbe_sprintf (GTXT ("%s: Initializing heap tracing failed"), type); + break; + case COL_ERROR_DISPINIT: + text = dbe_sprintf (GTXT ("%s: Initializing SIGPROF dispatcher failed"), type); + break; + case COL_ERROR_ITMRINIT: + text = dbe_sprintf (GTXT ("%s: Initializing interval timer failed; %s"), type, par); + break; + case COL_ERROR_SMPLINIT: + text = dbe_sprintf (GTXT ("%s: Initializing periodic sampling failed"), type); + break; + case COL_ERROR_MPIINIT: + text = dbe_sprintf (GTXT ("%s: Initializing MPI tracing failed"), type); + break; + case COL_ERROR_JAVAINIT: + text = dbe_sprintf (GTXT ("%s: Initializing Java profiling failed"), type); + break; + case COL_ERROR_LINEINIT: + text = dbe_sprintf (GTXT ("%s: Initializing descendant process lineage failed"), type); + break; + case COL_ERROR_NOSPACE: + text = dbe_sprintf (GTXT ("%s: Out of disk space writing `%s'"), type, par); + break; + case COL_ERROR_ITMRRST: + text = dbe_sprintf (GTXT ("%s: Resetting interval timer failed: %s"), type, par); + break; + case COL_ERROR_MKDIR: + text = dbe_sprintf (GTXT ("%s: Unable to create directory `%s'"), type, par); + break; + case COL_ERROR_JVM2NEW: + text = dbe_sprintf (GTXT ("%s: JVM version with JVMTI requires more recent release of the performance tools; please upgrade"), type); + break; + case COL_ERROR_JVMNOTSUPP: + text = dbe_sprintf (GTXT ("%s: JVM version does not support JVMTI; no java profiling is available"), type); + break; + case COL_ERROR_JVMNOJSTACK: + text = dbe_sprintf (GTXT ("%s: JVM version does not support java callstacks; java mode data will not be recorded"), type); + break; + case COL_ERROR_DYNOPEN: + text = dbe_sprintf (GTXT ("%s: Can't open dyntext file `%s'"), type, par); + break; + case COL_ERROR_DYNWRITE: + text = dbe_sprintf (GTXT ("%s: Can't write dyntext file `%s'"), type, par); + break; + case COL_ERROR_MAPOPEN: + text = dbe_sprintf (GTXT ("%s: Can't open map file `%s'"), type, par); + break; + case COL_ERROR_MAPREAD: + text = dbe_sprintf (GTXT ("%s: Can't read map file `%s'"), type, par); + break; + case COL_ERROR_MAPWRITE: + text = dbe_sprintf (GTXT ("%s: Can't write map file"), type); + break; + case COL_ERROR_RESOLVE: + text = dbe_sprintf (GTXT ("%s: Can't resolve map file `%s'"), type, par); + break; + case COL_ERROR_OMPINIT: + text = dbe_sprintf (GTXT ("%s: Initializing OpenMP tracing failed"), type); + break; + case COL_ERROR_DURATION_INIT: + text = dbe_sprintf (GTXT ("%s: Initializing experiment-duration setting to `%s' failed"), type, par); + break; + case COL_ERROR_RDTINIT: + text = dbe_sprintf (GTXT ("%s: Initializing RDT failed"), type); + break; + case COL_ERROR_GENERAL: + if (strlen (par)) + text = dbe_sprintf (GTXT ("%s: %s"), type, par); + else + text = dbe_sprintf (GTXT ("%s: General error"), type); + break; + case COL_ERROR_EXEC_FAIL: + text = dbe_sprintf (GTXT ("%s: Exec of process failed"), type); + break; + case COL_ERROR_THR_MAX: + text = dbe_sprintf (GTXT ("%s: Thread count exceeds maximum (%s); set SP_COLLECTOR_NUMTHREADS for higher value"), type, par); + break; + case COL_ERROR_IOINIT: + text = dbe_sprintf (GTXT ("%s: Initializing IO tracing failed"), type); + break; + case COL_ERROR_NODATA: + text = dbe_sprintf (GTXT ("%s: No data was recorded in the experiment"), type); + break; + case COL_ERROR_DTRACE_FATAL: + text = dbe_sprintf (GTXT ("%s: Fatal error reported from DTrace -- %s"), type, par); + break; + case COL_ERROR_MAPSEEK: + text = dbe_sprintf (GTXT ("%s: Seek error on map file `%s'"), type, par); + break; + case COL_ERROR_UNEXP_FOUNDER: + text = dbe_sprintf (GTXT ("%s: Unexpected value for founder `%s'"), type, par); + break; + case COL_ERROR_LOG_OPEN: + text = dbe_sprintf (GTXT ("%s: Failure to open log file"), type); + break; + case COL_ERROR_TSD_INIT: + text = dbe_sprintf (GTXT ("%s: TSD could not be initialized"), type); + break; + case COL_ERROR_UTIL_INIT: + text = dbe_sprintf (GTXT ("%s: libcol_util.c initialization failed"), type); + break; + case COL_ERROR_MAPCACHE: + text = dbe_sprintf (GTXT ("%s: Unable to cache mappings; internal error (`%s')"), type, par); + break; + case COL_WARN_NONE: + text = dbe_sprintf (GTXT ("%s: No warning"), type); + break; + case COL_WARN_FSTYPE: + text = dbe_sprintf (GTXT ("%s: Experiment was written to a filesystem of type `%s'; data may be distorted"), type, par); + break; + case COL_WARN_PROFRND: + text = dbe_sprintf (GTXT ("%s: Profiling interval was changed from requested %s (microsecs.) used"), type, par); + break; + case COL_WARN_SIZELIM: + text = dbe_sprintf (GTXT ("%s: Experiment size limit exceeded"), type); + break; + case COL_WARN_SIGPROF: + text = dbe_sprintf (GTXT ("%s: SIGPROF handler was changed (%s) during the run; profile data may be unreliable"), type, par); + break; + case COL_WARN_SMPLADJ: + text = dbe_sprintf (GTXT ("%s: Periodic sampling rate adjusted %s microseconds"), type, par); + break; + case COL_WARN_ITMROVR: + text = dbe_sprintf (GTXT ("%s: Application's attempt to set interval timer period to %s was ignored; its behavior may be changed"), type, par); + break; + case COL_WARN_ITMRREP: + text = dbe_sprintf (GTXT ("%s: Collection interval timer period was changed (%s); profile data may be unreliable"), type, par); + break; + case COL_WARN_SIGEMT: + text = dbe_sprintf (GTXT ("%s: SIGEMT handler was changed during the run; profile data may be unreliable"), type); + break; + case COL_WARN_CPCBLK: + text = dbe_sprintf (GTXT ("%s: libcpc access blocked for hardware counter profiling"), type); + break; + case COL_WARN_VFORK: + text = dbe_sprintf (GTXT ("%s: vfork(2) replaced by %s; execution may be affected"), type, par); + break; + case COL_WARN_EXECENV: + text = dbe_sprintf (GTXT ("%s: exec environment augmented with %s missing collection variables"), type, par); + break; + case COL_WARN_SAMPSIGUSED: + text = dbe_sprintf (GTXT ("%s: target installed handler for sample signal %s; samples may be lost"), type, par); + break; + case COL_WARN_PAUSESIGUSED: + text = dbe_sprintf (GTXT ("%s: target installed handler for pause/resume signal %s; data may be lost or unexpected"), + type, par); + break; + case COL_WARN_CPCNOTRESERVED: + text = dbe_sprintf (GTXT ("%s: unable to reserve HW counters; data may be distorted by other users of the counters"), type); + break; + case COL_WARN_LIBTHREAD_T1: /* par contains the aslwpid... do we want to report it? */ + text = dbe_sprintf (GTXT ("%s: application ran with a libthread version that may distort data; see collect(1) man page"), type); + break; + case COL_WARN_SIGMASK: + text = dbe_sprintf (GTXT ("%s: Blocking %s ignored while in use for collection"), type, par); + break; + case COL_WARN_NOFOLLOW: + text = dbe_sprintf (GTXT ("%s: Following disabled for uncollectable target (%s)"), type, par); + break; + case COL_WARN_RISKYFOLLOW: + text = dbe_sprintf (GTXT ("%s: Following unqualified target may be unreliable (%s)"), type, par); + break; + case COL_WARN_IDCHNG: + text = dbe_sprintf (GTXT ("%s: Imminent process ID change (%s) may result in an inconsistent experiment"), type, par); + break; + case COL_WARN_OLDJAVA: + text = dbe_sprintf (GTXT ("%s: Java profiling requires JVM version 1.4.2_02 or later"), type); + break; + case COL_WARN_ITMRPOVR: + text = dbe_sprintf (GTXT ("%s: Collector reset application's profile timer %s; application behavior may be changed"), type, par); + break; + case COL_WARN_NO_JAVA_HEAP: + text = dbe_sprintf (GTXT ("%s: Java heap profiling is not supported by JVMTI; disabled "), type); + break; + case COL_WARN_RDT_PAUSE_NOMEM: + text = dbe_sprintf (GTXT ("%s: Data race detection paused at %s because of running out of internal memory"), type, par); + break; + case COL_WARN_RDT_RESUME: + text = dbe_sprintf (GTXT ("%s: Data race detection resumed"), type); + break; + case COL_WARN_RDT_THROVER: + text = dbe_sprintf (GTXT ("%s: Too many concurrent/created threads; accesses with thread IDs above limit are not checked"), type); + break; + case COL_WARN_THR_PAUSE_RESUME: + text = dbe_sprintf (GTXT ("%s: The collector_thread_pause/collector_thread_resume APIs are deprecated, and will be removed in a future release"), type); + break; + case COL_WARN_NOPROF_DATA: + text = dbe_sprintf (GTXT ("%s: No profile data recorded in experiment"), type); + break; + case COL_WARN_LONG_FSTAT: + text = dbe_sprintf (GTXT ("%s: Long fstat call -- %s"), type, par); + break; + case COL_WARN_LONG_READ: + text = dbe_sprintf (GTXT ("%s: Long read call -- %s"), type, par); + break; + case COL_WARN_LINUX_X86_APICID: + text = dbe_sprintf (GTXT ("%s: Linux libc sched_getcpu() not found; using x86 %s IDs rather than CPU IDs"), type, par); + break; + + case COL_COMMENT_NONE: + text = dbe_sprintf (GTXT ("%s"), par); + break; + case COL_COMMENT_CWD: + text = dbe_sprintf (GTXT ("Initial execution directory `%s'"), par); + break; + case COL_COMMENT_ARGV: + text = dbe_sprintf (GTXT ("Argument list `%s'"), par); + break; + case COL_COMMENT_MAYASSNAP: + text = dbe_sprintf (GTXT ("Mayas snap file `%s'"), par); + break; + + case COL_COMMENT_LINEFORK: + text = dbe_sprintf (GTXT ("Target fork: %s"), par); + break; + case COL_COMMENT_LINEEXEC: + text = dbe_sprintf (GTXT ("Target exec: %s"), par); + break; + case COL_COMMENT_LINECOMBO: + text = dbe_sprintf (GTXT ("Target fork/exec: %s"), par); + break; + case COL_COMMENT_FOXSNAP: + text = dbe_sprintf (GTXT ("Fox snap file `%s'"), par); + break; + case COL_COMMENT_ROCKSNAP: + text = dbe_sprintf (GTXT ("Rock simulator snap file `%s'"), par); + break; + case COL_COMMENT_BITINSTRDATA: + text = dbe_sprintf (GTXT ("Bit instrument data file `%s'"), par); + break; + case COL_COMMENT_BITSNAP: + text = dbe_sprintf (GTXT ("Bit snap file `%s'"), par); + break; + case COL_COMMENT_SIMDSPSNAP: + text = dbe_sprintf (GTXT ("Simulator dataspace profiling snap file `%s'"), par); + break; + case COL_COMMENT_HWCADJ: + text = dbe_sprintf (GTXT ("%s: HWC overflow interval adjusted: %s"), type, par); + break; + case COL_WARN_APP_NOT_READY: + text = dbe_sprintf (GTXT ("*** Collect: %s"), par); + break; + case COL_WARN_RDT_DL_TERMINATE: + text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process terminated"), type); + break; + case COL_WARN_RDT_DL_TERMINATE_CORE: + text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process terminated and core dumped"), type); + break; + case COL_WARN_RDT_DL_CONTINUE: + text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process allowed to continue"), type); + break; + default: + text = dbe_sprintf (GTXT ("%s: Number %d (\"%s\")"), type, flavor, par); + break; + }; +} + +Emsg::~Emsg () +{ + free (par); + free (text); +} + +// ----------------------- Message Queue -------------------- +Emsgqueue::Emsgqueue (char *_qname) +{ + first = NULL; + last = NULL; + qname = strdup (_qname); +} + +Emsgqueue::~Emsgqueue () +{ + free (qname); + clear (); +} + +Emsg * +Emsgqueue::find_msg (Cmsg_warn w, char *msg) +{ + for (Emsg *m = first; m; m = m->next) + if (m->get_warn () == w && strcmp (m->get_msg (), msg) == 0) + return m; + return NULL; +} + +Emsg * +Emsgqueue::append (Cmsg_warn w, char *msg) +{ + Emsg *m = find_msg (w, msg); + if (m) + return m; + m = new Emsg (w, msg); + append (m); + return m; +} + +// Append a single message to a queue +void +Emsgqueue::append (Emsg* m) +{ + m->next = NULL; + if (last == NULL) + { + first = m; + last = m; + } + else + { + last->next = m; + last = m; + } +} + +// Append a queue of messages to a queue +void +Emsgqueue::appendqueue (Emsgqueue* mq) +{ + Emsg *m = mq->first; + if (m == NULL) + return; + if (last == NULL) + first = m; + else + last->next = m; + // now find the new last + while (m->next != NULL) + m = m->next; + last = m; +} + +Emsg * +Emsgqueue::fetch (void) +{ + return first; +} + +// Empty the queue, deleting all messages +void +Emsgqueue::clear (void) +{ + Emsg *pp; + Emsg *p = first; + while (p != NULL) + { + pp = p; + p = p->next; + delete pp; + } + first = NULL; + last = NULL; +} + +// Mark the queue empty, without deleting the messages -- +// used when the messages have been requeued somewhere else +void +Emsgqueue::mark_clear (void) +{ + first = NULL; + last = NULL; +} + +DbeMessages::DbeMessages () +{ + msgs = NULL; +} + +DbeMessages::~DbeMessages () +{ + if (msgs) + { + msgs->destroy (); + delete msgs; + } +} + +Emsg * +DbeMessages::get_error () +{ + for (int i = msgs ? msgs->size () - 1 : -1; i >= 0; i--) + { + Emsg *msg = msgs->get (i); + if (msg->get_warn () == CMSG_ERROR) + return msg; + } + return NULL; +} + +void +DbeMessages::remove_msg (Emsg *msg) +{ + for (int i = 0, sz = msgs ? msgs->size () : 0; i < sz; i++) + if (msg == msgs->get (i)) + { + msgs->remove (i); + delete msg; + return; + } +} + +Emsg * +DbeMessages::append_msg (Cmsg_warn w, const char *fmt, ...) +{ + char buffer[256]; + size_t buf_size; + Emsg *msg; + va_list vp; + + va_start (vp, fmt); + buf_size = vsnprintf (buffer, sizeof (buffer), fmt, vp) + 1; + va_end (vp); + if (buf_size < sizeof (buffer)) + msg = new Emsg (w, buffer); + else + { + va_start (vp, fmt); + char *buf = (char *) malloc (buf_size); + vsnprintf (buf, buf_size, fmt, vp); + va_end (vp); + msg = new Emsg (w, buf); + free (buf); + } + + if (msgs == NULL) + msgs = new Vector<Emsg*>(); + msgs->append (msg); + Dprintf (DEBUG_ERR_MSG, NTXT ("Warning: %s\n"), msg->get_msg ()); + return msg; +} + +void +DbeMessages::append_msgs (Vector<Emsg*> *lst) +{ + if (lst && (lst->size () != 0)) + { + if (msgs == NULL) + msgs = new Vector<Emsg*>(); + for (int i = 0, sz = lst->size (); i < sz; i++) + { + Emsg *m = lst->fetch (i); + msgs->append (new Emsg (m->get_warn (), m->get_msg ())); + } + } +} |