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 <ctype.h> 23#include <stdio.h> 24#include <dirent.h> 25#include <unistd.h> 26#include <sys/types.h> 27#include <errno.h> 28#include <sys/param.h> 29 30#include "util.h" 31#include "Application.h" 32#include "Experiment.h" 33#include "ExpGroup.h" 34#include "Expression.h" 35#include "DataObject.h" 36#include "Elf.h" 37#include "Function.h" 38#include "DbeSession.h" 39#include "LoadObject.h" 40#include "DbeSyncMap.h" 41#include "DbeThread.h" 42#include "ClassFile.h" 43#include "IndexObject.h" 44#include "PathTree.h" 45#include "Print.h" 46 47// Bison 3.0 doesn't define YY_NULLPTR. I copied this from QLParser.tab.cc. 48// Why this is not in QLParser.tab.hh ? YY_NULLPTR is used in QLParser.tab.hh 49# ifndef YY_NULLPTR 50# if defined __cplusplus && 201103L <= __cplusplus 51# define YY_NULLPTR nullptr 52# else 53# define YY_NULLPTR 0 54# endif 55# endif 56#include "QLParser.tab.hh" 57#include "DbeView.h" 58#include "MemorySpace.h" 59#include "Module.h" 60#include "SourceFile.h" 61#include "StringBuilder.h" 62#include "BaseMetric.h" 63#include "BaseMetricTreeNode.h" 64#include "Command.h" 65#include "UserLabel.h" 66#include "StringMap.h" 67#include "DbeFile.h" 68#include "DbeJarFile.h" 69#include "IOActivity.h" 70#include "HeapActivity.h" 71 72// This is a universal List structure to organize objects 73// of various types, even if different. 74struct List 75{ 76 List *next; 77 void *val; 78}; 79 80struct Countable 81{ 82 Countable (void *_item) 83 { 84 item = _item; 85 ref_count = 0; 86 } 87 88 void *item; 89 int ref_count; 90}; 91 92Platform_t DbeSession::platform = 93#if ARCH(SPARC) 94 Sparc; 95#elif ARCH(Aarch64) 96 Aarch64; 97#else // ARCH(Intel) 98 Intel; 99#endif 100 101// This constant determines the size of the data object name hash table. 102static const int HTableSize = 8192; 103static int DEFAULT_TINY_THRESHOLD = -1; 104 105unsigned int mpmt_debug_opt = 0; 106DbeSession *dbeSession = NULL; 107 108DbeSession::DbeSession (Settings *_settings, bool _ipc_mode, bool _rdt_mode) 109{ 110 dbeSession = this; 111 ipc_mode = _ipc_mode; 112 rdt_mode = _rdt_mode; 113 settings = new Settings (_settings); 114 views = new Vector<DbeView*>; 115 exps = new Vector<Experiment*>; 116 lobjs = new Vector<LoadObject*>; 117 objs = new Vector<Histable*>; 118 dobjs = new Vector<DataObject*>; 119 metrics = new Vector<Countable*>; 120 reg_metrics = new Vector<BaseMetric*>; 121 hwcentries = NULL; 122 reg_metrics_tree = NULL; // BaseMetric() requires DbeSession::ql_parse 123 idxobjs = new Vector<HashMap<uint64_t, Histable*>*>; 124 tmp_files = new Vector<char*>; 125 search_path = new Vector<char*>; 126 classpath = new Vector<char*>; 127 classpath_df = NULL; 128 expGroups = new Vector<ExpGroup*>; 129 sourcesMap = new HashMap<char*, SourceFile*>; 130 sources = new Vector<SourceFile*>; 131 comp_lobjs = new HashMap<char*, LoadObject*>; 132 comp_dbelines = new HashMap<char*, DbeLine*>; 133 comp_sources = new HashMap<char*, SourceFile*>; 134 loadObjMap = new DbeSyncMap<LoadObject>; 135 f_special = new Vector<Function*>(LastSpecialFunction); 136 omp_functions = new Vector<Function*>(OMP_LAST_STATE); 137 interactive = false; 138 lib_visibility_used = false; 139 140 // Define all known property names 141 propNames = new Vector<PropDescr*>; 142 propNames_name_store (PROP_NONE, NTXT ("")); 143 propNames_name_store (PROP_ATSTAMP, NTXT ("ATSTAMP")); 144 propNames_name_store (PROP_ETSTAMP, NTXT ("ETSTAMP")); 145 propNames_name_store (PROP_TSTAMP, NTXT ("TSTAMP")); 146 propNames_name_store (PROP_THRID, NTXT ("THRID")); 147 propNames_name_store (PROP_LWPID, NTXT ("LWPID")); 148 propNames_name_store (PROP_CPUID, NTXT ("CPUID")); 149 propNames_name_store (PROP_FRINFO, NTXT ("FRINFO")); 150 propNames_name_store (PROP_EVT_TIME, NTXT ("EVT_TIME")); 151 152 // Samples 153 propNames_name_store (PROP_SMPLOBJ, NTXT ("SMPLOBJ")); 154 propNames_name_store (PROP_SAMPLE, NTXT ("SAMPLE")); 155 156 // GCEvents 157 propNames_name_store (PROP_GCEVENTOBJ, NTXT ("GCEVENTOBJ")); 158 propNames_name_store (PROP_GCEVENT, NTXT ("GCEVENT")); 159 160 // Metadata used by some packet types 161 propNames_name_store (PROP_VOIDP_OBJ, NTXT ("VOIDP_OBJ"), 162 NULL, TYPE_UINT64, DDFLAG_NOSHOW); 163 164 // Clock profiling properties 165 propNames_name_store (PROP_UCPU, NTXT ("UCPU")); 166 propNames_name_store (PROP_SCPU, NTXT ("SCPU")); 167 propNames_name_store (PROP_TRAP, NTXT ("TRAP")); 168 propNames_name_store (PROP_TFLT, NTXT ("TFLT")); 169 propNames_name_store (PROP_DFLT, NTXT ("DFLT")); 170 propNames_name_store (PROP_KFLT, NTXT ("KFLT")); 171 propNames_name_store (PROP_ULCK, NTXT ("ULCK")); 172 propNames_name_store (PROP_TSLP, NTXT ("TSLP")); 173 propNames_name_store (PROP_WCPU, NTXT ("WCPU")); 174 propNames_name_store (PROP_TSTP, NTXT ("TSTP")); 175 176 propNames_name_store (PROP_MSTATE, NTXT ("MSTATE")); 177 propNames_name_store (PROP_NTICK, NTXT ("NTICK")); 178 propNames_name_store (PROP_OMPSTATE, NTXT ("OMPSTATE")); 179 180 // Synchronization tracing properties 181 propNames_name_store (PROP_SRQST, NTXT ("SRQST")); 182 propNames_name_store (PROP_SOBJ, NTXT ("SOBJ")); 183 184 // Hardware counter profiling properties 185 propNames_name_store (PROP_HWCTAG, NTXT ("HWCTAG")); 186 propNames_name_store (PROP_HWCINT, NTXT ("HWCINT")); 187 propNames_name_store (PROP_VADDR, NTXT ("VADDR")); 188 propNames_name_store (PROP_PADDR, NTXT ("PADDR")); 189 propNames_name_store (PROP_VIRTPC, NTXT ("VIRTPC")); 190 propNames_name_store (PROP_PHYSPC, NTXT ("PHYSPC")); 191 propNames_name_store (PROP_LWP_LGRP_HOME, NTXT ("LWP_LGRP_HOME")); 192 propNames_name_store (PROP_PS_LGRP_HOME, NTXT ("PS_LGRP_HOME")); 193 propNames_name_store (PROP_EA_PAGESIZE, NTXT ("EA_PAGESIZE")); 194 propNames_name_store (PROP_EA_LGRP, NTXT ("EA_LGRP")); 195 propNames_name_store (PROP_PC_PAGESIZE, NTXT ("PC_PAGESIZE")); 196 propNames_name_store (PROP_PC_LGRP, NTXT ("PC_LGRP")); 197 propNames_name_store (PROP_HWCDOBJ, NTXT ("HWCDOBJ")); 198 propNames_name_store (PROP_MEM_LAT, NTXT ("MEM_LAT")); 199 propNames_name_store (PROP_MEM_SRC, NTXT ("MEM_SRC")); 200 201 // Heap tracing properties 202 propNames_name_store (PROP_HTYPE, NTXT ("HTYPE")); 203 propNames_name_store (PROP_HSIZE, NTXT ("HSIZE")); 204 propNames_name_store (PROP_HVADDR, NTXT ("HVADDR")); 205 propNames_name_store (PROP_HOVADDR, NTXT ("HOVADDR")); 206 propNames_name_store (PROP_HLEAKED, NTXT ("HLEAKED"), 207 GTXT ("Leaked bytes"), TYPE_UINT64, 0); 208 propNames_name_store (PROP_HMEM_USAGE, NTXT ("HMEM_USAGE")); 209 propNames_name_store (PROP_HFREED, NTXT ("HFREED"), 210 GTXT ("Freed bytes"), TYPE_UINT64, 0); 211 propNames_name_store (PROP_HCUR_ALLOCS, NTXT ("HCUR_ALLOCS"), 212 GTXT ("Current allocations"), TYPE_INT64, 0); 213 propNames_name_store (PROP_HCUR_NET_ALLOC, NTXT ("HCUR_NET_ALLOC"), 214 NULL, TYPE_INT64, DDFLAG_NOSHOW); 215 propNames_name_store (PROP_HCUR_LEAKS, NTXT ("HCUR_LEAKS"), 216 GTXT ("Current leaks"), TYPE_UINT64, 0); 217 propNames_name_store (PROP_DDSCR_LNK, NTXT ("DDSCR_LNK"), 218 NULL, TYPE_UINT64, DDFLAG_NOSHOW); 219 220 // IO tracing properties 221 propNames_name_store (PROP_IOTYPE, NTXT ("IOTYPE")); 222 propNames_name_store (PROP_IOFD, NTXT ("IOFD")); 223 propNames_name_store (PROP_IONBYTE, NTXT ("IONBYTE")); 224 propNames_name_store (PROP_IORQST, NTXT ("IORQST")); 225 propNames_name_store (PROP_IOOFD, NTXT ("IOOFD")); 226 propNames_name_store (PROP_IOFNAME, NTXT ("IOFNAME")); 227 propNames_name_store (PROP_IOVFD, NTXT ("IOVFD")); 228 propNames_name_store (PROP_IOFSTYPE, NTXT ("IOFSTYPE")); 229 230 // omptrace raw properties 231 propNames_name_store (PROP_CPRID, NTXT ("CPRID")); 232 propNames_name_store (PROP_PPRID, NTXT ("PPRID")); 233 propNames_name_store (PROP_TSKID, NTXT ("TSKID")); 234 propNames_name_store (PROP_PTSKID, NTXT ("PTSKID")); 235 propNames_name_store (PROP_PRPC, NTXT ("PRPC")); 236 237 // Data race detection properties 238 propNames_name_store (PROP_RID, NTXT ("RID")); 239 propNames_name_store (PROP_RTYPE, NTXT ("RTYPE")); 240 propNames_name_store (PROP_LEAFPC, NTXT ("LEAFPC")); 241 propNames_name_store (PROP_RVADDR, NTXT ("RVADDR")); 242 propNames_name_store (PROP_RCNT, NTXT ("RCNT")); 243 244 // Deadlock detection properties 245 propNames_name_store (PROP_DID, NTXT ("DID")); 246 propNames_name_store (PROP_DLTYPE, NTXT ("DLTYPE")); 247 propNames_name_store (PROP_DTYPE, NTXT ("DTYPE")); 248 propNames_name_store (PROP_DVADDR, NTXT ("DVADDR")); 249 250 // Synthetic properties (queries only) 251 propNames_name_store (PROP_STACK, NTXT ("STACK")); 252 propNames_name_store (PROP_MSTACK, NTXT ("MSTACK")); 253 propNames_name_store (PROP_USTACK, NTXT ("USTACK")); 254 propNames_name_store (PROP_XSTACK, NTXT ("XSTACK")); 255 propNames_name_store (PROP_HSTACK, NTXT ("HSTACK")); 256 propNames_name_store (PROP_STACKID, NTXT ("STACKID")); 257 //propNames_name_store( PROP_CPRID, NTXT("CPRID") ); 258 //propNames_name_store( PROP_TSKID, NTXT("TSKID") ); 259 propNames_name_store (PROP_JTHREAD, NTXT ("JTHREAD"), 260 GTXT ("Java thread number"), TYPE_UINT64, 0); 261 262 propNames_name_store (PROP_LEAF, NTXT ("LEAF")); 263 propNames_name_store (PROP_DOBJ, NTXT ("DOBJ")); 264 propNames_name_store (PROP_SAMPLE_MAP, NTXT ("SAMPLE_MAP")); 265 propNames_name_store (PROP_GCEVENT_MAP, NTXT ("GCEVENT_MAP")); 266 propNames_name_store (PROP_PID, NTXT ("PID"), 267 GTXT ("Process id"), TYPE_UINT64, 0); 268 propNames_name_store (PROP_EXPID, NTXT ("EXPID"), 269 GTXT ("Experiment id"), TYPE_UINT64, DDFLAG_NOSHOW); 270 propNames_name_store (PROP_EXPID_CMP, NTXT ("EXPID_CMP"), 271 GTXT ("Comparable Experiment Id"), TYPE_UINT64, 272 DDFLAG_NOSHOW); //YXXX find better description 273 propNames_name_store (PROP_EXPGRID, NTXT ("EXPGRID"), 274 GTXT ("Comparison Group id"), TYPE_UINT64, 0); 275 propNames_name_store (PROP_PARREG, NTXT ("PARREG")); 276 propNames_name_store (PROP_TSTAMP_LO, NTXT ("TSTAMP_LO"), 277 GTXT ("Start Timestamp (nanoseconds)"), TYPE_UINT64, 0); 278 propNames_name_store (PROP_TSTAMP_HI, NTXT ("TSTAMP_HI"), 279 GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64, 0); 280 propNames_name_store (PROP_TSTAMP2, NTXT ("TSTAMP2"), 281 GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64, 282 DDFLAG_NOSHOW); 283 propNames_name_store (PROP_FREQ_MHZ, NTXT ("FREQ_MHZ"), 284 GTXT ("CPU Frequency, MHz"), TYPE_UINT32, 0); 285 propNames_name_store (PROP_NTICK_USEC, NTXT ("NTICK_USEC"), 286 GTXT ("Clock Profiling Interval, Microseconds"), 287 TYPE_UINT64, 0); 288 289 propNames_name_store (PROP_IOHEAPBYTES, NTXT ("IOHEAPBYTES")); 290 291 propNames_name_store (PROP_STACKL, NTXT ("STACKL")); 292 propNames_name_store (PROP_MSTACKL, NTXT ("MSTACKL")); 293 propNames_name_store (PROP_USTACKL, NTXT ("USTACKL")); 294 propNames_name_store (PROP_XSTACKL, NTXT ("XSTACKL")); 295 296 propNames_name_store (PROP_STACKI, NTXT ("STACKI")); 297 propNames_name_store (PROP_MSTACKI, NTXT ("MSTACKI")); 298 propNames_name_store (PROP_USTACKI, NTXT ("USTACKI")); 299 propNames_name_store (PROP_XSTACKI, NTXT ("XSTACKI")); 300 301 // Make sure predefined names are not used for dynamic properties 302 propNames_name_store (PROP_LAST, NTXT ("")); 303 304 localized_SP_UNKNOWN_NAME = GTXT ("(unknown)"); 305 306 // define Index objects 307 dyn_indxobj = new Vector<IndexObjType_t*>(); 308 dyn_indxobj_indx = 0; 309 char *s = dbe_sprintf (NTXT ("((EXPID_CMP<<%llu) | THRID)"), 310 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT); 311 indxobj_define (NTXT ("Threads"), GTXT ("Threads"), s, NULL, NULL); 312 free (s); 313 indxobj_define (NTXT ("CPUs"), GTXT ("CPUs"), NTXT ("(CPUID)"), NULL, NULL); 314 indxobj_define (NTXT ("Samples"), GTXT ("Samples"), NTXT ("(SAMPLE_MAP)"), 315 NULL, NULL); 316 indxobj_define (NTXT ("GCEvents"), GTXT ("GCEvents"), NTXT ("(GCEVENT_MAP)"), 317 NULL, NULL); 318 indxobj_define (NTXT ("Seconds"), GTXT ("Seconds"), 319 NTXT ("(TSTAMP/1000000000)"), NULL, NULL); 320 indxobj_define (NTXT ("Processes"), GTXT ("Processes"), NTXT ("(EXPID_CMP)"), 321 NULL, NULL); 322 s = dbe_sprintf (NTXT ("((EXPGRID<<%llu) | (EXPID<<%llu))"), 323 (unsigned long long) IndexObject::INDXOBJ_EXPGRID_SHIFT, 324 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT); 325 indxobj_define (NTXT ("Experiment_IDs"), GTXT ("Experiment_IDs"), s, NULL, NULL); 326 free (s); 327 indxobj_define (NTXT ("Datasize"), GTXT ("Datasize"), 328 "(IOHEAPBYTES==0?0:" 329 "((IOHEAPBYTES<=(1<<0)?(1<<0):" 330 "((IOHEAPBYTES<=(1<<2)?(1<<2):" 331 "((IOHEAPBYTES<=(1<<4)?(1<<4):" 332 "((IOHEAPBYTES<=(1<<6)?(1<<6):" 333 "((IOHEAPBYTES<=(1<<8)?(1<<8):" 334 "((IOHEAPBYTES<=(1<<10)?(1<<10):" 335 "((IOHEAPBYTES<=(1<<12)?(1<<12):" 336 "((IOHEAPBYTES<=(1<<14)?(1<<14):" 337 "((IOHEAPBYTES<=(1<<16)?(1<<16):" 338 "((IOHEAPBYTES<=(1<<18)?(1<<18):" 339 "((IOHEAPBYTES<=(1<<20)?(1<<20):" 340 "((IOHEAPBYTES<=(1<<22)?(1<<22):" 341 "((IOHEAPBYTES<=(1<<24)?(1<<24):" 342 "((IOHEAPBYTES<=(1<<26)?(1<<26):" 343 "((IOHEAPBYTES<=(1<<28)?(1<<28):" 344 "((IOHEAPBYTES<=(1<<30)?(1<<30):" 345 "((IOHEAPBYTES<=(1<<32)?(1<<32):" 346 "((IOHEAPBYTES<=(1<<34)?(1<<34):" 347 "((IOHEAPBYTES<=(1<<36)?(1<<36):" 348 "((IOHEAPBYTES<=(1<<38)?(1<<38):" 349 "((IOHEAPBYTES<=(1<<40)?(1<<40):" 350 "((IOHEAPBYTES<=(1<<42)?(1<<42):" 351 "((IOHEAPBYTES<=(1<<44)?(1<<44):" 352 "((IOHEAPBYTES<=(1<<46)?(1<<46):" 353 "((IOHEAPBYTES<=(1<<48)?(1<<48):" 354 "((IOHEAPBYTES<=(1<<50)?(1<<50):" 355 "(IOHEAPBYTES==-1?-1:(1<<50|1)" 356 "))))))))))))))))))))))))))))))))))))))))))))))))))))))", 357 NULL, NULL); 358 indxobj_define (NTXT ("Duration"), GTXT ("Duration"), 359 "((TSTAMP_HI-TSTAMP_LO)==0?0:" 360 "(((TSTAMP_HI-TSTAMP_LO)<=1000?1000:" 361 "(((TSTAMP_HI-TSTAMP_LO)<=10000?10000:" 362 "(((TSTAMP_HI-TSTAMP_LO)<=100000?100000:" 363 "(((TSTAMP_HI-TSTAMP_LO)<=1000000?1000000:" 364 "(((TSTAMP_HI-TSTAMP_LO)<=10000000?10000000:" 365 "(((TSTAMP_HI-TSTAMP_LO)<=100000000?100000000:" 366 "(((TSTAMP_HI-TSTAMP_LO)<=1000000000?1000000000:" 367 "(((TSTAMP_HI-TSTAMP_LO)<=10000000000?10000000000:" 368 "(((TSTAMP_HI-TSTAMP_LO)<=100000000000?100000000000:" 369 "(((TSTAMP_HI-TSTAMP_LO)<=1000000000000?1000000000000:" 370 "(((TSTAMP_HI-TSTAMP_LO)<=10000000000000?10000000000000:" 371 "(10000000000001))))))))))))))))))))))))", NULL, NULL); 372 dyn_indxobj_indx_fixed = dyn_indxobj_indx; 373 Elf::elf_init (); 374 defExpName = NULL; 375 mach_model_loaded = NULL; 376 tmp_dir_name = NULL; 377 settings->read_rc (ipc_mode || rdt_mode); 378 379 init (); 380} 381 382DbeSession::~DbeSession () 383{ 384 Destroy (views); 385 Destroy (exps); 386 Destroy (dobjs); 387 Destroy (metrics); 388 Destroy (search_path); 389 Destroy (classpath); 390 Destroy (propNames); 391 Destroy (expGroups); 392 Destroy (userLabels); 393 if (hwcentries) 394 { 395 for (long i = 0, sz = hwcentries->size (); i < sz; i++) 396 { 397 Hwcentry *h = hwcentries->get (i); 398 free (h->int_name); 399 free (h->name); 400 delete h; 401 } 402 delete hwcentries; 403 } 404 405 if (idxobjs) 406 { 407 for (int i = 0; i < idxobjs->size (); ++i) 408 { 409 HashMap<uint64_t, Histable*> *hMap = idxobjs->get (i); 410 if (hMap) 411 { 412 hMap->values ()->destroy (); 413 delete hMap; 414 } 415 } 416 delete idxobjs; 417 } 418 419 for (int i = 0; i < HTableSize; i++) 420 { 421 List *list = dnameHTable[i]; 422 while (list) 423 { 424 List *tmp = list; 425 list = list->next; 426 delete tmp; 427 } 428 } 429 delete[] dnameHTable; 430 delete classpath_df; 431 Destroy (objs); 432 Destroy (reg_metrics); 433 Destroy (dyn_indxobj); 434 delete lobjs; 435 delete f_special; 436 destroy_map (DbeFile *, dbeFiles); 437 destroy_map (DbeJarFile *, dbeJarFiles); 438 delete loadObjMap; 439 delete omp_functions; 440 delete sourcesMap; 441 delete sources; 442 delete comp_lobjs; 443 delete comp_dbelines; 444 delete comp_sources; 445 delete reg_metrics_tree; 446 delete settings; 447 free (mach_model_loaded); 448 449 if (defExpName != NULL) 450 { 451 StringBuilder *sb = new StringBuilder (); 452 sb->append (NTXT ("/bin/rm -rf ")); 453 sb->append (defExpName); 454 char *cmd = sb->toString (); 455 system (cmd); 456 free (cmd); 457 delete sb; 458 free (defExpName); 459 } 460 unlink_tmp_files (); 461 delete tmp_files; 462 dbeSession = NULL; 463} 464 465void 466DbeSession::unlink_tmp_files () 467{ 468 if (tmp_files) 469 { 470 for (int i = 0, sz = tmp_files->size (); i < sz; i++) 471 unlink (tmp_files->fetch (i)); 472 tmp_files->destroy (); 473 delete tmp_files; 474 tmp_files = NULL; 475 } 476 if (tmp_dir_name) 477 { 478 char *cmd = dbe_sprintf (NTXT ("/bin/rm -rf %s"), tmp_dir_name); 479 system (cmd); 480 free (cmd); 481 free (tmp_dir_name); 482 tmp_dir_name = NULL; 483 } 484} 485 486char * 487DbeSession::get_tmp_file_name (const char *nm, bool for_java) 488{ 489 if (tmp_dir_name == NULL) 490 { 491 tmp_dir_name = dbe_sprintf (NTXT ("/tmp/analyzer.%llu.%lld"), 492 (unsigned long long) getuid (), (long long) getpid ()); 493 mkdir (tmp_dir_name, S_IRWXU); 494 } 495 char *fnm = dbe_sprintf (NTXT ("%s/%s"), tmp_dir_name, nm); 496 if (for_java) 497 for (char *s = fnm + strlen (tmp_dir_name) + 1; *s; s++) 498 if (*s == '/') 499 *s = '.'; 500 return fnm; 501} 502 503void 504DbeSession::init () 505{ 506 user_exp_id_counter = 0; 507 status_ompavail = 0; 508 archive_mode = 0; 509 510#if DEBUG 511 char *s = getenv (NTXT ("MPMT_DEBUG")); 512 if (s) 513 mpmt_debug_opt = atoi (s); 514#endif /* DEBUG */ 515 dbeFiles = new StringMap<DbeFile*>(); 516 dbeJarFiles = new StringMap<DbeJarFile*>(128, 128); 517 518 // set up the initial (after .rc file reading) search path 519 set_search_path (settings->str_search_path, true); 520 userLabels = NULL; 521 522 // Preset all objects as they may reuse each other 523 lo_unknown = NULL; 524 f_unknown = NULL; 525 j_unknown = NULL; 526 lo_total = NULL; 527 sf_unknown = NULL; 528 f_total = NULL; 529 f_jvm = NULL; 530 d_total = NULL; 531 d_scalars = NULL; 532 d_unknown = NULL; 533 expGroups->destroy (); 534 f_special->reset (); 535 for (int i = 0; i < LastSpecialFunction; i++) 536 f_special->append (NULL); 537 538 lo_omp = NULL; 539 omp_functions->reset (); 540 for (int i = 0; i < OMP_LAST_STATE; i++) 541 omp_functions->append (NULL); 542 543 // make sure the metric list is initialized 544 register_metric (Metric::SIZES); 545 register_metric (Metric::ADDRESS); 546 register_metric (Metric::ONAME); 547 548 // This is needed only to maintain loadobject id's 549 // for <Total> and <Unknown> in tests 550 (void) get_Unknown_LoadObject (); 551 (void) get_Total_LoadObject (); 552 553 // Create the data object name hash table. 554 dnameHTable = new List*[HTableSize]; 555 for (int i = 0; i < HTableSize; i++) 556 dnameHTable[i] = NULL; 557 558 d_total = createDataObject (); 559 d_total->set_name (NTXT ("<Total>")); 560 561 // XXXX <Scalars> only appropriate for Program/Data-oriented analyses 562 d_scalars = createDataObject (); 563 d_scalars->set_name (GTXT ("<Scalars>")); 564 565 d_unknown = createDataObject (); 566 d_unknown->set_name (GTXT ("<Unknown>")); 567 568 // assign d_unknown's children so data_olayout has consistent sorting 569 for (unsigned pp_code = 1; pp_code < NUM_ABS_PP_CODES + 2; pp_code++) 570 { 571 char *errcode; 572 DataObject* dobj = createDataObject (); 573 switch (pp_code) 574 { 575 case NUM_ABS_PP_CODES + 1: 576 errcode = PTXT (DOBJ_UNDETERMINED); 577 break; 578 case NUM_ABS_PP_CODES: 579 errcode = PTXT (DOBJ_UNSPECIFIED); 580 break; 581 case NUM_ABS_PP_CODES - 1: 582 errcode = PTXT (DOBJ_UNIDENTIFIED); 583 break; 584 default: 585 errcode = PTXT (ABS_PP_CODES[pp_code]); 586 } 587 dobj->parent = d_unknown; 588 dobj->set_dobjname (errcode, NULL); // dobj->parent must already be set 589 } 590 591 for (unsigned rt_code = 1; rt_code < NUM_ABS_RT_CODES - 1; rt_code++) 592 { 593 DataObject* dobj = createDataObject (); 594 dobj->parent = d_unknown; 595 dobj->set_dobjname (PTXT (ABS_RT_CODES[rt_code]), NULL); // dobj->parent must already be set 596 } 597} 598 599void 600DbeSession::reset_data () 601{ 602 for (long i = 0, sz = VecSize (idxobjs); i < sz; ++i) 603 if (idxobjs->get (i)) 604 idxobjs->get (i)->reset (); 605} 606 607void 608DbeSession::reset () 609{ 610 loadObjMap->reset (); 611 DbeView *dbev; 612 int index; 613 614 Vec_loop (DbeView*, views, index, dbev) 615 { 616 dbev->reset (); 617 } 618 619 destroy_map (DbeFile *, dbeFiles); 620 destroy_map (DbeJarFile *, dbeJarFiles); 621 exps->destroy (); 622 lobjs->reset (); // all LoadObjects belong to objs 623 dobjs->destroy (); // deletes d_unknown and d_total as well 624 objs->destroy (); 625 comp_lobjs->clear (); 626 comp_dbelines->clear (); 627 comp_sources->clear (); 628 sourcesMap->clear (); 629 sources->reset (); 630 631 // Delete the data object name hash table. 632 for (int i = 0; i < HTableSize; i++) 633 { 634 List *list = dnameHTable[i]; 635 while (list) 636 { 637 List *tmp = list; 638 list = list->next; 639 delete tmp; 640 } 641 } 642 delete[] dnameHTable; 643 644 // IndexObect definitions remain, objects themselves may go 645 for (int i = 0; i < idxobjs->size (); ++i) 646 { 647 HashMap<uint64_t, Histable*> *v = idxobjs->fetch (i); 648 if (v != NULL) 649 { 650 v->values ()->destroy (); 651 v->clear (); 652 } 653 } 654 init (); 655} 656 657Vector<SourceFile*> * 658DbeSession::get_sources () 659{ 660 return sources; 661} 662 663DbeFile * 664DbeSession::getDbeFile (char *filename, int filetype) 665{ 666 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeSession::getDbeFile filetype=0x%x %s\n"), filetype, filename); 667 if (strncmp (filename, NTXT ("./"), 2) == 0) 668 filename += 2; 669 DbeFile *dbeFile = dbeFiles->get (filename); 670 if (dbeFile == NULL) 671 { 672 dbeFile = new DbeFile (filename); 673 dbeFiles->put (filename, dbeFile); 674 } 675 dbeFile->filetype |= filetype; 676 return dbeFile; 677} 678 679LoadObject * 680DbeSession::get_Total_LoadObject () 681{ 682 if (lo_total == NULL) 683 { 684 lo_total = createLoadObject (NTXT ("<Total>")); 685 lo_total->dbeFile->filetype |= DbeFile::F_FICTION; 686 } 687 return lo_total; 688} 689 690Function * 691DbeSession::get_Total_Function () 692{ 693 if (f_total == NULL) 694 { 695 f_total = createFunction (); 696 f_total->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET; 697 f_total->set_name (NTXT ("<Total>")); 698 Module *mod = get_Total_LoadObject ()->noname; 699 f_total->module = mod; 700 mod->functions->append (f_total); 701 } 702 return f_total; 703} 704 705LoadObject * 706DbeSession::get_Unknown_LoadObject () 707{ 708 if (lo_unknown == NULL) 709 { 710 lo_unknown = createLoadObject (GTXT ("<Unknown>")); 711 lo_unknown->type = LoadObject::SEG_TEXT; // makes it expandable 712 lo_unknown->dbeFile->filetype |= DbeFile::F_FICTION; 713 714 // force creation of the <Unknown> function 715 (void) get_Unknown_Function (); 716 } 717 return lo_unknown; 718} 719 720SourceFile * 721DbeSession::get_Unknown_Source () 722{ 723 if (sf_unknown == NULL) 724 { 725 sf_unknown = createSourceFile (localized_SP_UNKNOWN_NAME); 726 sf_unknown->dbeFile->filetype |= DbeFile::F_FICTION; 727 sf_unknown->flags |= SOURCE_FLAG_UNKNOWN; 728 } 729 return sf_unknown; 730} 731 732Function * 733DbeSession::get_Unknown_Function () 734{ 735 if (f_unknown == NULL) 736 { 737 f_unknown = createFunction (); 738 f_unknown->flags |= FUNC_FLAG_SIMULATED; 739 f_unknown->set_name (GTXT ("<Unknown>")); 740 Module *mod = get_Unknown_LoadObject ()->noname; 741 f_unknown->module = mod; 742 mod->functions->append (f_unknown); 743 } 744 return f_unknown; 745} 746 747// LIBRARY_VISIBILITY 748 749Function * 750DbeSession::create_hide_function (LoadObject *lo) 751{ 752 Function *h_function = createFunction (); 753 h_function->set_name (lo->get_name ()); 754 h_function->module = lo->noname; 755 h_function->isHideFunc = true; 756 lo->noname->functions->append (h_function); 757 return h_function; 758} 759 760Function * 761DbeSession::get_JUnknown_Function () 762{ 763 if (j_unknown == NULL) 764 { 765 j_unknown = createFunction (); 766 j_unknown->flags |= FUNC_FLAG_SIMULATED; 767 j_unknown->set_name (GTXT ("<no Java callstack recorded>")); 768 Module *mod = get_Unknown_LoadObject ()->noname; 769 j_unknown->module = mod; 770 mod->functions->append (j_unknown); 771 } 772 return j_unknown; 773} 774 775Function * 776DbeSession::get_jvm_Function () 777{ 778 if (f_jvm == NULL) 779 { 780 f_jvm = createFunction (); 781 f_jvm->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET; 782 f_jvm->set_name (GTXT ("<JVM-System>")); 783 784 // Find the JVM LoadObject 785 LoadObject *jvm = get_Unknown_LoadObject (); 786 for (int i = 0; i < lobjs->size (); ++i) 787 { 788 LoadObject *lo = lobjs->fetch (i); 789 if (lo->flags & SEG_FLAG_JVM) 790 { 791 jvm = lo; 792 break; 793 } 794 } 795 Module *mod = jvm->noname; 796 f_jvm->module = mod; 797 mod->functions->append (f_jvm); 798 // XXXX is it required? no consistency among all special functions 799 // jvm->functions->append( f_jvm ); 800 } 801 return f_jvm; 802} 803 804Function * 805DbeSession::getSpecialFunction (SpecialFunction kind) 806{ 807 if (kind < 0 || kind >= LastSpecialFunction) 808 return NULL; 809 810 Function *func = f_special->fetch (kind); 811 if (func == NULL) 812 { 813 char *fname; 814 switch (kind) 815 { 816 case TruncatedStackFunc: 817 fname = GTXT ("<Truncated-stack>"); 818 break; 819 case FailedUnwindFunc: 820 fname = GTXT ("<Stack-unwind-failed>"); 821 break; 822 default: 823 return NULL; 824 } 825 func = createFunction (); 826 func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET; 827 Module *mod = get_Total_LoadObject ()->noname; 828 func->module = mod; 829 mod->functions->append (func); 830 func->set_name (fname); 831 f_special->store (kind, func); 832 } 833 return func; 834} 835 836LoadObject * 837DbeSession::get_OMP_LoadObject () 838{ 839 if (lo_omp == NULL) 840 { 841 for (int i = 0, sz = lobjs->size (); i < sz; i++) 842 { 843 LoadObject *lo = lobjs->fetch (i); 844 if (lo->flags & SEG_FLAG_OMP) 845 { 846 lo_omp = lo; 847 return lo_omp; 848 } 849 } 850 lo_omp = createLoadObject (GTXT ("<OMP>")); 851 lo_omp->type = LoadObject::SEG_TEXT; 852 lo_omp->dbeFile->filetype |= DbeFile::F_FICTION; 853 } 854 return lo_omp; 855} 856 857Function * 858DbeSession::get_OMP_Function (int n) 859{ 860 if (n < 0 || n >= OMP_LAST_STATE) 861 return NULL; 862 863 Function *func = omp_functions->fetch (n); 864 if (func == NULL) 865 { 866 char *fname; 867 switch (n) 868 { 869 case OMP_OVHD_STATE: 870 fname = GTXT ("<OMP-overhead>"); 871 break; 872 case OMP_IDLE_STATE: 873 fname = GTXT ("<OMP-idle>"); 874 break; 875 case OMP_RDUC_STATE: 876 fname = GTXT ("<OMP-reduction>"); 877 break; 878 case OMP_IBAR_STATE: 879 fname = GTXT ("<OMP-implicit_barrier>"); 880 break; 881 case OMP_EBAR_STATE: 882 fname = GTXT ("<OMP-explicit_barrier>"); 883 break; 884 case OMP_LKWT_STATE: 885 fname = GTXT ("<OMP-lock_wait>"); 886 break; 887 case OMP_CTWT_STATE: 888 fname = GTXT ("<OMP-critical_section_wait>"); 889 break; 890 case OMP_ODWT_STATE: 891 fname = GTXT ("<OMP-ordered_section_wait>"); 892 break; 893 case OMP_ATWT_STATE: 894 fname = GTXT ("<OMP-atomic_wait>"); 895 break; 896 default: 897 return NULL; 898 } 899 func = createFunction (); 900 func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET; 901 func->set_name (fname); 902 903 LoadObject *omp = get_OMP_LoadObject (); 904 func->module = omp->noname; 905 omp->noname->functions->append (func); 906 omp->functions->append (func); 907 omp_functions->store (n, func); 908 } 909 return func; 910} 911 912// Divide the original createExperiment() into two steps 913// In part1, we just create the data structure, in part2, if 914// we decide to keep the experiment around, add it to various 915// lists in DbeSession 916Experiment * 917DbeSession::createExperimentPart1 () 918{ 919 Experiment *exp = new Experiment (); 920 return exp; 921} 922 923void 924DbeSession::createExperimentPart2 (Experiment *exp) 925{ 926 int ind = expGroups->size (); 927 if (ind > 0) 928 { 929 ExpGroup *gr = expGroups->fetch (ind - 1); 930 exp->groupId = gr->groupId; 931 gr->append (exp); 932 } 933 exp->setExpIdx (exps->size ()); 934 exp->setUserExpId (++user_exp_id_counter); 935 exps->append (exp); 936} 937 938Experiment * 939DbeSession::createExperiment () 940{ 941 Experiment *exp = new Experiment (); 942 append (exp); 943 return exp; 944} 945 946void 947DbeSession::append (Experiment *exp) 948{ 949 exp->setExpIdx (exps->size ()); 950 exp->setUserExpId (++user_exp_id_counter); 951 exps->append (exp); 952 if (exp->founder_exp) 953 { 954 if (exp->founder_exp->children_exps == NULL) 955 exp->founder_exp->children_exps = new Vector<Experiment *>; 956 exp->founder_exp->children_exps->append (exp); 957 if (exp->founder_exp->groupId > 0) 958 { 959 exp->groupId = exp->founder_exp->groupId; 960 expGroups->get (exp->groupId - 1)->append (exp); 961 } 962 } 963 if (exp->groupId == 0) 964 { 965 long ind = VecSize (expGroups); 966 if (ind > 0) 967 { 968 ExpGroup *gr = expGroups->get (ind - 1); 969 exp->groupId = gr->groupId; 970 gr->append (exp); 971 } 972 } 973} 974 975void 976DbeSession::append (Hwcentry *h) 977{ 978 if (hwcentries == NULL) 979 hwcentries = new Vector<Hwcentry*>; 980 hwcentries->append (h); 981} 982 983int 984DbeSession::ngoodexps () 985{ 986 return exps->size (); 987} 988 989int 990DbeSession::createView (int index, int cloneindex) 991{ 992 // ensure that there is no view with that index 993 DbeView *dbev = getView (index); 994 if (dbev != NULL) 995 abort (); 996 997 // find the view to be cloned 998 dbev = getView (cloneindex); 999 DbeView *newview; 1000 if (dbev == NULL) 1001 newview = new DbeView (theApplication, settings, index); 1002 else 1003 newview = new DbeView (dbev, index); 1004 views->append (newview); 1005 return index; 1006} 1007 1008DbeView * 1009DbeSession::getView (int index) 1010{ 1011 int i; 1012 DbeView *dbev; 1013 Vec_loop (DbeView*, views, i, dbev) 1014 { 1015 if (dbev->vindex == index) 1016 return dbev; 1017 } 1018 return NULL; 1019} 1020 1021void 1022DbeSession::dropView (int index) 1023{ 1024 int i; 1025 DbeView *dbev; 1026 1027 Vec_loop (DbeView*, views, i, dbev) 1028 { 1029 if (dbev->vindex == index) 1030 { 1031 views->remove (i); 1032 delete dbev; 1033 return; 1034 } 1035 } 1036 // view not found; ignore for now 1037} 1038 1039Vector<char*> * 1040DbeSession::get_group_or_expt (char *path) 1041{ 1042 Vector<char*> *exp_list = new Vector<char*>; 1043 FILE *fptr; 1044 char *new_path, buf[MAXPATHLEN], name[MAXPATHLEN]; 1045 1046 fptr = fopen (path, NTXT ("r")); 1047 if (!fptr || !fgets (buf, (int) sizeof (buf), fptr) 1048 || strncmp (buf, SP_GROUP_HEADER, strlen (SP_GROUP_HEADER))) 1049 { 1050 // it's not an experiment group 1051 new_path = dbe_strdup (path); 1052 new_path = canonical_path (new_path); 1053 exp_list->append (new_path); 1054 } 1055 else 1056 { 1057 // it is an experiment group, read the list to get them all 1058 while (fgets (buf, (int) sizeof (buf), fptr)) 1059 { 1060 if ((*buf != '#') && (sscanf (buf, NTXT ("%s"), name) == 1)) 1061 { 1062 new_path = dbe_strdup (name); 1063 new_path = canonical_path (new_path); 1064 exp_list->append (new_path); 1065 } 1066 } 1067 } 1068 if (fptr) 1069 fclose (fptr); 1070 return exp_list; 1071} 1072 1073#define GET_INT_VAL(v, s, len) \ 1074 for (v = len = 0; isdigit(*s); s++, len++) { v = v * 10 + (*s -'0'); } 1075 1076static int 1077dir_name_cmp (const void *a, const void *b) 1078{ 1079 char *s1 = *((char **) a); 1080 char *s2 = *((char **) b); 1081 while (*s1) 1082 { 1083 if (isdigit (*s1) && isdigit (*s2)) 1084 { 1085 int v1, v2, len1, len2; 1086 GET_INT_VAL (v1, s1, len1); 1087 GET_INT_VAL (v2, s2, len2); 1088 if (v1 != v2) 1089 return v1 - v2; 1090 if (len1 != len2) 1091 return len2 - len1; 1092 continue; 1093 } 1094 if (*s1 != *s2) 1095 break; 1096 s1++; 1097 s2++; 1098 } 1099 return *s1 - *s2; 1100} 1101 1102static int 1103read_experiment_data_in_parallel (void *arg) 1104{ 1105 exp_ctx *ctx = (exp_ctx *) arg; 1106 Experiment *dexp = ctx->exp; 1107 bool read_ahead = ctx->read_ahead; 1108 dexp->read_experiment_data (read_ahead); 1109 free (ctx); 1110 return 0; 1111} 1112 1113void 1114DbeSession::open_experiment (Experiment *exp, char *path) 1115{ 1116 exp->open (path); 1117 if (exp->get_status () != Experiment::FAILURE) 1118 exp->read_experiment_data (false); 1119 exp->open_epilogue (); 1120 1121 // Update all DbeViews 1122 for (int i = 0, sz = views->size (); i < sz; i++) 1123 { 1124 DbeView *dbev = views->fetch (i); 1125 dbev->add_experiment (exp->getExpIdx (), true); 1126 } 1127 1128 if (exp->get_status () == Experiment::FAILURE) 1129 { 1130 check_tab_avail (); 1131 return; 1132 } 1133 1134 char *discard_tiny = getenv (NTXT ("SP_ANALYZER_DISCARD_TINY_EXPERIMENTS")); 1135 int user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD; // in milliseconds 1136 if (discard_tiny != NULL) 1137 { 1138 user_specified_tiny_threshold = (atoi (discard_tiny)); 1139 if (user_specified_tiny_threshold < 0) 1140 user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD; 1141 } 1142 1143 // Open descendant experiments 1144 DIR *exp_dir = opendir (path); 1145 if (exp_dir == NULL) 1146 { 1147 check_tab_avail (); 1148 return; 1149 } 1150 1151 Vector<char*> *exp_names = new Vector<char*>(); 1152 struct dirent *entry = NULL; 1153 while ((entry = readdir (exp_dir)) != NULL) 1154 { 1155 if (entry->d_name[0] != '_') 1156 continue; 1157 size_t len = strlen (entry->d_name); 1158 if (len < 3 || strcmp (entry->d_name + len - 3, NTXT (".er")) != 0) 1159 continue; 1160 exp_names->append (dbe_strdup (entry->d_name)); 1161 } 1162 closedir (exp_dir); 1163 exp_names->sort (dir_name_cmp); 1164 Experiment **t_exp_list = new Experiment *[exp_names->size ()]; 1165 int nsubexps = 0; 1166 1167 for (int j = 0, jsz = exp_names->size (); j < jsz; j++) 1168 { 1169 t_exp_list[j] = NULL; 1170 1171 char *lineage_name = exp_names->fetch (j); 1172 struct stat64 sbuf; 1173 char *dpath = dbe_sprintf (NTXT ("%s/%s"), path, lineage_name); 1174 1175 // look for experiments with no profile collected 1176 if (user_specified_tiny_threshold == DEFAULT_TINY_THRESHOLD) 1177 { 1178 char *frinfoname = dbe_sprintf (NTXT ("%s/%s"), dpath, "data." SP_FRINFO_FILE); 1179 int st = dbe_stat (frinfoname, &sbuf); 1180 free (frinfoname); 1181 if (st == 0) 1182 { 1183 // if no profile/trace data do not process this experiment any further 1184 if (sbuf.st_size == 0) 1185 { 1186 free (dpath); 1187 continue; 1188 } 1189 } 1190 } 1191 else 1192 { // check if dpath is a directory 1193 if (dbe_stat (dpath, &sbuf) != 0) 1194 { 1195 free (dpath); 1196 continue; 1197 } 1198 else if (!S_ISDIR (sbuf.st_mode)) 1199 { 1200 free (dpath); 1201 continue; 1202 } 1203 } 1204 size_t lineage_name_len = strlen (lineage_name); 1205 lineage_name[lineage_name_len - 3] = 0; /* remove .er */ 1206 Experiment *dexp = new Experiment (); 1207 dexp->founder_exp = exp; 1208 if (user_specified_tiny_threshold > DEFAULT_TINY_THRESHOLD) 1209 { 1210 dexp->setTinyThreshold (user_specified_tiny_threshold); 1211 dexp->open (dpath); 1212 if (dexp->isDiscardedTinyExperiment ()) 1213 { 1214 delete dexp; 1215 free (dpath); 1216 continue; 1217 } 1218 } 1219 else 1220 dexp->open (dpath); 1221 append (dexp); 1222 t_exp_list[j] = dexp; 1223 nsubexps++; 1224 dexp->set_clock (exp->clock); 1225 1226 // DbeView add_experiment() is split into two parts 1227 // add_subexperiment() is called repeeatedly for 1228 // all sub_experiments, later add_experiment_epilogue() finishes up the task 1229 for (int i = 0, sz = views->size (); i < sz; i++) 1230 { 1231 DbeView *dbev = views->fetch (i); 1232 bool enabled = settings->check_en_desc (lineage_name, dexp->utargname); 1233 dbev->add_subexperiment (dexp->getExpIdx (), enabled); 1234 } 1235 free (dpath); 1236 } 1237 1238 for (int i = 0, sz = views->size (); i < sz; i++) 1239 { 1240 DbeView *dbev = views->fetch (i); 1241 dbev->add_experiment_epilogue (); 1242 } 1243 1244 DbeThreadPool * threadPool = new DbeThreadPool (-1); 1245 for (int j = 0, jsz = exp_names->size (); j < jsz; j++) 1246 { 1247 if (t_exp_list[j] == NULL) continue; 1248 Experiment *dexp = t_exp_list[j]; 1249 exp_ctx *new_ctx = (exp_ctx*) malloc (sizeof (exp_ctx)); 1250 new_ctx->path = NULL; 1251 new_ctx->exp = dexp; 1252 new_ctx->ds = this; 1253 new_ctx->read_ahead = true; 1254 DbeQueue *q = new DbeQueue (read_experiment_data_in_parallel, new_ctx); 1255 threadPool->put_queue (q); 1256 } 1257 threadPool->wait_queues (); 1258 delete threadPool; 1259 1260 for (long j = 0, jsz = exp_names->size (); j < jsz; j++) 1261 { 1262 if (t_exp_list[j] == NULL) continue; 1263 Experiment *dexp = t_exp_list[j]; 1264 dexp->open_epilogue (); 1265 } 1266 exp_names->destroy (); 1267 delete[] t_exp_list; 1268 delete exp_names; 1269 1270 // update setting for leaklist and dataspace 1271 check_tab_avail (); 1272} 1273 1274void 1275DbeSession::append_mesgs (StringBuilder *sb, char *path, Experiment *exp) 1276{ 1277 if (exp->fetch_errors () != NULL) 1278 { 1279 // yes, there were errors 1280 char *ststr = pr_mesgs (exp->fetch_errors (), NTXT (""), NTXT ("")); 1281 sb->append (path); 1282 sb->append (NTXT (": ")); 1283 sb->append (ststr); 1284 free (ststr); 1285 } 1286 1287 Emsg *m = exp->fetch_warnings (); 1288 if (m != NULL) 1289 { 1290 sb->append (path); 1291 sb->append (NTXT (": ")); 1292 if (!is_interactive ()) 1293 sb->append (GTXT ("Experiment has warnings, see header for details\n")); 1294 else 1295 sb->append (GTXT ("Experiment has warnings, see experiment panel for details\n")); 1296 } 1297 1298 // Check for descendant experiments that are not loaded 1299 int num_desc = VecSize (exp->children_exps); 1300 if ((num_desc > 0) && !settings->check_en_desc (NULL, NULL)) 1301 { 1302 char *s; 1303 if (!is_interactive ()) 1304 s = dbe_sprintf (GTXT ("Has %d descendant(s), use commands controlling selection to load descendant data\n"), num_desc); 1305 else 1306 s = dbe_sprintf (GTXT ("Has %d descendant(s), use filter panel to load descendant data\n"), num_desc); 1307 sb->append (path); 1308 sb->append (NTXT (": ")); 1309 sb->append (s); 1310 free (s); 1311 } 1312} 1313 1314Experiment * 1315DbeSession::get_exp (int exp_ind) 1316{ 1317 if (exp_ind < 0 || exp_ind >= exps->size ()) 1318 return NULL; 1319 Experiment *exp = exps->fetch (exp_ind); 1320 exp->setExpIdx (exp_ind); 1321 return exp; 1322} 1323 1324Vector<Vector<char*>*> * 1325DbeSession::getExperimensGroups () 1326{ 1327 if (dbeSession->expGroups == NULL || dbeSession->expGroups->size () == 0) 1328 return NULL; 1329 bool compare_mode = expGroups->size () > 1; 1330 Vector<Vector<char*>*> *groups = new Vector<Vector<char*>*> ( 1331 compare_mode ? expGroups->size () : 1); 1332 for (int i = 0; i < expGroups->size (); i++) 1333 { 1334 ExpGroup *grp = expGroups->fetch (i); 1335 Vector<Experiment*> *founders = grp->get_founders (); 1336 if (founders && founders->size () != 0) 1337 { 1338 Vector<char *> *names = new Vector<char*> (founders->size ()); 1339 for (int j = 0; j < founders->size (); j++) 1340 { 1341 Experiment *exp = founders->fetch (j); 1342 names->append (dbe_strdup (exp->get_expt_name ())); 1343 } 1344 if (compare_mode || groups->size () == 0) 1345 groups->append (names); 1346 else 1347 groups->fetch (0)->addAll (names); 1348 } 1349 delete founders; 1350 } 1351 return groups; 1352} 1353 1354char * 1355DbeSession::setExperimentsGroups (Vector<Vector<char*>*> *groups) 1356{ 1357 StringBuilder sb; 1358 for (int i = 0; i < groups->size (); i++) 1359 { 1360 Vector<char *> *names = groups->fetch (i); 1361 ExpGroup *grp; 1362 if (names->size () == 1) 1363 grp = new ExpGroup (names->fetch (0)); 1364 else 1365 { 1366 char *nm = dbe_sprintf (GTXT ("Group %d"), i + 1); 1367 grp = new ExpGroup (nm); 1368 free (nm); 1369 } 1370 expGroups->append (grp); 1371 grp->groupId = expGroups->size (); 1372 1373 for (int j = 0; j < names->size (); j++) 1374 { 1375 char *path = names->fetch (j); 1376 size_t len = strlen (path); 1377 if ((len > 4) && !strcmp (path + len - 4, NTXT (".erg"))) 1378 { 1379 Vector<char*> *lst = get_group_or_expt (path); 1380 for (int j1 = 0; j1 < lst->size (); j1++) 1381 { 1382 Experiment *exp = new Experiment (); 1383 append (exp); 1384 open_experiment (exp, lst->get (j1)); 1385 if (exp->get_status () == Experiment::FAILURE) 1386 append_mesgs (&sb, path, exp); 1387 } 1388 lst->destroy (); 1389 delete lst; 1390 } 1391 else 1392 { 1393 Experiment *exp = new Experiment (); 1394 append (exp); 1395 open_experiment (exp, path); 1396 if (exp->get_status () == Experiment::FAILURE) 1397 append_mesgs (&sb, path, exp); 1398 } 1399 } 1400 } 1401 1402 for (int i = 0, sz = views->size (); i < sz; i++) 1403 { 1404 DbeView *dbev = views->fetch (i); 1405 dbev->update_advanced_filter (); 1406 int cmp = dbev->get_settings ()->get_compare_mode (); 1407 dbev->set_compare_mode (CMP_DISABLE); 1408 dbev->set_compare_mode (cmp); 1409 } 1410 return sb.length () == 0 ? NULL : sb.toString (); 1411} 1412 1413char * 1414DbeSession::drop_experiment (int exp_ind) 1415{ 1416 DbeView *dbev; 1417 int index; 1418 Experiment *exp2; 1419 1420 status_ompavail = -1; 1421 Experiment *exp = exps->fetch (exp_ind); 1422 1423 // If this is a sub experiment, don't do it 1424 if (exp->founder_exp != NULL) // this is a sub experiment; don't do it 1425 return (dbe_strdup (GTXT ("Can not drop subexperiments"))); 1426 1427 if (VecSize (exp->children_exps) > 0) 1428 for (;;) 1429 { 1430 // search the list of experiments to find all that have this one as founder 1431 bool found = false; 1432 Vec_loop (Experiment*, exps, index, exp2) 1433 { 1434 if (exp2->founder_exp == exp) 1435 { 1436 exp2->founder_exp = NULL; 1437 drop_experiment (index); 1438 found = true; 1439 break; 1440 } 1441 } 1442 if (found == false) 1443 break; 1444 } 1445 1446 // then proceed to finish the drop 1447 Vec_loop (DbeView*, views, index, dbev) 1448 { 1449 dbev->drop_experiment (exp_ind); 1450 } 1451 1452 int old_cnt = expGroups->size (); 1453 for (int i = 0; i < old_cnt; i++) 1454 { 1455 ExpGroup *gr = expGroups->fetch (i); 1456 if (gr->groupId == exp->groupId) 1457 { 1458 gr->drop_experiment (exp); 1459 if ((gr->founder == NULL) && (gr->exps->size () == 0)) 1460 { 1461 delete gr; 1462 expGroups->remove (i); 1463 } 1464 break; 1465 } 1466 } 1467 delete exps->remove (exp_ind); 1468 if (old_cnt != expGroups->size ()) 1469 { 1470 for (int i = 0, sz = expGroups->size (); i < sz; i++) 1471 { 1472 ExpGroup *gr = expGroups->fetch (i); 1473 gr->groupId = i + 1; 1474 Vector<Experiment*> *expList = gr->exps; 1475 for (int i1 = 0, sz1 = expList->size (); i1 < sz1; i1++) 1476 expList->fetch (i1)->groupId = gr->groupId; 1477 } 1478 for (int i = 0, sz = views->size (); i < sz; i++) 1479 { 1480 dbev = views->fetch (i); 1481 int cmp = dbev->get_compare_mode (); 1482 dbev->set_compare_mode (CMP_DISABLE); 1483 dbev->set_compare_mode (cmp); 1484 } 1485 } 1486 check_tab_avail (); // update tab availability 1487 return NULL; 1488} 1489 1490int 1491DbeSession::find_experiment (char *path) 1492{ 1493 Experiment *exp; 1494 int index; 1495 Vec_loop (Experiment*, exps, index, exp) 1496 { 1497 if (strcmp (exp->get_expt_name (), path) == 0) 1498 return exp->getExpIdx (); 1499 } 1500 return -1; 1501} 1502 1503LoadObject * 1504DbeSession::createLoadObject (const char *nm, int64_t cksum) 1505{ 1506 return loadObjMap->sync_create_item (nm, cksum); 1507} 1508 1509LoadObject * 1510DbeSession::createLoadObject (const char *nm, const char *runTimePath, DbeFile *df) 1511{ 1512 return loadObjMap->sync_create_item (nm, runTimePath, df); 1513} 1514 1515void 1516DbeSession::append (LoadObject *lobj) 1517{ 1518 Histable *obj = lobj; // workaround for a C++ problem 1519 objs->append (obj); 1520 lobj->id = objs->size () - 1; 1521 lobjs->append (lobj); 1522 lobj->seg_idx = lobjs->size () - 1; 1523 char *loname = lobj->get_pathname (); 1524 dbeFiles->put (loname, lobj->dbeFile); 1525} 1526 1527DbeJarFile * 1528DbeSession::get_JarFile (const char *name) 1529{ 1530 DbeJarFile *jf = dbeJarFiles->get (name); 1531 if (jf == NULL) 1532 { 1533 jf = new DbeJarFile (name); 1534 dbeJarFiles->put (name, jf); 1535 } 1536 return jf; 1537} 1538 1539Module * 1540DbeSession::createModule (LoadObject *lo, const char *nm) 1541{ 1542 Module *mod = new Module (); 1543 Histable *obj = mod; // workaround for a C++ problem 1544 objs->append (obj); 1545 mod->id = objs->size () - 1; 1546 mod->loadobject = lo; 1547 mod->set_name (dbe_strdup (nm ? nm : localized_SP_UNKNOWN_NAME)); 1548 lo->seg_modules->append (mod); 1549 return mod; 1550} 1551 1552Module * 1553DbeSession::createUnknownModule (LoadObject *lo) 1554{ 1555 Module *mod = createModule (lo, localized_SP_UNKNOWN_NAME); 1556 mod->flags |= MOD_FLAG_UNKNOWN; 1557 mod->set_file_name (dbe_strdup (localized_SP_UNKNOWN_NAME)); 1558 return mod; 1559} 1560 1561SourceFile * 1562DbeSession::createSourceFile (const char *_path) 1563{ 1564 char *path = (char *) _path; 1565 if (strncmp (path, NTXT ("./"), 2) == 0) 1566 path += 2; 1567 SourceFile *source = sourcesMap->get (path); 1568 if (source == NULL) 1569 { 1570 source = new SourceFile (path); 1571 (void) sourcesMap->put (path, source); 1572 append (source); 1573 } 1574 return source; 1575} 1576 1577Function * 1578DbeSession::createFunction () 1579{ 1580 Function *func = new Function (objs->size ()); 1581 Histable *obj = func; // workaround for a C++ problem 1582 objs->append (obj); 1583 return func; 1584} 1585 1586JMethod * 1587DbeSession::createJMethod () 1588{ 1589 JMethod *jmthd = new JMethod (objs->size ()); 1590 Histable *obj = jmthd; // workaround for a C++ problem 1591 objs->append (obj); 1592 return jmthd; 1593} 1594 1595Module * 1596DbeSession::createClassFile (char *className) 1597{ 1598 ClassFile *cls = new ClassFile (); 1599 cls->set_name (className); 1600 char *clpath = cls->get_java_file_name (className, true); 1601 cls->dbeFile = getDbeFile (clpath, DbeFile::F_JAVACLASS); 1602 free (clpath); 1603 Histable *obj = cls; // workaround for a C++ problem 1604 objs->append (obj); 1605 cls->id = objs->size () - 1; 1606 return cls; 1607} 1608 1609Histable * 1610DbeSession::createHistObject (Histable::Type type) 1611{ 1612 switch (type) 1613 { 1614 case Histable::DOBJECT: 1615 { 1616 DataObject *dataobj = new DataObject (); 1617 dobjs->append (dataobj); 1618 dataobj->id = dobjs->size () - 1; 1619 return dataobj; 1620 } 1621 default: 1622 assert (0); 1623 } 1624 return NULL; 1625} 1626 1627DataObject * 1628DbeSession::createDataObject () 1629{ 1630 DataObject *dataobj = new DataObject (); 1631 dobjs->append (dataobj); 1632 dataobj->id = dobjs->size () - 1; 1633 return dataobj; 1634} 1635 1636DataObject * 1637DbeSession::createDataObject (DataObject *dobj, DataObject *parent) 1638{ 1639 DataObject *dataobj = new DataObject (); 1640 dataobj->size = dobj->size; 1641 dataobj->offset = dobj->offset; 1642 dataobj->parent = parent; 1643 dataobj->set_dobjname (dobj->get_typename (), dobj->get_instname ()); 1644 dobjs->append (dataobj); 1645 dataobj->id = dobjs->size () - 1; 1646 return dataobj; 1647} 1648 1649DataObject * 1650DbeSession::createMasterDataObject (DataObject *dobj) 1651{ 1652 DataObject *parent = NULL; 1653 if (dobj->parent) 1654 { // define master parent first 1655 parent = find_dobj_master (dobj->parent); 1656 if (!parent) 1657 { // clone master from this dataobject parent 1658 parent = createDataObject (dobj->parent); 1659 parent->scope = NULL; // master is scope-less 1660 Dprintf (DEBUG_DATAOBJ, 1661 "Master DataObject(%llu) cloned from (%llu) %s\n", 1662 (ull_t) parent->id, (ull_t) dobj->parent->id, 1663 dobj->parent->get_name ()); 1664 // clone master DataObject elements 1665 Vector<DataObject*> *delem = get_dobj_elements (dobj->parent); 1666 int element_index = 0; 1667 DataObject *element = NULL; 1668 Vec_loop (DataObject*, delem, element_index, element) 1669 { 1670 DataObject *master_element = createDataObject (element, parent); 1671 master_element->scope = NULL; // master is scope-less 1672 Dprintf (DEBUG_DATAOBJ, 1673 "Member DataObject(%llu) cloned from (%llu) %s\n", 1674 (ull_t) master_element->id, (ull_t) element->id, 1675 element->get_name ()); 1676 } 1677 } 1678 else 1679 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n", 1680 (ull_t) parent->id, (ull_t) dobj->parent->id, 1681 dobj->parent->get_name ()); 1682 } 1683 1684 DataObject *master = find_dobj_master (dobj); 1685 if (!master) 1686 { // clone master from this dataobject 1687 master = createDataObject (dobj, parent); 1688 master->scope = NULL; // master is scope-less 1689 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) cloned from (%llu) %s\n", 1690 (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ()); 1691 } 1692 else 1693 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n", 1694 (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ()); 1695 return master; 1696} 1697 1698void 1699DbeSession::insert_metric (BaseMetric *mtr, Vector<BaseMetric*> *mlist) 1700{ 1701 if ((mtr->get_flavors () & Metric::STATIC) == 0) 1702 { 1703 // insert in front of the first STATIC 1704 for (int i = 0, mlist_sz = mlist->size (); i < mlist_sz; i++) 1705 { 1706 BaseMetric *m = mlist->fetch (i); 1707 if (m->get_flavors () & Metric::STATIC) 1708 { 1709 mlist->insert (i, mtr); 1710 return; 1711 } 1712 } 1713 } 1714 mlist->append (mtr); 1715} 1716 1717BaseMetricTreeNode* 1718DbeSession::get_reg_metrics_tree () 1719{ 1720 if (reg_metrics_tree == NULL) 1721 // Can't init earlier because BaseMetric() requires DbeSession::ql_parse 1722 reg_metrics_tree = new BaseMetricTreeNode (); 1723 return reg_metrics_tree; 1724} 1725 1726void 1727DbeSession::update_metric_tree (BaseMetric *m) 1728{ 1729 get_reg_metrics_tree ()->register_metric (m); 1730} 1731 1732BaseMetric * 1733DbeSession::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec) 1734{ 1735 BaseMetric *m = find_metric (type, cmd, expr_spec); 1736 if (m) 1737 return m; 1738 BaseMetric *bm = find_metric (type, cmd, NULL); // clone this version 1739 m = new BaseMetric (*bm); 1740 m->set_expr_spec (expr_spec); 1741 insert_metric (m, reg_metrics); 1742 return m; 1743} 1744 1745BaseMetric * 1746DbeSession::register_metric (BaseMetric::Type type) 1747{ 1748 BaseMetric *m = find_metric (type, NULL, NULL); 1749 if (m) 1750 return m; 1751 m = new BaseMetric (type); 1752 insert_metric (m, reg_metrics); 1753 update_metric_tree (m); 1754 return m; 1755} 1756 1757BaseMetric * 1758DbeSession::register_metric (Hwcentry *ctr, const char* aux, const char* username) 1759{ 1760 BaseMetric *m = find_metric (BaseMetric::HWCNTR, aux, NULL); 1761 if (m) 1762 // That may be a problem when metrics aren't an exact match. 1763 // For example, memoryspace is disabled in one experiment and not in another. 1764 return m; 1765 if (ctr->timecvt) 1766 { 1767 char *time_cmd = dbe_sprintf (NTXT ("t%s"), aux); 1768 char *time_username = dbe_sprintf (GTXT ("%s Time"), 1769 ctr->metric ? ctr->metric : 1770 (ctr->name ? ctr->name : ctr->int_name)); 1771 BaseMetric *m1; 1772 if (ipc_mode) 1773 { 1774 // Two visible metrics are presented in GUI 1775 m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL); 1776 insert_metric (m1, reg_metrics); 1777 update_metric_tree (m1); 1778 m = new BaseMetric (ctr, aux, username, VAL_VALUE, m1); 1779 } 1780 else 1781 { 1782 // Only one visible metric is presented in er_print 1783 m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL | VAL_INTERNAL); 1784 insert_metric (m1, reg_metrics); 1785 m = new BaseMetric (ctr, aux, username, VAL_TIMEVAL | VAL_VALUE, m1); 1786 } 1787 free (time_cmd); 1788 free (time_username); 1789 } 1790 else 1791 m = new BaseMetric (ctr, aux, username, VAL_VALUE); 1792 insert_metric (m, reg_metrics); 1793 update_metric_tree (m); 1794 return m; 1795} 1796 1797BaseMetric * 1798DbeSession::register_metric (char *name, char *username, char *_def) 1799{ 1800 BaseMetric *m = find_metric (BaseMetric::DERIVED, name, NULL); 1801 if (m) 1802 return m; 1803 Definition *p = Definition::add_definition (_def); 1804 if (p == NULL) 1805 return NULL; 1806 m = new BaseMetric (name, username, p); 1807 insert_metric (m, reg_metrics); 1808 update_metric_tree (m); 1809 return m; 1810} 1811 1812void 1813DbeSession::drop_metric (BaseMetric *mtr) 1814{ 1815 Countable *cnt; 1816 int index; 1817 1818 Vec_loop (Countable*, metrics, index, cnt) 1819 { 1820 if (mtr == (BaseMetric *) cnt->item) 1821 { 1822 cnt->ref_count--; 1823 if (cnt->ref_count == 0) 1824 { 1825 // Remove this metric from all views 1826 DbeView *dbev; 1827 int index2; 1828 Vec_loop (DbeView*, views, index2, dbev) 1829 { 1830 dbev->reset_metrics (); 1831 } 1832 delete metrics->remove (index); 1833 delete mtr; 1834 return; 1835 } 1836 } 1837 } 1838} 1839 1840BaseMetric * 1841DbeSession::find_metric (BaseMetric::Type type, const char *cmd, const char *expr_spec) 1842{ 1843 for (int i = 0, sz = reg_metrics->size (); i < sz; i++) 1844 { 1845 BaseMetric *bm = reg_metrics->fetch (i); 1846 if (bm->get_type () == type && dbe_strcmp (bm->get_expr_spec (), expr_spec) == 0) 1847 { 1848 if ((type == BaseMetric::DERIVED || type == BaseMetric::HWCNTR) 1849 && dbe_strcmp (bm->get_cmd (), cmd) != 0) 1850 continue; 1851 return bm; 1852 } 1853 } 1854 return NULL; 1855} 1856 1857BaseMetric * 1858DbeSession::find_base_reg_metric (char * mcmd) 1859{ 1860 for (int i = 0, sz = reg_metrics->size (); i < sz; i++) 1861 { 1862 BaseMetric *bm = reg_metrics->fetch (i); 1863 if (bm->get_expr_spec () != NULL) 1864 continue; // skip compare metrics 1865 if (dbe_strcmp (bm->get_cmd (), mcmd) == 0) 1866 return bm; 1867 } 1868 return NULL; 1869} 1870 1871Vector<BaseMetric*> * 1872DbeSession::get_base_reg_metrics () 1873{ 1874 Vector<BaseMetric*> *mlist = new Vector<BaseMetric*>; 1875 Vector<BaseMetric*> *ml = get_all_reg_metrics (); 1876 for (int i = 0, sz = ml->size (); i < sz; i++) 1877 { 1878 BaseMetric *m = ml->fetch (i); 1879 if (m->get_expr_spec () == NULL) 1880 mlist->append (m); 1881 } 1882 return mlist; 1883} 1884 1885void 1886DbeSession::check_tab_avail () 1887{ 1888 DbeView *dbev; 1889 int index; 1890 // tell the views to update their tab lists 1891 Vec_loop (DbeView*, views, index, dbev) 1892 { 1893 dbev->get_settings ()->updateTabAvailability (); 1894 } 1895} 1896 1897bool 1898DbeSession::is_datamode_available () 1899{ 1900 Experiment *exp; 1901 int index; 1902 Vec_loop (Experiment*, exps, index, exp) 1903 { 1904 if (exp->dataspaceavail) 1905 return true; 1906 } 1907 return false; 1908} 1909 1910bool 1911DbeSession::is_leaklist_available () 1912{ 1913 Experiment *exp; 1914 int index; 1915 Vec_loop (Experiment*, exps, index, exp) 1916 { 1917 if (exp->leaklistavail) 1918 return true; 1919 } 1920 return false; 1921} 1922 1923bool 1924DbeSession::is_heapdata_available () 1925{ 1926 Experiment *exp; 1927 int index; 1928 Vec_loop (Experiment*, exps, index, exp) 1929 { 1930 if (exp->heapdataavail) 1931 return true; 1932 } 1933 return false; 1934} 1935 1936bool 1937DbeSession::is_iodata_available () 1938{ 1939 Experiment *exp; 1940 int index; 1941 Vec_loop (Experiment*, exps, index, exp) 1942 { 1943 if (exp->iodataavail) 1944 return true; 1945 } 1946 return false; 1947} 1948 1949bool 1950DbeSession::is_racelist_available () 1951{ 1952 Experiment *exp; 1953 int index; 1954 Vec_loop (Experiment*, exps, index, exp) 1955 { 1956 if (exp->racelistavail) 1957 return true; 1958 } 1959 return false; 1960} 1961 1962bool 1963DbeSession::is_deadlocklist_available () 1964{ 1965 Experiment *exp; 1966 int index; 1967 Vec_loop (Experiment*, exps, index, exp) 1968 { 1969 if (exp->deadlocklistavail) 1970 return true; 1971 } 1972 return false; 1973} 1974 1975bool 1976DbeSession::is_timeline_available () 1977{ 1978 Experiment *exp; 1979 int index; 1980 Vec_loop (Experiment*, exps, index, exp) 1981 { 1982 if (exp->timelineavail) 1983 return true; 1984 } 1985 return false; 1986} 1987 1988bool 1989DbeSession::is_ifreq_available () 1990{ 1991 Experiment *exp; 1992 int index; 1993 Vec_loop (Experiment*, exps, index, exp) 1994 { 1995 if (exp->ifreqavail) 1996 return true; 1997 } 1998 return false; 1999} 2000 2001bool 2002DbeSession::is_omp_available () 2003{ 2004 if (status_ompavail == -1) 2005 { 2006 status_ompavail = 0; 2007 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++) 2008 { 2009 Experiment *exp = exps->fetch (i); 2010 if (exp->ompavail) 2011 { 2012 status_ompavail = 1; 2013 break; 2014 } 2015 } 2016 } 2017 return status_ompavail == 1; 2018} 2019 2020bool 2021DbeSession::has_java () 2022{ 2023 int status_has_java = 0; 2024 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++) 2025 { 2026 Experiment *exp = exps->fetch (i); 2027 if (exp->has_java) 2028 { 2029 status_has_java = 1; 2030 break; 2031 } 2032 } 2033 return status_has_java == 1; 2034} 2035 2036bool 2037DbeSession::has_ompavail () 2038{ 2039 int status_has_ompavail = 0; 2040 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++) 2041 { 2042 Experiment *exp = exps->fetch (i); 2043 if (exp->ompavail) 2044 { 2045 status_has_ompavail = 1; 2046 break; 2047 } 2048 } 2049 return status_has_ompavail == 1; 2050} 2051 2052int 2053DbeSession::get_clock (int whichexp) 2054{ 2055 // XXXX clock frequency should be an attribute of each CPU, 2056 // XXX and not a property of the session 2057 // if whichexp is -1, pick the first exp that has a clock 2058 // otherwise return the clock from the numbered experiment 2059 Experiment *exp; 2060 if (whichexp != -1) 2061 { 2062 exp = get_exp (whichexp); 2063 if (exp != NULL) 2064 return exp->clock; 2065 return 0; 2066 } 2067 int n = nexps (); 2068 for (int i = 0; i < n; i++) 2069 { 2070 exp = get_exp (i); 2071 if (exp != NULL && exp->clock != 0) 2072 return exp->clock; 2073 } 2074 return 0; 2075} 2076 2077LoadObject * 2078DbeSession::find_lobj_by_name (const char *lobj_name, int64_t cksum) 2079{ 2080 return loadObjMap->get (lobj_name, cksum); 2081} 2082 2083static unsigned 2084hash (char *s) 2085{ 2086 unsigned res = 0; 2087 for (int i = 0; i < 64 && *s; i++) 2088 res = res * 13 + *s++; 2089 return res; 2090} 2091 2092// This method is introduced to fix performance 2093// problems with the data space profiling in the 2094// current release. A better design is desired. 2095void 2096DbeSession::dobj_updateHT (DataObject *dobj) 2097{ 2098 unsigned index = hash (dobj->get_unannotated_name ()) % HTableSize; 2099 List *list = new List; 2100 list->val = (void*) dobj; 2101 list->next = dnameHTable[index]; 2102 dnameHTable[index] = list; 2103} 2104 2105DataObject * 2106DbeSession::find_dobj_by_name (char *dobj_name) 2107{ 2108 unsigned index = hash (dobj_name) % HTableSize; 2109 List *list = dnameHTable[index]; 2110 for (; list; list = list->next) 2111 { 2112 DataObject *d = (DataObject*) list->val; 2113 if (strcmp (d->get_unannotated_name (), dobj_name) == 0) 2114 return d; 2115 } 2116 return (DataObject *) NULL; 2117} 2118 2119DataObject * 2120DbeSession::find_dobj_match (DataObject *dobj) 2121{ 2122 char *dobj_name = dobj->get_unannotated_name (); 2123 unsigned index = hash (dobj_name) % HTableSize; 2124 List *list = dnameHTable[index]; 2125 for (; list; list = list->next) 2126 { 2127 DataObject *d = (DataObject*) list->val; 2128 if (strcmp (d->get_unannotated_name (), dobj_name) == 0 2129 && d->size == dobj->size && d->offset == dobj->offset 2130 && d->scope == dobj->scope) 2131 return d; 2132 } 2133 return (DataObject *) NULL; 2134} 2135 2136DataObject * 2137DbeSession::find_dobj_master (DataObject *dobj) 2138{ 2139 char *dobj_name = dobj->get_unannotated_name (); 2140 unsigned index = hash (dobj_name) % HTableSize; 2141 List *list = dnameHTable[index]; 2142 for (; list; list = list->next) 2143 { 2144 DataObject *d = (DataObject*) list->val; 2145 // XXXX should parent also match? 2146 if (strcmp (d->get_unannotated_name (), dobj_name) == 0 2147 && d->size == dobj->size && d->offset == dobj->offset 2148 && d->master == NULL && d->scope == NULL) 2149 return d; 2150 } 2151 return (DataObject *) NULL; 2152} 2153 2154Vector<DataObject*>* 2155DbeSession::get_dobj_elements (DataObject *dobj) 2156{ 2157 DataObject *d; 2158 int index; 2159 Vector<DataObject*> *elements = new Vector<DataObject*>; 2160 if (dobj == d_total) 2161 return elements; 2162 Vec_loop (DataObject*, dobjs, index, d) 2163 { 2164 if (d->get_parent () && d->get_parent () == dobj) 2165 elements->append (d); 2166 } 2167 return elements; 2168} 2169 2170Vector<LoadObject*>* 2171DbeSession::get_text_segments () 2172{ 2173 LoadObject *lo; 2174 int index; 2175 Vector<LoadObject*> *tlobjs = new Vector<LoadObject*>; 2176 Vec_loop (LoadObject*, lobjs, index, lo) 2177 { 2178 if (lo->type == LoadObject::SEG_TEXT) 2179 tlobjs->append (lo); 2180 } 2181 return tlobjs; 2182} 2183 2184static long long 2185getNumber (const char *s, char * &last) 2186{ 2187 long long val; 2188 char *sp; 2189 errno = 0; 2190 val = strtoll (s, &sp, 0); 2191 if (errno == EINVAL) 2192 last = NULL; 2193 else 2194 { 2195 while (isspace (*sp)) 2196 sp++; 2197 last = sp; 2198 } 2199 return (val); 2200} 2201 2202bool 2203DbeSession::find_obj (FILE *dis_file, FILE *inp_file, Histable *&obj, 2204 char *name, const char *sel, Histable::Type type, bool xdefault) 2205{ 2206 Vector<Histable*> *obj_lst; 2207 int which = -1; 2208 char *last = NULL; 2209 if (type != Histable::FUNCTION && sel) 2210 { 2211 // check that a number has been provided 2212 which = (int) getNumber (sel, last); 2213 if (last == NULL || *last != '\0') 2214 { 2215 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel); 2216 sel = NULL; 2217 which = 0; 2218 } 2219 which--; 2220 } 2221 obj_lst = new Vector<Histable*>; 2222 switch (type) 2223 { 2224 case Histable::FUNCTION: 2225 obj = map_NametoFunction (name, obj_lst, sel); 2226 break; 2227 case Histable::MODULE: 2228 obj = map_NametoModule (name, obj_lst, which); 2229 break; 2230 case Histable::LOADOBJECT: 2231 obj = map_NametoLoadObject (name, obj_lst, which); 2232 break; 2233 case Histable::DOBJECT: 2234 obj = map_NametoDataObject (name, obj_lst, which); 2235 break; 2236 default: 2237 abort (); // unexpected Histable! 2238 } 2239 2240 if ((obj == NULL) && (obj_lst->size () > 0)) 2241 { 2242 if (obj_lst->size () == 1) 2243 which = 0; 2244 else 2245 { 2246 if (sel && (which < 0 || which >= obj_lst->size ())) 2247 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel); 2248 if (xdefault) 2249 { 2250 fprintf (stderr, GTXT ("Default selection \"1\" made\n")); 2251 which = 0; 2252 } 2253 else 2254 { 2255 which = ask_which (dis_file, inp_file, obj_lst, name); 2256 if (which == -1) 2257 { 2258 delete obj_lst; 2259 return false; 2260 } 2261 } 2262 } 2263 obj = obj_lst->fetch (which); 2264 } 2265 delete obj_lst; 2266 return true; 2267} 2268 2269int 2270DbeSession::ask_which (FILE *dis_file, FILE *inp_file, 2271 Vector<Histable*> *list, char *name) 2272{ 2273 Histable *hitem; 2274 Function *func; 2275 Module *module; 2276 int which, index, index1; 2277 char *item_name, *lo_name, *fname, *last; 2278 char buf[BUFSIZ]; 2279 for (;;) 2280 { 2281 fprintf (dis_file, GTXT ("Available name list:\n")); 2282 fprintf (dis_file, GTXT ("%8d) Cancel\n"), 0); 2283 Vec_loop (Histable*, list, index, hitem) 2284 { 2285 index1 = index + 1; 2286 item_name = hitem->get_name (); 2287 switch (hitem->get_type ()) 2288 { 2289 case Histable::FUNCTION: 2290 func = (Function *) hitem; 2291 module = func->module; 2292 2293 // id == -1 indicates er_src invocation 2294 if (module == NULL || (module->lang_code == Sp_lang_java 2295 && module->loadobject->id == -1)) 2296 fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name); 2297 else 2298 { 2299 lo_name = module->loadobject->get_pathname (); 2300 fname = (module->file_name && *module->file_name) ? 2301 module->file_name : module->get_name (); 2302 if (fname && *fname) 2303 fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx (%s)\n"), index1, 2304 item_name, lo_name, (ull_t) func->img_offset, fname); 2305 else 2306 fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx\n"), index1, 2307 item_name, lo_name, (ull_t) func->img_offset); 2308 } 2309 break; 2310 case Histable::MODULE: 2311 module = (Module *) hitem; 2312 lo_name = module->loadobject->get_pathname (); 2313 if (name[strlen (name) - 1] == 2314 module->file_name[strlen (module->file_name) - 1]) 2315 fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1, 2316 module->file_name, lo_name); 2317 else 2318 fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1, item_name, 2319 lo_name); 2320 break; 2321 default: 2322 fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name); 2323 break; 2324 } 2325 } 2326 if (inp_file != stdin) 2327 return -1; 2328 fprintf (dis_file, GTXT ("Enter selection: ")); 2329 if (fgets (buf, (int) sizeof (buf), inp_file) == NULL) 2330 { 2331 fprintf (stderr, GTXT ("Error: Invalid number entered:\n")); 2332 return -1; 2333 } 2334 which = (int) getNumber (buf, last); 2335 if (last && *last == '\0') 2336 if (which >= 0 && which <= list->size ()) 2337 return which - 1; 2338 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), buf); 2339 } 2340} 2341 2342static bool 2343match_basename (char *name, char *full_name, int len = -1) 2344{ 2345 if (full_name == NULL) 2346 return false; 2347 if (!strchr (name, '/')) 2348 full_name = get_basename (full_name); 2349 if (len == -1) 2350 return streq (name, full_name); 2351 return strncmp (name, full_name, len) == 0; 2352} 2353 2354LoadObject * 2355DbeSession::map_NametoLoadObject (char *name, Vector<Histable*> *list, int which) 2356{ 2357 // Search the tree to find the first module whose module name 2358 // matches "name" or whose source file name matches "name" 2359 // Issues: is the name a pathname, or a base name? 2360 // Should we look at suffix to disambiguate? 2361 LoadObject *loitem; 2362 int index; 2363 Vec_loop (LoadObject*, lobjs, index, loitem) 2364 { 2365 // try pathname first 2366 // if failed, try object name next 2367 if (match_basename (name, loitem->get_pathname ()) || 2368 match_basename (name, loitem->get_name ())) 2369 { 2370 if (which == list->size ()) 2371 return loitem; 2372 list->append (loitem); 2373 } 2374 } 2375 return (LoadObject *) NULL; 2376} 2377 2378Module * 2379DbeSession::map_NametoModule (char *name, Vector<Histable*> *list, int which) 2380{ 2381 // Search the tree to find the first loadobject whose loadobject name 2382 // matches "name". 2383 2384 // Issues: is the name a pathname, or a base name? 2385 // Should we look at suffix to disambiguate? 2386 LoadObject *loitem; 2387 Module *mitem; 2388 int index1, index2; 2389 Vec_loop (LoadObject*, lobjs, index1, loitem) 2390 { 2391 Vec_loop (Module*, loitem->seg_modules, index2, mitem) 2392 { 2393 // try source name first 2394 // if failed, try object name next 2395 if (match_basename (name, mitem->file_name) || 2396 match_basename (name, mitem->get_name ())) 2397 { 2398 if (which == list->size ()) 2399 return mitem; 2400 list->append (mitem); 2401 } 2402 } 2403 } 2404 return (Module *) NULL; 2405} 2406 2407Function * 2408DbeSession::map_NametoFunction (char *name, Vector<Histable*> *list, 2409 const char *sel) 2410{ 2411 // Search the tree to find the first function whose 2412 // name matches "name". 2413 // Issues: is the name a full name, or a short name? 2414 // Is it a demangled name? If so, what about spaces 2415 // within the name? 2416 // Is there a way to return all names that match? 2417 // How can the user specify a particular function of that name? 2418 LoadObject *loitem; 2419 Function *fitem, *main_func = NULL; 2420 Module *mitem, *main_mod = NULL; 2421 int index1, index2, index3, which = -1; 2422 if (sel) 2423 { 2424 char *last = NULL; 2425 if (*sel == '@') 2426 { // 'sel' is "@seg_num:address" 2427 which = (int) getNumber (sel + 1, last); 2428 if (last == NULL || *last != ':' || (which < 0) || (which >= lobjs->size ())) 2429 { 2430 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel); 2431 return NULL; 2432 } 2433 uint64_t address = getNumber (last + 1, last); 2434 if (last == NULL || *last != '\0') 2435 { 2436 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel); 2437 return NULL; 2438 } 2439 loitem = lobjs->fetch (which); 2440 Vec_loop (Module*, loitem->seg_modules, index2, mitem) 2441 { 2442 Vec_loop (Function*, mitem->functions, index3, fitem) 2443 { 2444 if (address == fitem->img_offset && match_FName (name, fitem)) 2445 return fitem; 2446 } 2447 } 2448 return NULL; 2449 } 2450 2451 which = (int) getNumber (sel, last); 2452 if (last == NULL || *last != '\0') 2453 { 2454 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel); 2455 return NULL; 2456 } 2457 which--; 2458 } 2459 2460 int len_path = 0; 2461 char *with_path = name; 2462 name = StrRchr (name, '`'); 2463 if (name != with_path) 2464 len_path = (int) (name - with_path); 2465 else 2466 with_path = NULL; 2467 2468 Vec_loop (LoadObject*, lobjs, index1, loitem) 2469 { 2470 Vec_loop (Module*, loitem->seg_modules, index2, mitem) 2471 { 2472 if (with_path) 2473 { // with file name 2474 // try source name first 2475 // if failed, try object name next 2476 if (!match_basename (with_path, mitem->file_name, len_path) && 2477 !match_basename (with_path, mitem->get_name (), len_path)) 2478 continue; 2479 } 2480 Vec_loop (Function*, mitem->functions, index3, fitem) 2481 { 2482 if (match_FName (name, fitem)) 2483 { 2484 if (which == list->size ()) 2485 return fitem; 2486 list->append (fitem); 2487 continue; 2488 } 2489 if (streq (fitem->get_name (), NTXT ("MAIN_")) && mitem->is_fortran ()) 2490 { 2491 main_func = fitem; 2492 main_mod = mitem; 2493 } 2494 } 2495 } 2496 } 2497 2498 if (main_mod && main_func) 2499 { 2500 main_mod->read_stabs (); 2501 if (streq (main_func->get_match_name (), name) && which <= 1) 2502 return main_func; 2503 } 2504 return (Function *) NULL; 2505} 2506 2507DataObject * 2508DbeSession::map_NametoDataObject (char *name, Vector<Histable*> *list, 2509 int which) 2510{ 2511 // Search master list to find dataobjects whose names match "name" 2512 // selecting only the entry corresponding to "which" if it is not -1. 2513 // Issues: is the name fully qualified or only partially? 2514 DataObject *ditem = NULL; 2515 int index; 2516 char *full_name; 2517 Vec_loop (DataObject*, dobjs, index, ditem) 2518 { 2519 if (ditem->scope) continue; // skip non-master dataobjects 2520 2521 // try fully-qualified dataobject name first 2522 if ((full_name = ditem->get_name ()) != NULL) 2523 { 2524 if (streq (name, full_name)) 2525 { 2526 if (which == list->size ()) 2527 return ditem; 2528 list->append (ditem); 2529 } 2530 } 2531 } 2532 if (list->size () > 0) 2533 return ditem; // return fully-qualified match 2534 2535 // if fully-qualified name doesn't match anything, try a partial match 2536 Vec_loop (DataObject*, dobjs, index, ditem) 2537 { 2538 if (ditem->scope) continue; // skip non-master dataobjects 2539 2540 // try fully-qualified dataobject name first 2541 if ((full_name = ditem->get_name ()) != NULL) 2542 { 2543 if (strstr (full_name, name)) 2544 { 2545 if (which == list->size ()) 2546 return ditem; 2547 list->append (ditem); 2548 } 2549 } 2550 } 2551 return (DataObject *) NULL; 2552} 2553 2554bool 2555DbeSession::match_FName (char *name, Function *func) 2556{ 2557 size_t len; 2558 char buf[MAXDBUF]; 2559 char *full_name; 2560 if (streq (func->get_name (), name)) // try full name comparison 2561 return true; 2562 if (streq (func->get_mangled_name (), name)) // try mangled name 2563 return true; 2564 if (streq (func->get_match_name (), name)) // try match name 2565 return true; 2566 2567 Module *md = func->module; // try FORTRAN name 2568 if (md && md->is_fortran ()) 2569 { 2570 char *mangled_name = func->get_mangled_name (); 2571 len = strlen (name); 2572 if (((len + 1) == strlen (mangled_name)) && 2573 (strncmp (name, mangled_name, len) == 0)) 2574 return true; 2575 } 2576 snprintf (buf, sizeof (buf), NTXT ("%s"), func->get_name ()); 2577 full_name = buf; 2578 char *arg = NULL; // find modifier and C++ class name 2579 int i = get_paren (buf); 2580 if (i >= 0) 2581 { 2582 arg = buf + i; 2583 *arg = '\0'; 2584 } 2585 2586 char *mod = strchr (full_name, ' '); 2587 char *cls = strchr (full_name, ':'); 2588 2589 if (mod) 2590 { 2591 len = mod - full_name + 1; 2592 if (!strncmp (full_name, name, len)) 2593 name += len; 2594 full_name += len; 2595 if (streq (full_name, name)) // try without modifier 2596 return true; 2597 } 2598 2599 size_t len_cmp = strlen (name); 2600 if (arg) 2601 { 2602 *arg = '('; 2603 len = arg - full_name; // try without 'args' 2604 if (len_cmp == len && !strncmp (full_name, name, len)) 2605 return true; 2606 if (cls) 2607 { 2608 len = arg - cls - 2; // and without 'class name' 2609 if ((len_cmp == len) && !strncmp (cls + 2, name, len)) 2610 return true; 2611 } 2612 } 2613 2614 if (cls) 2615 { 2616 len = cls - full_name; // try C++ class name only 2617 if (len_cmp == len && !strncmp (full_name, name, len)) 2618 return true; 2619 if (streq (cls + 2, name)) // try without 'class name' 2620 return true; 2621 } 2622 return false; 2623} 2624 2625bool 2626DbeSession::add_path (char *path) 2627{ 2628 return add_path (path, get_search_path ()); 2629} 2630 2631bool 2632DbeSession::add_classpath (char *path) 2633{ 2634 return add_path (path, classpath); 2635} 2636 2637Vector<DbeFile*> * 2638DbeSession::get_classpath () 2639{ 2640 if (classpath_df == NULL) 2641 classpath_df = new Vector<DbeFile*>; 2642 for (int i = classpath_df->size (), sz = classpath->size (); i < sz; i++) 2643 classpath_df->store (i, getDbeFile (classpath->fetch (i), 2644 DbeFile::F_DIR_OR_JAR)); 2645 return classpath_df; 2646} 2647 2648bool 2649DbeSession::add_path (char *path, Vector<char*> *pathes) 2650{ 2651 bool result = false; 2652 Vector <char *> *tokens = split_str (path, ':'); 2653 for (long j = 0, jsz = VecSize (tokens); j < jsz; j++) 2654 { 2655 char *spath = tokens->get (j); 2656 // Don't append path if it's already there 2657 bool got = false; 2658 for (int i = 0, sz = pathes->size (); i < sz; i++) 2659 { 2660 char *nm = pathes->get (i); 2661 if (streq (nm, spath)) 2662 { 2663 got = true; 2664 break; 2665 } 2666 } 2667 if (!got) 2668 { 2669 pathes->append (spath); 2670 result = true; 2671 } 2672 else 2673 free (spath); 2674 } 2675 delete tokens; 2676 return result; 2677} 2678 2679void 2680DbeSession::set_need_refind () 2681{ 2682 Vector<DbeFile*> *f_list = dbeFiles->values (); 2683 for (long i = 0, sz = f_list == NULL ? 0 : f_list->size (); i < sz; i++) 2684 { 2685 DbeFile *f = f_list->get (i); 2686 f->set_need_refind (true); 2687 } 2688 delete f_list; 2689 for (long i = 0, sz = sources == NULL ? 0 : sources->size (); i < sz; i++) 2690 { 2691 SourceFile *f = sources->get (i); 2692 if (f && f->dbeFile) 2693 f->dbeFile->set_need_refind (true); 2694 } 2695} 2696 2697void 2698DbeSession::set_search_path (Vector<char*> *path, bool reset) 2699{ 2700 if (reset) 2701 search_path->destroy (); 2702 for (int i = 0, sz = path == NULL ? 0 : path->size (); i < sz; i++) 2703 { 2704 char *name = path->fetch (i); 2705 if (add_path (name)) 2706 reset = true; 2707 } 2708 if (reset) 2709 { 2710 set_need_refind (); 2711 2712 // now reset the string setting for it 2713 StringBuilder sb; 2714 for (int i = 0, sz = search_path == NULL ? 0 : search_path->size (); i < sz; i++) 2715 { 2716 char *name = search_path->fetch (i); 2717 if (sb.length () != 0) 2718 sb.append (':'); 2719 sb.append (name); 2720 } 2721 free (settings->str_search_path); 2722 settings->str_search_path = sb.toString (); 2723 } 2724} 2725 2726void 2727DbeSession::set_search_path (char *_lpath, bool reset) 2728{ 2729 Vector<char *> *path = new Vector<char*>; 2730 char *lpath = dbe_strdup (_lpath); 2731 for (char *s = lpath; s;) 2732 { 2733 path->append (s); 2734 s = strchr (s, ':'); 2735 if (s) 2736 { 2737 *s = 0; 2738 s++; 2739 } 2740 } 2741 set_search_path (path, reset); 2742 delete path; 2743 free (lpath); 2744} 2745 2746void 2747DbeSession::set_pathmaps (Vector<pathmap_t*> *newPathMap) 2748{ 2749 set_need_refind (); 2750 settings->set_pathmaps (newPathMap); 2751} 2752 2753Vector<pathmap_t*> * 2754DbeSession::get_pathmaps () 2755{ 2756 return settings->pathmaps; 2757} 2758 2759void 2760DbeSession::mobj_define (MemObjType_t *mobj) 2761{ 2762 settings->mobj_define (mobj, false); 2763 DbeView *dbev; 2764 int index; 2765 Vec_loop (DbeView*, views, index, dbev) 2766 { 2767 dbev->get_settings ()->mobj_define (mobj, false); 2768 } 2769} 2770 2771void 2772DbeSession::dump_segments (FILE *out) 2773{ 2774 int index; 2775 LoadObject *loitem; 2776 Vec_loop (LoadObject*, lobjs, index, loitem) 2777 { 2778 fprintf (out, NTXT ("Segment %d -- %s -- %s\n\n"), 2779 index, loitem->get_name (), loitem->get_pathname ()); 2780 loitem->dump_functions (out); 2781 fprintf (out, NTXT ("\n End Segment %d -- %s -- %s\n\n"), 2782 index, loitem->get_name (), loitem->get_pathname ()); 2783 } 2784} 2785 2786void 2787DbeSession::dump_dataobjects (FILE *out) 2788{ 2789 DataObject *ditem; 2790 int index; 2791 2792 fprintf (out, NTXT ("\nMaster list of DataObjects:\n")); 2793 Vec_loop (DataObject*, dobjs, index, ditem) 2794 { 2795 Histable* scope = ditem->get_scope (); 2796 DataObject* parent = ditem->get_parent (); 2797 DataObject* master = ditem->get_master (); 2798 if (parent != NULL) 2799 fprintf (out, "id %6lld: [%4lld] parent = %6lld, offset = %+4lld %s\n", 2800 (ll_t) ditem->id, (ll_t) ditem->get_size (), 2801 (ll_t) parent->id, (ll_t) ditem->get_offset (), 2802 ditem->get_name ()); 2803 else 2804 { 2805 // parent is NULL 2806 fprintf (out, NTXT ("id %6lld: [%4lld] %s "), 2807 (ll_t) ditem->id, (ll_t) ditem->get_size (), 2808 ditem->get_name ()); 2809 if (master != NULL) 2810 fprintf (out, NTXT (" master=%lld "), (ll_t) master->id); 2811 else if (scope != NULL) 2812 fprintf (out, NTXT (" master=?? ")); 2813 else 2814 fprintf (out, NTXT (" MASTER ")); 2815#if DEBUG 2816 if (scope != NULL) 2817 { 2818 switch (scope->get_type ()) 2819 { 2820 case Histable::LOADOBJECT: 2821 case Histable::FUNCTION: 2822 fprintf (out, NTXT ("%s"), scope->get_name ()); 2823 break; 2824 case Histable::MODULE: 2825 { 2826 char *filename = get_basename (scope->get_name ()); 2827 fprintf (out, NTXT ("%s"), filename); 2828 break; 2829 } 2830 default: 2831 fprintf (out, NTXT (" Unexpected scope %d:%s"), 2832 scope->get_type (), scope->get_name ()); 2833 } 2834 } 2835#endif 2836 fprintf (out, NTXT ("\n")); 2837 } 2838 } 2839} 2840 2841void 2842DbeSession::dump_map (FILE *out) 2843{ 2844 Experiment *exp; 2845 int index; 2846 Vec_loop (Experiment*, exps, index, exp) 2847 { 2848 exp->dump_map (out); 2849 } 2850} 2851 2852void 2853DbeSession::dump_stacks (FILE *outfile) 2854{ 2855 Experiment *exp; 2856 int n = nexps (); 2857 FILE *f = (outfile == NULL ? stderr : outfile); 2858 for (int i = 0; i < n; i++) 2859 { 2860 exp = get_exp (i); 2861 fprintf (f, GTXT ("Experiment %d -- %s\n"), i, exp->get_expt_name ()); 2862 exp->dump_stacks (f); 2863 } 2864} 2865 2866void 2867DbeSession::propNames_name_store (int propId, const char *propName) 2868{ 2869 PropDescr *prop = new PropDescr (propId, propName); 2870 prop->flags = PRFLAG_NOSHOW; // do not show descriptions 2871 propNames->store (propId, prop); 2872} 2873 2874void 2875DbeSession::propNames_name_store (int propId, const char* propName, 2876 const char* propUname, VType_type dataType, 2877 int flags) 2878{ 2879 PropDescr *prop = new PropDescr (propId, propName); 2880 prop->vtype = dataType; 2881 prop->uname = dbe_strdup (propUname); 2882 prop->flags = flags; 2883 propNames->store (propId, prop); 2884} 2885 2886char * 2887DbeSession::propNames_name_fetch (int i) 2888{ 2889 PropDescr *prop = propNames->fetch (i); 2890 if (prop) 2891 return prop->name; 2892 return NULL; 2893} 2894 2895int 2896DbeSession::registerPropertyName (const char *name) 2897{ 2898 if (name == NULL) 2899 return PROP_NONE; 2900 for (int i = 0; i < propNames->size (); i++) 2901 { 2902 char *pname = propNames_name_fetch (i); 2903 if (pname && strcasecmp (pname, name) == 0) 2904 return i; 2905 } 2906 int propId = propNames->size (); 2907 propNames_name_store (propId, name); 2908 return propId; 2909} 2910 2911int 2912DbeSession::getPropIdByName (const char *name) 2913{ 2914 if (name == NULL) 2915 return PROP_NONE; 2916 for (int i = 0; i < propNames->size (); i++) 2917 { 2918 char *pname = propNames_name_fetch (i); 2919 if (pname && strcasecmp (pname, name) == 0) 2920 return i; 2921 } 2922 return PROP_NONE; 2923} 2924 2925char * 2926DbeSession::getPropName (int propId) 2927{ 2928 if (!propNames) 2929 return NULL; 2930 if (propId < 0 || propId >= propNames->size ()) 2931 return NULL; 2932 return dbe_strdup (propNames_name_fetch (propId)); 2933} 2934 2935char * 2936DbeSession::getPropUName (int propId) 2937{ 2938 if (!propNames) 2939 return NULL; 2940 if (propId < 0 || propId >= propNames->size ()) 2941 return NULL; 2942 PropDescr *prop = propNames->fetch (propId); 2943 if (prop) 2944 return dbe_strdup (prop->uname); 2945 return NULL; 2946} 2947 2948void 2949DbeSession::append (UserLabel *lbl) 2950{ 2951 if (lbl->expr) 2952 { 2953 if (userLabels == NULL) 2954 userLabels = new Vector<UserLabel*> (); 2955 userLabels->append (lbl); 2956 } 2957} 2958 2959void 2960DbeSession::append (SourceFile *sf) 2961{ 2962 sources->append (sf); 2963 objs->append (sf); 2964} 2965 2966UserLabel * 2967DbeSession::findUserLabel (const char *name) 2968{ 2969 for (int i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++) 2970 { 2971 UserLabel *lbl = userLabels->fetch (i); 2972 if (strcasecmp (lbl->name, name) == 0) 2973 return lbl; 2974 } 2975 return NULL; 2976} 2977 2978Expression * 2979DbeSession::findObjDefByName (const char *name) 2980{ 2981 Expression *expr = NULL; 2982 2983 MemObjType_t *mot = MemorySpace::findMemSpaceByName (name); 2984 if (mot != NULL) 2985 { 2986 char *index_expr_str = mot->index_expr; 2987 expr = ql_parse (index_expr_str); 2988 } 2989 2990 if (expr == NULL) 2991 { 2992 int indxtype = findIndexSpaceByName (name); 2993 expr = getIndexSpaceExpr (indxtype); 2994 } 2995 if (expr == NULL) 2996 { 2997 UserLabel *ulbl = findUserLabel (name); 2998 if (ulbl) 2999 expr = ulbl->expr; 3000 } 3001 return expr; 3002} 3003 3004Expression * 3005DbeSession::ql_parse (const char *expr_spec) 3006{ 3007 if (expr_spec == NULL) 3008 expr_spec = ""; 3009 QL::Result result (expr_spec); 3010 QL::Parser qlparser (result); 3011 if (qlparser.parse () != 0) 3012 return NULL; 3013 return result (); 3014} 3015 3016Vector<void*> * 3017DbeSession::getIndxObjDescriptions () 3018{ 3019 int size = dyn_indxobj_indx; 3020 if (size == 0) 3021 return NULL; 3022 Vector<int> *type = new Vector<int>(dyn_indxobj_indx); 3023 Vector<char*> *desc = new Vector<char*>(dyn_indxobj_indx); 3024 Vector<char*> *i18ndesc = new Vector<char*>(dyn_indxobj_indx); 3025 Vector<char> *mnemonic = new Vector<char>(dyn_indxobj_indx); 3026 Vector<int> *orderList = new Vector<int>(dyn_indxobj_indx); 3027 Vector<char*> *exprList = new Vector<char*>(dyn_indxobj_indx); 3028 Vector<char*> *sdesc = new Vector<char*>(dyn_indxobj_indx); 3029 Vector<char*> *ldesc = new Vector<char*>(dyn_indxobj_indx); 3030 3031 for (long i = 0, sz = VecSize (dyn_indxobj); i < sz; i++) 3032 { 3033 IndexObjType_t *tot = dyn_indxobj->get (i); 3034 if (tot->memObj == NULL) 3035 { 3036 type->append ((int) tot->type); 3037 desc->append (dbe_strdup (tot->name)); 3038 i18ndesc->append (dbe_strdup (tot->i18n_name)); 3039 sdesc->append (dbe_strdup (tot->short_description)); 3040 ldesc->append (dbe_strdup (tot->long_description)); 3041 mnemonic->append (tot->mnemonic); 3042 orderList->append (settings->indx_tab_order->fetch (i)); 3043 exprList->append (dbe_strdup (tot->index_expr_str)); 3044 } 3045 } 3046 Vector<void*> *res = new Vector<void*>(8); 3047 res->store (0, type); 3048 res->store (1, desc); 3049 res->store (2, mnemonic); 3050 res->store (3, i18ndesc); 3051 res->store (4, orderList); 3052 res->store (5, exprList); 3053 res->store (6, sdesc); 3054 res->store (7, ldesc); 3055 return (res); 3056} 3057 3058// Static function to get a vector of custom index object definitions 3059Vector<void*> * 3060DbeSession::getCustomIndxObjects () 3061{ 3062 Vector<char*> *name = new Vector<char*>; 3063 Vector<char*> *formula = new Vector<char*>; 3064 for (long i = dyn_indxobj_indx_fixed, sz = VecSize (dyn_indxobj); i < sz; i++) 3065 { 3066 IndexObjType_t *tot = dyn_indxobj->get (i); 3067 if (tot->memObj == NULL) 3068 { 3069 name->append (dbe_strdup (tot->name)); 3070 formula->append (dbe_strdup (tot->index_expr_str)); 3071 } 3072 } 3073 Vector<void*> *res = new Vector<void*>(2); 3074 res->store (0, name); 3075 res->store (1, formula); 3076 return (res); 3077} 3078 3079// Static function to define a new index object type 3080char * 3081DbeSession::indxobj_define (const char *mname, char *i18nname, const char *index_expr_str, char *short_description, char *long_description) 3082{ 3083 if (mname == NULL) 3084 return dbe_strdup (GTXT ("No index object type name has been specified.")); 3085 if (isalpha ((int) (mname[0])) == 0) 3086 return dbe_sprintf (GTXT ("Index Object type name %s does not begin with an alphabetic character"), 3087 mname); 3088 const char *p = mname; 3089 while (*p != 0) 3090 { 3091 if ((isalnum ((int) (*p)) == 0) && (*p != '_')) 3092 return dbe_sprintf (GTXT ("Index Object type name %s contains a non-alphanumeric character"), 3093 mname); 3094 p++; 3095 } 3096 3097 // make sure the name is not in use 3098 if (MemorySpace::findMemSpaceByName (mname) != NULL) 3099 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"), 3100 mname); 3101 3102 int idxx = findIndexSpaceByName (mname); 3103 if (idxx >= 0) 3104 { 3105 IndexObjType_t *mt = dyn_indxobj->fetch (idxx); 3106 if (strcmp (mt->index_expr_str, index_expr_str) == 0) 3107 // It's a redefinition, but the new definition is the same 3108 return NULL; 3109 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"), 3110 mname); 3111 } 3112 if (index_expr_str == NULL) 3113 return dbe_strdup (GTXT ("No index-expr has been specified.")); 3114 if (strlen (index_expr_str) == 0) 3115 return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"), 3116 index_expr_str); 3117 3118 // verify that the index expression parses correctly 3119 char *expr_str = dbe_strdup (index_expr_str); 3120 Expression *expr = ql_parse (expr_str); 3121 if (expr == NULL) 3122 return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"), 3123 expr_str); 3124 3125 // It's OK, create the new table entry 3126 IndexObjType_t *tot = new IndexObjType_t; 3127 tot->type = dyn_indxobj_indx++; 3128 tot->name = dbe_strdup (mname); 3129 tot->i18n_name = dbe_strdup (i18nname); 3130 tot->short_description = dbe_strdup (short_description); 3131 tot->long_description = dbe_strdup (long_description); 3132 tot->index_expr_str = expr_str; 3133 tot->index_expr = expr; 3134 tot->mnemonic = mname[0]; 3135 3136 // add it to the list 3137 dyn_indxobj->append (tot); 3138 idxobjs->append (new HashMap<uint64_t, Histable*>); 3139 3140 // tell the session 3141 settings->indxobj_define (tot->type, false); 3142 3143 DbeView *dbev; 3144 int index; 3145 Vec_loop (DbeView*, views, index, dbev) 3146 { 3147 dbev->addIndexSpace (tot->type); 3148 } 3149 return NULL; 3150} 3151 3152char * 3153DbeSession::getIndexSpaceName (int index) 3154{ 3155 if (index < 0 || index >= dyn_indxobj->size ()) 3156 return NULL; 3157 return dyn_indxobj->fetch (index)->name; 3158} 3159 3160char * 3161DbeSession::getIndexSpaceDescr (int index) 3162{ 3163 if (index < 0 || index >= dyn_indxobj->size ()) 3164 return NULL; 3165 return dyn_indxobj->fetch (index)->i18n_name; 3166} 3167 3168Expression * 3169DbeSession::getIndexSpaceExpr (int index) 3170{ 3171 if (index < 0 || index >= dyn_indxobj->size ()) 3172 return NULL; 3173 return dyn_indxobj->fetch (index)->index_expr; 3174} 3175 3176char * 3177DbeSession::getIndexSpaceExprStr (int index) 3178{ 3179 if (index < 0 || index >= dyn_indxobj->size ()) 3180 return NULL; 3181 return dyn_indxobj->fetch (index)->index_expr_str; 3182} 3183 3184int 3185DbeSession::findIndexSpaceByName (const char *mname) 3186{ 3187 int idx; 3188 IndexObjType_t *mt; 3189 Vec_loop (IndexObjType_t*, dyn_indxobj, idx, mt) 3190 { 3191 if (strcasecmp (mt->name, mname) == 0) 3192 return idx; 3193 } 3194 return -1; 3195} 3196 3197void 3198DbeSession::removeIndexSpaceByName (const char *mname) 3199{ 3200 IndexObjType_t *indObj = findIndexSpace (mname); 3201 if (indObj) 3202 indObj->name[0] = 0; 3203} 3204 3205IndexObjType_t * 3206DbeSession::getIndexSpace (int index) 3207{ 3208 return ((index < 0) || (index >= VecSize (dyn_indxobj))) ? NULL : dyn_indxobj->get (index); 3209} 3210 3211IndexObjType_t * 3212DbeSession::findIndexSpace (const char *mname) 3213{ 3214 return getIndexSpace (findIndexSpaceByName (mname)); 3215} 3216 3217void 3218DbeSession::get_filter_keywords (Vector<void*> *res) 3219{ 3220 Vector <char*> *kwCategory = (Vector<char*>*) res->fetch (0); 3221 Vector <char*> *kwCategoryI18N = (Vector<char*>*) res->fetch (1); 3222 Vector <char*> *kwDataType = (Vector<char*>*) res->fetch (2); 3223 Vector <char*> *kwKeyword = (Vector<char*>*) res->fetch (3); 3224 Vector <char*> *kwFormula = (Vector<char*>*) res->fetch (4); 3225 Vector <char*> *kwDescription = (Vector<char*>*) res->fetch (5); 3226 Vector <void*> *kwEnumDescs = (Vector<void*>*) res->fetch (6); 3227 3228 char *vtypeNames[] = VTYPE_TYPE_NAMES; 3229 for (long i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++) 3230 { 3231 UserLabel *lbl = userLabels->fetch (i); 3232 kwCategory->append (dbe_strdup (NTXT ("FK_LABEL"))); 3233 kwCategoryI18N->append (dbe_strdup (GTXT ("Labels"))); 3234 kwDataType->append (dbe_strdup (vtypeNames[TYPE_BOOL])); 3235 kwKeyword->append (dbe_strdup (lbl->name)); 3236 kwFormula->append (dbe_strdup (lbl->str_expr)); 3237 kwDescription->append (dbe_strdup (lbl->comment)); 3238 kwEnumDescs->append (NULL); 3239 } 3240 3241 for (long i = 0, sz = propNames ? propNames->size () : 0; i < sz; i++) 3242 { 3243 PropDescr *prop = propNames->fetch (i); 3244 char *pname = prop ? prop->name : NULL; 3245 if (pname == NULL || *pname == 0 || prop->flags & PRFLAG_NOSHOW) 3246 continue; 3247 int vtypeNum = prop->vtype; 3248 if (vtypeNum < 0 || vtypeNum >= TYPE_LAST) 3249 vtypeNum = TYPE_NONE; 3250 kwCategory->append (dbe_strdup (NTXT ("FK_EVTPROP"))); //Event Property 3251 kwCategoryI18N->append (dbe_strdup (GTXT ("Misc. Definitions"))); 3252 kwDataType->append (dbe_strdup (vtypeNames[vtypeNum])); 3253 kwKeyword->append (dbe_strdup (pname)); 3254 kwFormula->append (NULL); 3255 kwDescription->append (dbe_strdup (prop->uname)); 3256 kwEnumDescs->append (NULL); 3257 } 3258 3259 for (long i = 0, sz = dyn_indxobj ? dyn_indxobj->size () : 0; i < sz; i++) 3260 { 3261 IndexObjType_t *obj = dyn_indxobj->get (i); 3262 if (obj->memObj) 3263 continue; 3264 kwCategory->append (dbe_strdup (NTXT ("FK_IDXOBJ"))); 3265 kwCategoryI18N->append (dbe_strdup (GTXT ("Index Object Definitions"))); 3266 kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT64])); 3267 kwKeyword->append (dbe_strdup (obj->name)); 3268 kwFormula->append (dbe_strdup (obj->index_expr_str)); 3269 kwDescription->append (dbe_strdup (obj->i18n_name)); 3270 kwEnumDescs->append (NULL); 3271 } 3272} 3273 3274Histable * 3275DbeSession::findIndexObject (int idxtype, uint64_t idx) 3276{ 3277 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype); 3278 return iobjs->get (idx); 3279} 3280 3281Histable * 3282DbeSession::createIndexObject (int idxtype, int64_t idx) 3283{ 3284 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype); 3285 3286 Histable *idxobj = iobjs->get (idx); 3287 if (idxobj == NULL) 3288 { 3289 idxobj = new IndexObject (idxtype, idx); 3290 if (idx == -1) 3291 idxobj->set_name (dbe_strdup (GTXT ("<Unknown>"))); 3292 iobjs->put (idx, idxobj); 3293 } 3294 3295 return idxobj; 3296} 3297 3298Histable * 3299DbeSession::createIndexObject (int idxtype, Histable *hobj) 3300{ 3301 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype); 3302 int64_t idx = hobj ? hobj->id : -1; 3303 Histable *idxobj = iobjs->get (idx); 3304 if (idxobj == NULL) 3305 { 3306 idxobj = new IndexObject (idxtype, hobj); 3307 if (idx == -1) 3308 idxobj->set_name (dbe_strdup (GTXT ("<Unknown>"))); 3309 iobjs->put (idx, idxobj); 3310 } 3311 3312 return idxobj; 3313} 3314 3315Histable * 3316DbeSession::findObjectById (Histable::Type type, int subtype, uint64_t id) 3317{ 3318 switch (type) 3319 { 3320 case Histable::FUNCTION: 3321 case Histable::MODULE: 3322 case Histable::LOADOBJECT: 3323 return ( id < (uint64_t) objs->size ()) ? objs->fetch ((int) id) : NULL; 3324 case Histable::INDEXOBJ: 3325 return findIndexObject (subtype, id); 3326 // ignoring the following cases 3327 case Histable::INSTR: 3328 case Histable::LINE: 3329 case Histable::EADDR: 3330 case Histable::MEMOBJ: 3331 case Histable::PAGE: 3332 case Histable::DOBJECT: 3333 case Histable::SOURCEFILE: 3334 case Histable::IOACTFILE: 3335 case Histable::IOACTVFD: 3336 case Histable::IOCALLSTACK: 3337 case Histable::HEAPCALLSTACK: 3338 case Histable::OTHER: 3339 case Histable::EXPERIMENT: 3340 break; 3341 } 3342 return NULL; 3343} 3344 3345// return a vector of Functions that match the regular expression input string 3346Vector<JThread *> * 3347DbeSession::match_java_threads (char *ustr, int matchParent, 3348 Vector<uint64_t> * &grids, 3349 Vector<uint64_t> * &expids) 3350{ 3351 if (ustr == NULL) 3352 return NULL; 3353 3354 char *str = dbe_sprintf (NTXT ("^%s$"), ustr); 3355 regex_t regex_desc; 3356 int rc = regcomp (®ex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE); 3357 free (str); 3358 if (rc) // syntax error in parsing string 3359 return NULL; 3360 3361 // allocate the new vector 3362 Vector<JThread *> *ret = new Vector<JThread*>; 3363 grids = new Vector<uint64_t>; 3364 expids = new Vector<uint64_t>; 3365 3366 int index; 3367 JThread *jthread; 3368 int expid; 3369 Experiment* exp; 3370 Vec_loop (Experiment*, exps, expid, exp) 3371 { 3372 3373 Vec_loop (JThread*, exp->get_jthreads (), index, jthread) 3374 { 3375 const char * name; 3376 if (matchParent) 3377 name = jthread->parent_name; 3378 else 3379 name = jthread->group_name; 3380 if (name == NULL) 3381 name = ""; 3382 if (!regexec (®ex_desc, name, 0, NULL, 0)) 3383 { 3384 // this one matches 3385 ret->append (jthread); 3386 grids->append (exp->groupId); 3387 expids->append (exp->getUserExpId ()); 3388 } 3389 } 3390 } 3391 3392 regfree (®ex_desc); 3393 return ret; 3394} 3395 3396// return a vector of Functions that match the regular expression input string 3397Vector<Function *> * 3398DbeSession::match_func_names (const char *ustr, Histable::NameFormat nfmt) 3399{ 3400 if (ustr == NULL) 3401 return NULL; 3402 char *str = dbe_sprintf (NTXT ("^%s$"), ustr); 3403 regex_t regex_desc; 3404 int rc = regcomp (®ex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE); 3405 free (str); 3406 if (rc) // syntax error in parsing string 3407 return NULL; 3408 3409 // allocate the new vector 3410 Vector<Function *> *ret = new Vector<Function*>; 3411 3412 int index; 3413 Histable *obj; 3414 Vec_loop (Histable*, objs, index, obj) 3415 { 3416 if (obj->get_type () == Histable::FUNCTION) 3417 { 3418 Function *func = (Function*) obj; 3419 if (!regexec (®ex_desc, func->get_name (nfmt), 0, NULL, 0)) 3420 // this one matches 3421 ret->append (func); 3422 } 3423 } 3424 regfree (®ex_desc); 3425 return ret; 3426} 3427 3428// return a vector of Functions that match the regular expression input string 3429Vector<FileData *> * 3430DbeSession::match_file_names (char *ustr, Histable::NameFormat nfmt) 3431{ 3432 if (ustr == NULL) 3433 return NULL; 3434 char *str = dbe_sprintf (NTXT ("^%s$"), ustr); 3435 regex_t regex_desc; 3436 int rc = regcomp (®ex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE); 3437 free (str); 3438 if (rc) // syntax error in parsing string 3439 return NULL; 3440 3441 // allocate the new vector 3442 Vector<FileData *> *ret = new Vector<FileData*>; 3443 int numExps = nexps (); 3444 DefaultMap<int64_t, FileData*>* fDataMap; 3445 Vector<FileData *> *fDataObjs; 3446 FileData *fData; 3447 int size; 3448 for (int i = 0; i < numExps; i++) 3449 { 3450 Experiment *exp = get_exp (i); 3451 fDataMap = exp->getFDataMap (); 3452 fDataObjs = fDataMap->values (); 3453 size = fDataObjs->size (); 3454 for (int j = 0; j < size; j++) 3455 { 3456 fData = fDataObjs->fetch (j); 3457 if (fData 3458 && !regexec (®ex_desc, fData->get_raw_name (nfmt), 0, NULL, 0)) 3459 // this one matches 3460 ret->append (fData); 3461 } 3462 } 3463 regfree (®ex_desc); 3464 return ret; 3465} 3466 3467// return a vector of DataObjects that match the regular expression input string 3468Vector<DataObject *> * 3469DbeSession::match_dobj_names (char *ustr) 3470{ 3471 if (ustr == NULL) 3472 return NULL; 3473 char *str = dbe_sprintf (NTXT ("^%s$"), ustr); 3474 regex_t regex_desc; 3475 int rc = regcomp (®ex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE); 3476 free (str); 3477 if (rc) // syntax error in parsing string 3478 return NULL; 3479 3480 // allocate the new vector 3481 Vector<DataObject *> *ret = new Vector<DataObject*>; 3482 int index; 3483 DataObject *ditem; 3484 Vec_loop (DataObject*, dobjs, index, ditem) 3485 { 3486 // does this one match 3487 if (!regexec (®ex_desc, ditem->get_name (), 0, NULL, 0)) 3488 // this one matches 3489 ret->append (ditem); 3490 } 3491 regfree (®ex_desc); 3492 return ret; 3493} 3494 3495void 3496DbeSession::dump (char *msg, Vector<BaseMetric*> *mlist) 3497{ 3498 if (msg) 3499 fprintf (stderr, "%s\n", msg); 3500 int sz = mlist ? mlist->size () : -1; 3501 for (int i = 0; i < sz; i++) 3502 { 3503 BaseMetric *m = mlist->fetch (i); 3504 char *s = m->dump (); 3505 fprintf (stderr, "%2d %s\n", i, s); 3506 free (s); 3507 } 3508 fprintf (stderr, "======END of mlist[%d] =========\n", sz); 3509} 3510 3511void 3512DbeSession::dump (char *msg, Vector<Metric*> *mlist) 3513{ 3514 if (msg) 3515 fprintf (stderr, "%s\n", msg); 3516 int sz = mlist ? mlist->size () : -1; 3517 for (int i = 0; i < sz; i++) 3518 { 3519 Metric *m = mlist->fetch (i); 3520 char *s = m->dump (); 3521 fprintf (stderr, "%2d %s\n", i, s); 3522 free (s); 3523 } 3524 fprintf (stderr, "======END of mlist[%d] =========\n", sz); 3525} 3526