1/* Copyright (C) 2021 Free Software Foundation, Inc. 2 Contributed by Oracle. 3 4 This file is part of GNU Binutils. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21#include "config.h" 22#include <stdarg.h> 23 24#include "util.h" 25#include "Emsg.h" 26#include "StringBuilder.h" 27 28// The Emsg, experiment message, has as objects I18N'd messages 29// in a structure suitable for attaching to and fetching 30// from a queue of such messages. It is intended to 31// be used for collector errors, collector warnings, parser 32// errors, and er_archive errors that are encountered when 33// reading an experiment 34 35// ----------------------- Message -------------------------- 36 37Emsg::Emsg (Cmsg_warn w, const char *i18n_text) 38{ 39 warn = w; 40 flavor = 0; 41 par = NULL; 42 text = strdup (i18n_text); 43 next = NULL; 44} 45 46Emsg::Emsg (Cmsg_warn w, StringBuilder& sb) 47{ 48 warn = w; 49 flavor = 0; 50 par = NULL; 51 text = sb.toString (); 52 next = NULL; 53} 54 55Emsg::Emsg (Cmsg_warn w, int f, const char *param) 56{ 57 char *type; 58 warn = w; 59 flavor = f; 60 if (param != NULL) 61 par = dbe_strdup (param); 62 else 63 par = dbe_strdup (""); 64 next = NULL; 65 66 // determine type 67 switch (warn) 68 { 69 case CMSG_WARN: 70 type = GTXT ("*** Collector Warning"); 71 break; 72 case CMSG_ERROR: 73 type = GTXT ("*** Collector Error"); 74 break; 75 case CMSG_FATAL: 76 type = GTXT ("*** Collector Fatal Error"); 77 break; 78 case CMSG_COMMENT: 79 type = GTXT ("Comment"); 80 break; 81 case CMSG_PARSER: 82 type = GTXT ("*** Log Error"); 83 break; 84 case CMSG_ARCHIVE: 85 type = GTXT ("*** Archive Error"); 86 break; 87 default: 88 type = GTXT ("*** Internal Error"); 89 break; 90 }; 91 92 // now convert the message to its I18N'd string 93 switch (flavor) 94 { 95 case COL_ERROR_NONE: 96 text = dbe_sprintf (GTXT ("%s: No error"), type); 97 break; 98 case COL_ERROR_ARGS2BIG: 99 text = dbe_sprintf (GTXT ("%s: Data argument too long"), type); 100 break; 101 case COL_ERROR_BADDIR: 102 text = dbe_sprintf (GTXT ("%s: Bad experiment directory name"), type); 103 break; 104 case COL_ERROR_ARGS: 105 text = dbe_sprintf (GTXT ("%s: Data argument format error `%s'"), type, par); 106 break; 107 case COL_ERROR_PROFARGS: 108 text = dbe_sprintf (GTXT ("%s: [UNUSED] Bad clock-profiling argument"), type); 109 break; 110 case COL_ERROR_SYNCARGS: 111 text = dbe_sprintf (GTXT ("%s: [UNUSED] Bad synchronization tracing argument"), type); 112 break; 113 case COL_ERROR_HWCARGS: 114 text = dbe_sprintf (GTXT ("%s: Bad hardware counter profiling argument"), type); 115 break; 116 case COL_ERROR_DIRPERM: 117 text = dbe_sprintf (GTXT ("%s: Experiment directory is not writeable; check umask and permissions"), type); 118 break; 119 case COL_ERROR_NOMSACCT: 120 text = dbe_sprintf (GTXT ("%s: Turning on microstate accounting failed"), type); 121 break; 122 case COL_ERROR_PROFINIT: 123 text = dbe_sprintf (GTXT ("%s: Initializing clock-profiling failed"), type); 124 break; 125 case COL_ERROR_SYNCINIT: 126 text = dbe_sprintf (GTXT ("%s: Initializing synchronization tracing failed"), type); 127 break; 128 case COL_ERROR_HWCINIT: 129 text = dbe_sprintf (GTXT ("%s: Initializing hardware counter profiling failed -- %s"), type, par); 130 break; 131 case COL_ERROR_HWCFAIL: 132 text = dbe_sprintf (GTXT ("%s: HW counter data collection failed; likely cause is that another process preempted the counters"), type); 133 break; 134 case COL_ERROR_EXPOPEN: 135 text = dbe_sprintf (GTXT ("%s: Experiment initialization failed, %s"), type, par); 136 break; 137 case COL_ERROR_SIZELIM: 138 text = dbe_sprintf (GTXT ("%s: Experiment size limit exceeded, writing %s"), type, par); 139 break; 140 case COL_ERROR_SYSINFO: 141 text = dbe_sprintf (GTXT ("%s: system name can not be determined"), type); 142 break; 143 case COL_ERROR_OVWOPEN: 144 text = dbe_sprintf (GTXT ("%s: Can't open overview %s"), type, par); 145 break; 146 case COL_ERROR_OVWWRITE: 147 text = dbe_sprintf (GTXT ("%s: Can't write overview %s"), type, par); 148 break; 149 case COL_ERROR_OVWREAD: 150 text = dbe_sprintf (GTXT ("%s: Can't read overview data for %s"), type, par); 151 break; 152 case COL_ERROR_NOZMEM: 153 text = dbe_sprintf (GTXT ("%s: Open of /dev/zero failed: %s"), type, par); 154 break; 155 case COL_ERROR_NOZMEMMAP: 156 text = dbe_sprintf (GTXT ("%s: Mmap of /dev/zero failed: %s"), type, par); 157 break; 158 case COL_ERROR_NOHNDL: 159 text = dbe_sprintf (GTXT ("%s: Out of data handles for %s"), type, par); 160 break; 161 case COL_ERROR_FILEOPN: 162 text = dbe_sprintf (GTXT ("%s: Open failed %s"), type, par); 163 break; 164 case COL_ERROR_FILETRNC: 165 text = dbe_sprintf (GTXT ("%s: Truncate failed for file %s"), type, par); 166 break; 167 case COL_ERROR_FILEMAP: 168 text = dbe_sprintf (GTXT ("%s: Mmap failed %s"), type, par); 169 break; 170 case COL_ERROR_HEAPINIT: 171 text = dbe_sprintf (GTXT ("%s: Initializing heap tracing failed"), type); 172 break; 173 case COL_ERROR_DISPINIT: 174 text = dbe_sprintf (GTXT ("%s: Initializing SIGPROF dispatcher failed"), type); 175 break; 176 case COL_ERROR_ITMRINIT: 177 text = dbe_sprintf (GTXT ("%s: Initializing interval timer failed; %s"), type, par); 178 break; 179 case COL_ERROR_SMPLINIT: 180 text = dbe_sprintf (GTXT ("%s: Initializing periodic sampling failed"), type); 181 break; 182 case COL_ERROR_MPIINIT: 183 text = dbe_sprintf (GTXT ("%s: Initializing MPI tracing failed"), type); 184 break; 185 case COL_ERROR_JAVAINIT: 186 text = dbe_sprintf (GTXT ("%s: Initializing Java profiling failed"), type); 187 break; 188 case COL_ERROR_LINEINIT: 189 text = dbe_sprintf (GTXT ("%s: Initializing descendant process lineage failed"), type); 190 break; 191 case COL_ERROR_NOSPACE: 192 text = dbe_sprintf (GTXT ("%s: Out of disk space writing `%s'"), type, par); 193 break; 194 case COL_ERROR_ITMRRST: 195 text = dbe_sprintf (GTXT ("%s: Resetting interval timer failed: %s"), type, par); 196 break; 197 case COL_ERROR_MKDIR: 198 text = dbe_sprintf (GTXT ("%s: Unable to create directory `%s'"), type, par); 199 break; 200 case COL_ERROR_JVM2NEW: 201 text = dbe_sprintf (GTXT ("%s: JVM version with JVMTI requires more recent release of the performance tools; please upgrade"), type); 202 break; 203 case COL_ERROR_JVMNOTSUPP: 204 text = dbe_sprintf (GTXT ("%s: JVM version does not support JVMTI; no java profiling is available"), type); 205 break; 206 case COL_ERROR_JVMNOJSTACK: 207 text = dbe_sprintf (GTXT ("%s: JVM version does not support java callstacks; java mode data will not be recorded"), type); 208 break; 209 case COL_ERROR_DYNOPEN: 210 text = dbe_sprintf (GTXT ("%s: Can't open dyntext file `%s'"), type, par); 211 break; 212 case COL_ERROR_DYNWRITE: 213 text = dbe_sprintf (GTXT ("%s: Can't write dyntext file `%s'"), type, par); 214 break; 215 case COL_ERROR_MAPOPEN: 216 text = dbe_sprintf (GTXT ("%s: Can't open map file `%s'"), type, par); 217 break; 218 case COL_ERROR_MAPREAD: 219 text = dbe_sprintf (GTXT ("%s: Can't read map file `%s'"), type, par); 220 break; 221 case COL_ERROR_MAPWRITE: 222 text = dbe_sprintf (GTXT ("%s: Can't write map file"), type); 223 break; 224 case COL_ERROR_RESOLVE: 225 text = dbe_sprintf (GTXT ("%s: Can't resolve map file `%s'"), type, par); 226 break; 227 case COL_ERROR_OMPINIT: 228 text = dbe_sprintf (GTXT ("%s: Initializing OpenMP tracing failed"), type); 229 break; 230 case COL_ERROR_DURATION_INIT: 231 text = dbe_sprintf (GTXT ("%s: Initializing experiment-duration setting to `%s' failed"), type, par); 232 break; 233 case COL_ERROR_RDTINIT: 234 text = dbe_sprintf (GTXT ("%s: Initializing RDT failed"), type); 235 break; 236 case COL_ERROR_GENERAL: 237 if (strlen (par)) 238 text = dbe_sprintf (GTXT ("%s: %s"), type, par); 239 else 240 text = dbe_sprintf (GTXT ("%s: General error"), type); 241 break; 242 case COL_ERROR_EXEC_FAIL: 243 text = dbe_sprintf (GTXT ("%s: Exec of process failed"), type); 244 break; 245 case COL_ERROR_THR_MAX: 246 text = dbe_sprintf (GTXT ("%s: Thread count exceeds maximum (%s); set SP_COLLECTOR_NUMTHREADS for higher value"), type, par); 247 break; 248 case COL_ERROR_IOINIT: 249 text = dbe_sprintf (GTXT ("%s: Initializing IO tracing failed"), type); 250 break; 251 case COL_ERROR_NODATA: 252 text = dbe_sprintf (GTXT ("%s: No data was recorded in the experiment"), type); 253 break; 254 case COL_ERROR_DTRACE_FATAL: 255 text = dbe_sprintf (GTXT ("%s: Fatal error reported from DTrace -- %s"), type, par); 256 break; 257 case COL_ERROR_MAPSEEK: 258 text = dbe_sprintf (GTXT ("%s: Seek error on map file `%s'"), type, par); 259 break; 260 case COL_ERROR_UNEXP_FOUNDER: 261 text = dbe_sprintf (GTXT ("%s: Unexpected value for founder `%s'"), type, par); 262 break; 263 case COL_ERROR_LOG_OPEN: 264 text = dbe_sprintf (GTXT ("%s: Failure to open log file"), type); 265 break; 266 case COL_ERROR_TSD_INIT: 267 text = dbe_sprintf (GTXT ("%s: TSD could not be initialized"), type); 268 break; 269 case COL_ERROR_UTIL_INIT: 270 text = dbe_sprintf (GTXT ("%s: libcol_util.c initialization failed"), type); 271 break; 272 case COL_ERROR_MAPCACHE: 273 text = dbe_sprintf (GTXT ("%s: Unable to cache mappings; internal error (`%s')"), type, par); 274 break; 275 case COL_WARN_NONE: 276 text = dbe_sprintf (GTXT ("%s: No warning"), type); 277 break; 278 case COL_WARN_FSTYPE: 279 text = dbe_sprintf (GTXT ("%s: Experiment was written to a filesystem of type `%s'; data may be distorted"), type, par); 280 break; 281 case COL_WARN_PROFRND: 282 text = dbe_sprintf (GTXT ("%s: Profiling interval was changed from requested %s (microsecs.) used"), type, par); 283 break; 284 case COL_WARN_SIZELIM: 285 text = dbe_sprintf (GTXT ("%s: Experiment size limit exceeded"), type); 286 break; 287 case COL_WARN_SIGPROF: 288 text = dbe_sprintf (GTXT ("%s: SIGPROF handler was changed (%s) during the run; profile data may be unreliable"), type, par); 289 break; 290 case COL_WARN_SMPLADJ: 291 text = dbe_sprintf (GTXT ("%s: Periodic sampling rate adjusted %s microseconds"), type, par); 292 break; 293 case COL_WARN_ITMROVR: 294 text = dbe_sprintf (GTXT ("%s: Application's attempt to set interval timer period to %s was ignored; its behavior may be changed"), type, par); 295 break; 296 case COL_WARN_ITMRREP: 297 text = dbe_sprintf (GTXT ("%s: Collection interval timer period was changed (%s); profile data may be unreliable"), type, par); 298 break; 299 case COL_WARN_SIGEMT: 300 text = dbe_sprintf (GTXT ("%s: SIGEMT handler was changed during the run; profile data may be unreliable"), type); 301 break; 302 case COL_WARN_CPCBLK: 303 text = dbe_sprintf (GTXT ("%s: libcpc access blocked for hardware counter profiling"), type); 304 break; 305 case COL_WARN_VFORK: 306 text = dbe_sprintf (GTXT ("%s: vfork(2) replaced by %s; execution may be affected"), type, par); 307 break; 308 case COL_WARN_EXECENV: 309 text = dbe_sprintf (GTXT ("%s: exec environment augmented with %s missing collection variables"), type, par); 310 break; 311 case COL_WARN_SAMPSIGUSED: 312 text = dbe_sprintf (GTXT ("%s: target installed handler for sample signal %s; samples may be lost"), type, par); 313 break; 314 case COL_WARN_PAUSESIGUSED: 315 text = dbe_sprintf (GTXT ("%s: target installed handler for pause/resume signal %s; data may be lost or unexpected"), 316 type, par); 317 break; 318 case COL_WARN_CPCNOTRESERVED: 319 text = dbe_sprintf (GTXT ("%s: unable to reserve HW counters; data may be distorted by other users of the counters"), type); 320 break; 321 case COL_WARN_LIBTHREAD_T1: /* par contains the aslwpid... do we want to report it? */ 322 text = dbe_sprintf (GTXT ("%s: application ran with a libthread version that may distort data; see collect(1) man page"), type); 323 break; 324 case COL_WARN_SIGMASK: 325 text = dbe_sprintf (GTXT ("%s: Blocking %s ignored while in use for collection"), type, par); 326 break; 327 case COL_WARN_NOFOLLOW: 328 text = dbe_sprintf (GTXT ("%s: Following disabled for uncollectable target (%s)"), type, par); 329 break; 330 case COL_WARN_RISKYFOLLOW: 331 text = dbe_sprintf (GTXT ("%s: Following unqualified target may be unreliable (%s)"), type, par); 332 break; 333 case COL_WARN_IDCHNG: 334 text = dbe_sprintf (GTXT ("%s: Imminent process ID change (%s) may result in an inconsistent experiment"), type, par); 335 break; 336 case COL_WARN_OLDJAVA: 337 text = dbe_sprintf (GTXT ("%s: Java profiling requires JVM version 1.4.2_02 or later"), type); 338 break; 339 case COL_WARN_ITMRPOVR: 340 text = dbe_sprintf (GTXT ("%s: Collector reset application's profile timer %s; application behavior may be changed"), type, par); 341 break; 342 case COL_WARN_NO_JAVA_HEAP: 343 text = dbe_sprintf (GTXT ("%s: Java heap profiling is not supported by JVMTI; disabled "), type); 344 break; 345 case COL_WARN_RDT_PAUSE_NOMEM: 346 text = dbe_sprintf (GTXT ("%s: Data race detection paused at %s because of running out of internal memory"), type, par); 347 break; 348 case COL_WARN_RDT_RESUME: 349 text = dbe_sprintf (GTXT ("%s: Data race detection resumed"), type); 350 break; 351 case COL_WARN_RDT_THROVER: 352 text = dbe_sprintf (GTXT ("%s: Too many concurrent/created threads; accesses with thread IDs above limit are not checked"), type); 353 break; 354 case COL_WARN_THR_PAUSE_RESUME: 355 text = dbe_sprintf (GTXT ("%s: The collector_thread_pause/collector_thread_resume APIs are deprecated, and will be removed in a future release"), type); 356 break; 357 case COL_WARN_NOPROF_DATA: 358 text = dbe_sprintf (GTXT ("%s: No profile data recorded in experiment"), type); 359 break; 360 case COL_WARN_LONG_FSTAT: 361 text = dbe_sprintf (GTXT ("%s: Long fstat call -- %s"), type, par); 362 break; 363 case COL_WARN_LONG_READ: 364 text = dbe_sprintf (GTXT ("%s: Long read call -- %s"), type, par); 365 break; 366 case COL_WARN_LINUX_X86_APICID: 367 text = dbe_sprintf (GTXT ("%s: Linux libc sched_getcpu() not found; using x86 %s IDs rather than CPU IDs"), type, par); 368 break; 369 370 case COL_COMMENT_NONE: 371 text = dbe_sprintf (GTXT ("%s"), par); 372 break; 373 case COL_COMMENT_CWD: 374 text = dbe_sprintf (GTXT ("Initial execution directory `%s'"), par); 375 break; 376 case COL_COMMENT_ARGV: 377 text = dbe_sprintf (GTXT ("Argument list `%s'"), par); 378 break; 379 case COL_COMMENT_MAYASSNAP: 380 text = dbe_sprintf (GTXT ("Mayas snap file `%s'"), par); 381 break; 382 383 case COL_COMMENT_LINEFORK: 384 text = dbe_sprintf (GTXT ("Target fork: %s"), par); 385 break; 386 case COL_COMMENT_LINEEXEC: 387 text = dbe_sprintf (GTXT ("Target exec: %s"), par); 388 break; 389 case COL_COMMENT_LINECOMBO: 390 text = dbe_sprintf (GTXT ("Target fork/exec: %s"), par); 391 break; 392 case COL_COMMENT_FOXSNAP: 393 text = dbe_sprintf (GTXT ("Fox snap file `%s'"), par); 394 break; 395 case COL_COMMENT_ROCKSNAP: 396 text = dbe_sprintf (GTXT ("Rock simulator snap file `%s'"), par); 397 break; 398 case COL_COMMENT_BITINSTRDATA: 399 text = dbe_sprintf (GTXT ("Bit instrument data file `%s'"), par); 400 break; 401 case COL_COMMENT_BITSNAP: 402 text = dbe_sprintf (GTXT ("Bit snap file `%s'"), par); 403 break; 404 case COL_COMMENT_SIMDSPSNAP: 405 text = dbe_sprintf (GTXT ("Simulator dataspace profiling snap file `%s'"), par); 406 break; 407 case COL_COMMENT_HWCADJ: 408 text = dbe_sprintf (GTXT ("%s: HWC overflow interval adjusted: %s"), type, par); 409 break; 410 case COL_WARN_APP_NOT_READY: 411 text = dbe_sprintf (GTXT ("*** Collect: %s"), par); 412 break; 413 case COL_WARN_RDT_DL_TERMINATE: 414 text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process terminated"), type); 415 break; 416 case COL_WARN_RDT_DL_TERMINATE_CORE: 417 text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process terminated and core dumped"), type); 418 break; 419 case COL_WARN_RDT_DL_CONTINUE: 420 text = dbe_sprintf (GTXT ("%s: Actual deadlock detected; process allowed to continue"), type); 421 break; 422 default: 423 text = dbe_sprintf (GTXT ("%s: Number %d (\"%s\")"), type, flavor, par); 424 break; 425 }; 426} 427 428Emsg::~Emsg () 429{ 430 free (par); 431 free (text); 432} 433 434// ----------------------- Message Queue -------------------- 435Emsgqueue::Emsgqueue (char *_qname) 436{ 437 first = NULL; 438 last = NULL; 439 qname = strdup (_qname); 440} 441 442Emsgqueue::~Emsgqueue () 443{ 444 free (qname); 445 clear (); 446} 447 448Emsg * 449Emsgqueue::find_msg (Cmsg_warn w, char *msg) 450{ 451 for (Emsg *m = first; m; m = m->next) 452 if (m->get_warn () == w && strcmp (m->get_msg (), msg) == 0) 453 return m; 454 return NULL; 455} 456 457Emsg * 458Emsgqueue::append (Cmsg_warn w, char *msg) 459{ 460 Emsg *m = find_msg (w, msg); 461 if (m) 462 return m; 463 m = new Emsg (w, msg); 464 append (m); 465 return m; 466} 467 468// Append a single message to a queue 469void 470Emsgqueue::append (Emsg* m) 471{ 472 m->next = NULL; 473 if (last == NULL) 474 { 475 first = m; 476 last = m; 477 } 478 else 479 { 480 last->next = m; 481 last = m; 482 } 483} 484 485// Append a queue of messages to a queue 486void 487Emsgqueue::appendqueue (Emsgqueue* mq) 488{ 489 Emsg *m = mq->first; 490 if (m == NULL) 491 return; 492 if (last == NULL) 493 first = m; 494 else 495 last->next = m; 496 // now find the new last 497 while (m->next != NULL) 498 m = m->next; 499 last = m; 500} 501 502Emsg * 503Emsgqueue::fetch (void) 504{ 505 return first; 506} 507 508// Empty the queue, deleting all messages 509void 510Emsgqueue::clear (void) 511{ 512 Emsg *pp; 513 Emsg *p = first; 514 while (p != NULL) 515 { 516 pp = p; 517 p = p->next; 518 delete pp; 519 } 520 first = NULL; 521 last = NULL; 522} 523 524// Mark the queue empty, without deleting the messages -- 525// used when the messages have been requeued somewhere else 526void 527Emsgqueue::mark_clear (void) 528{ 529 first = NULL; 530 last = NULL; 531} 532 533DbeMessages::DbeMessages () 534{ 535 msgs = NULL; 536} 537 538DbeMessages::~DbeMessages () 539{ 540 if (msgs) 541 { 542 msgs->destroy (); 543 delete msgs; 544 } 545} 546 547Emsg * 548DbeMessages::get_error () 549{ 550 for (int i = msgs ? msgs->size () - 1 : -1; i >= 0; i--) 551 { 552 Emsg *msg = msgs->get (i); 553 if (msg->get_warn () == CMSG_ERROR) 554 return msg; 555 } 556 return NULL; 557} 558 559void 560DbeMessages::remove_msg (Emsg *msg) 561{ 562 for (int i = 0, sz = msgs ? msgs->size () : 0; i < sz; i++) 563 if (msg == msgs->get (i)) 564 { 565 msgs->remove (i); 566 delete msg; 567 return; 568 } 569} 570 571Emsg * 572DbeMessages::append_msg (Cmsg_warn w, const char *fmt, ...) 573{ 574 char buffer[256]; 575 size_t buf_size; 576 Emsg *msg; 577 va_list vp; 578 579 va_start (vp, fmt); 580 buf_size = vsnprintf (buffer, sizeof (buffer), fmt, vp) + 1; 581 va_end (vp); 582 if (buf_size < sizeof (buffer)) 583 msg = new Emsg (w, buffer); 584 else 585 { 586 va_start (vp, fmt); 587 char *buf = (char *) malloc (buf_size); 588 vsnprintf (buf, buf_size, fmt, vp); 589 va_end (vp); 590 msg = new Emsg (w, buf); 591 free (buf); 592 } 593 594 if (msgs == NULL) 595 msgs = new Vector<Emsg*>(); 596 msgs->append (msg); 597 Dprintf (DEBUG_ERR_MSG, NTXT ("Warning: %s\n"), msg->get_msg ()); 598 return msg; 599} 600 601void 602DbeMessages::append_msgs (Vector<Emsg*> *lst) 603{ 604 if (lst && (lst->size () != 0)) 605 { 606 if (msgs == NULL) 607 msgs = new Vector<Emsg*>(); 608 for (int i = 0, sz = lst->size (); i < sz; i++) 609 { 610 Emsg *m = lst->fetch (i); 611 msgs->append (new Emsg (m->get_warn (), m->get_msg ())); 612 } 613 } 614} 615