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