1 /* Copyright (C) 2021-2024 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 "CallStack.h" 23 #include "DbeSession.h" 24 #include "Exp_Layout.h" 25 #include "Experiment.h" 26 #include "Function.h" 27 #include "Table.h" 28 #include "dbe_types.h" 29 #include "util.h" 30 31 /* 32 * PrUsage is a class which wraps access to the values of prusage 33 * system structure. It was expanded to 64 bit entities in 2.7 34 * (experiment version 6 & 7). 35 */ 36 PrUsage::PrUsage () 37 { 38 pr_tstamp = pr_create = pr_term = pr_rtime = (hrtime_t) 0; 39 pr_utime = pr_stime = pr_ttime = pr_tftime = pr_dftime = (hrtime_t) 0; 40 pr_kftime = pr_ltime = pr_slptime = pr_wtime = pr_stoptime = (hrtime_t) 0; 41 42 pr_minf = pr_majf = pr_nswap = pr_inblk = pr_oublk = 0; 43 pr_msnd = pr_mrcv = pr_sigs = pr_vctx = pr_ictx = pr_sysc = pr_ioch = 0; 44 } 45 46 /* 47 * Resource usage. /proc/<pid>/usage /proc/<pid>/lwp/<lwpid>/lwpusage 48 */ 49 struct timestruc_32 50 { /* v8 timestruc_t */ 51 uint32_t tv_sec; /* seconds */ 52 uint32_t tv_nsec; /* and nanoseconds */ 53 }; 54 55 typedef struct ana_prusage 56 { 57 id_t pr_lwpid; /* lwp id. 0: process or defunct */ 58 int pr_count; /* number of contributing lwps */ 59 timestruc_32 pr_tstamp; /* current time stamp */ 60 timestruc_32 pr_create; /* process/lwp creation time stamp */ 61 timestruc_32 pr_term; /* process/lwp termination time stamp */ 62 timestruc_32 pr_rtime; /* total lwp real (elapsed) time */ 63 timestruc_32 pr_utime; /* user level cpu time */ 64 timestruc_32 pr_stime; /* system call cpu time */ 65 timestruc_32 pr_ttime; /* other system trap cpu time */ 66 timestruc_32 pr_tftime; /* text page fault sleep time */ 67 timestruc_32 pr_dftime; /* data page fault sleep time */ 68 timestruc_32 pr_kftime; /* kernel page fault sleep time */ 69 timestruc_32 pr_ltime; /* user lock wait sleep time */ 70 timestruc_32 pr_slptime; /* all other sleep time */ 71 timestruc_32 pr_wtime; /* wait-cpu (latency) time */ 72 timestruc_32 pr_stoptime; /* stopped time */ 73 timestruc_32 filltime[6]; /* filler for future expansion */ 74 uint32_t pr_minf; /* minor page faults */ 75 uint32_t pr_majf; /* major page faults */ 76 uint32_t pr_nswap; /* swaps */ 77 uint32_t pr_inblk; /* input blocks */ 78 uint32_t pr_oublk; /* output blocks */ 79 uint32_t pr_msnd; /* messages sent */ 80 uint32_t pr_mrcv; /* messages received */ 81 uint32_t pr_sigs; /* signals received */ 82 uint32_t pr_vctx; /* voluntary context switches */ 83 uint32_t pr_ictx; /* involuntary context switches */ 84 uint32_t pr_sysc; /* system calls */ 85 uint32_t pr_ioch; /* chars read and written */ 86 uint32_t filler[10]; /* filler for future expansion */ 87 } raw_prusage_32; 88 89 uint64_t 90 PrUsage::bind32Size () 91 { 92 uint64_t bindSize = sizeof (raw_prusage_32); 93 return bindSize; 94 } 95 96 #define timestruc2hr(x) ((hrtime_t)(x).tv_sec*NANOSEC + (hrtime_t)(x).tv_nsec) 97 98 PrUsage * 99 PrUsage::bind32 (void *p, bool need_swap_endian) 100 { 101 if (p == NULL) 102 return NULL; 103 raw_prusage_32 pu, *tmp = (raw_prusage_32*) p; 104 if (need_swap_endian) 105 { 106 pu = *tmp; 107 tmp = &pu; 108 SWAP_ENDIAN (pu.pr_tstamp.tv_sec); 109 SWAP_ENDIAN (pu.pr_tstamp.tv_nsec); 110 SWAP_ENDIAN (pu.pr_create.tv_sec); 111 SWAP_ENDIAN (pu.pr_create.tv_nsec); 112 SWAP_ENDIAN (pu.pr_term.tv_sec); 113 SWAP_ENDIAN (pu.pr_term.tv_nsec); 114 SWAP_ENDIAN (pu.pr_rtime.tv_sec); 115 SWAP_ENDIAN (pu.pr_rtime.tv_nsec); 116 SWAP_ENDIAN (pu.pr_utime.tv_sec); 117 SWAP_ENDIAN (pu.pr_utime.tv_nsec); 118 SWAP_ENDIAN (pu.pr_stime.tv_sec); 119 SWAP_ENDIAN (pu.pr_stime.tv_nsec); 120 SWAP_ENDIAN (pu.pr_ttime.tv_sec); 121 SWAP_ENDIAN (pu.pr_ttime.tv_nsec); 122 SWAP_ENDIAN (pu.pr_tftime.tv_sec); 123 SWAP_ENDIAN (pu.pr_tftime.tv_nsec); 124 SWAP_ENDIAN (pu.pr_dftime.tv_sec); 125 SWAP_ENDIAN (pu.pr_dftime.tv_nsec); 126 SWAP_ENDIAN (pu.pr_kftime.tv_sec); 127 SWAP_ENDIAN (pu.pr_kftime.tv_nsec); 128 SWAP_ENDIAN (pu.pr_ltime.tv_sec); 129 SWAP_ENDIAN (pu.pr_ltime.tv_nsec); 130 SWAP_ENDIAN (pu.pr_slptime.tv_sec); 131 SWAP_ENDIAN (pu.pr_slptime.tv_nsec); 132 SWAP_ENDIAN (pu.pr_wtime.tv_sec); 133 SWAP_ENDIAN (pu.pr_wtime.tv_nsec); 134 SWAP_ENDIAN (pu.pr_stoptime.tv_sec); 135 SWAP_ENDIAN (pu.pr_stoptime.tv_nsec); 136 SWAP_ENDIAN (pu.pr_minf); 137 SWAP_ENDIAN (pu.pr_majf); 138 SWAP_ENDIAN (pu.pr_nswap); 139 SWAP_ENDIAN (pu.pr_inblk); 140 SWAP_ENDIAN (pu.pr_oublk); 141 SWAP_ENDIAN (pu.pr_msnd); 142 SWAP_ENDIAN (pu.pr_mrcv); 143 SWAP_ENDIAN (pu.pr_sigs); 144 SWAP_ENDIAN (pu.pr_vctx); 145 SWAP_ENDIAN (pu.pr_ictx); 146 SWAP_ENDIAN (pu.pr_sysc); 147 SWAP_ENDIAN (pu.pr_ioch); 148 } 149 pr_tstamp = timestruc2hr (tmp->pr_tstamp); 150 pr_create = timestruc2hr (tmp->pr_create); 151 pr_term = timestruc2hr (tmp->pr_term); 152 pr_rtime = timestruc2hr (tmp->pr_rtime); 153 pr_utime = timestruc2hr (tmp->pr_utime); 154 pr_stime = timestruc2hr (tmp->pr_stime); 155 pr_ttime = timestruc2hr (tmp->pr_ttime); 156 pr_tftime = timestruc2hr (tmp->pr_tftime); 157 pr_dftime = timestruc2hr (tmp->pr_dftime); 158 pr_kftime = timestruc2hr (tmp->pr_kftime); 159 pr_ltime = timestruc2hr (tmp->pr_ltime); 160 pr_slptime = timestruc2hr (tmp->pr_slptime); 161 pr_wtime = timestruc2hr (tmp->pr_wtime); 162 pr_stoptime = timestruc2hr (tmp->pr_stoptime); 163 pr_minf = tmp->pr_minf; 164 pr_majf = tmp->pr_majf; 165 pr_nswap = tmp->pr_nswap; 166 pr_inblk = tmp->pr_inblk; 167 pr_oublk = tmp->pr_oublk; 168 pr_msnd = tmp->pr_msnd; 169 pr_mrcv = tmp->pr_mrcv; 170 pr_sigs = tmp->pr_sigs; 171 pr_vctx = tmp->pr_vctx; 172 pr_ictx = tmp->pr_ictx; 173 pr_sysc = tmp->pr_sysc; 174 pr_ioch = tmp->pr_ioch; 175 return this; 176 } 177 178 struct timestruc_64 179 { /* 64-bit timestruc_t */ 180 uint64_t tv_sec; /* seconds */ 181 uint64_t tv_nsec; /* and nanoseconds */ 182 }; 183 184 typedef struct 185 { 186 id_t pr_lwpid; /* lwp id. 0: process or defunct */ 187 int pr_count; /* number of contributing lwps */ 188 timestruc_64 pr_tstamp; /* current time stamp */ 189 timestruc_64 pr_create; /* process/lwp creation time stamp */ 190 timestruc_64 pr_term; /* process/lwp termination time stamp */ 191 timestruc_64 pr_rtime; /* total lwp real (elapsed) time */ 192 timestruc_64 pr_utime; /* user level cpu time */ 193 timestruc_64 pr_stime; /* system call cpu time */ 194 timestruc_64 pr_ttime; /* other system trap cpu time */ 195 timestruc_64 pr_tftime; /* text page fault sleep time */ 196 timestruc_64 pr_dftime; /* data page fault sleep time */ 197 timestruc_64 pr_kftime; /* kernel page fault sleep time */ 198 timestruc_64 pr_ltime; /* user lock wait sleep time */ 199 timestruc_64 pr_slptime; /* all other sleep time */ 200 timestruc_64 pr_wtime; /* wait-cpu (latency) time */ 201 timestruc_64 pr_stoptime; /* stopped time */ 202 timestruc_64 filltime[6]; /* filler for future expansion */ 203 uint64_t pr_minf; /* minor page faults */ 204 uint64_t pr_majf; /* major page faults */ 205 uint64_t pr_nswap; /* swaps */ 206 uint64_t pr_inblk; /* input blocks */ 207 uint64_t pr_oublk; /* output blocks */ 208 uint64_t pr_msnd; /* messages sent */ 209 uint64_t pr_mrcv; /* messages received */ 210 uint64_t pr_sigs; /* signals received */ 211 uint64_t pr_vctx; /* voluntary context switches */ 212 uint64_t pr_ictx; /* involuntary context switches */ 213 uint64_t pr_sysc; /* system calls */ 214 uint64_t pr_ioch; /* chars read and written */ 215 uint64_t filler[10]; /* filler for future expansion */ 216 } raw_prusage_64; 217 218 uint64_t 219 PrUsage::bind64Size () 220 { 221 uint64_t bindSize = sizeof (raw_prusage_64); 222 return bindSize; 223 } 224 225 PrUsage * 226 PrUsage::bind64 (void *p, bool need_swap_endian) 227 { 228 if (p == NULL) 229 { 230 return NULL; 231 } 232 raw_prusage_64 pu, *tmp = (raw_prusage_64*) p; 233 if (need_swap_endian) 234 { 235 pu = *tmp; 236 tmp = &pu; 237 SWAP_ENDIAN (pu.pr_tstamp.tv_sec); 238 SWAP_ENDIAN (pu.pr_tstamp.tv_nsec); 239 SWAP_ENDIAN (pu.pr_create.tv_sec); 240 SWAP_ENDIAN (pu.pr_create.tv_nsec); 241 SWAP_ENDIAN (pu.pr_term.tv_sec); 242 SWAP_ENDIAN (pu.pr_term.tv_nsec); 243 SWAP_ENDIAN (pu.pr_rtime.tv_sec); 244 SWAP_ENDIAN (pu.pr_rtime.tv_nsec); 245 SWAP_ENDIAN (pu.pr_utime.tv_sec); 246 SWAP_ENDIAN (pu.pr_utime.tv_nsec); 247 SWAP_ENDIAN (pu.pr_stime.tv_sec); 248 SWAP_ENDIAN (pu.pr_stime.tv_nsec); 249 SWAP_ENDIAN (pu.pr_ttime.tv_sec); 250 SWAP_ENDIAN (pu.pr_ttime.tv_nsec); 251 SWAP_ENDIAN (pu.pr_tftime.tv_sec); 252 SWAP_ENDIAN (pu.pr_tftime.tv_nsec); 253 SWAP_ENDIAN (pu.pr_dftime.tv_sec); 254 SWAP_ENDIAN (pu.pr_dftime.tv_nsec); 255 SWAP_ENDIAN (pu.pr_kftime.tv_sec); 256 SWAP_ENDIAN (pu.pr_kftime.tv_nsec); 257 SWAP_ENDIAN (pu.pr_ltime.tv_sec); 258 SWAP_ENDIAN (pu.pr_ltime.tv_nsec); 259 SWAP_ENDIAN (pu.pr_slptime.tv_sec); 260 SWAP_ENDIAN (pu.pr_slptime.tv_nsec); 261 SWAP_ENDIAN (pu.pr_wtime.tv_sec); 262 SWAP_ENDIAN (pu.pr_wtime.tv_nsec); 263 SWAP_ENDIAN (pu.pr_stoptime.tv_sec); 264 SWAP_ENDIAN (pu.pr_stoptime.tv_nsec); 265 SWAP_ENDIAN (pu.pr_minf); 266 SWAP_ENDIAN (pu.pr_majf); 267 SWAP_ENDIAN (pu.pr_nswap); 268 SWAP_ENDIAN (pu.pr_inblk); 269 SWAP_ENDIAN (pu.pr_oublk); 270 SWAP_ENDIAN (pu.pr_msnd); 271 SWAP_ENDIAN (pu.pr_mrcv); 272 SWAP_ENDIAN (pu.pr_sigs); 273 SWAP_ENDIAN (pu.pr_vctx); 274 SWAP_ENDIAN (pu.pr_ictx); 275 SWAP_ENDIAN (pu.pr_sysc); 276 SWAP_ENDIAN (pu.pr_ioch); 277 } 278 279 pr_tstamp = timestruc2hr (tmp->pr_tstamp); 280 pr_create = timestruc2hr (tmp->pr_create); 281 pr_term = timestruc2hr (tmp->pr_term); 282 pr_rtime = timestruc2hr (tmp->pr_rtime); 283 pr_utime = timestruc2hr (tmp->pr_utime); 284 pr_stime = timestruc2hr (tmp->pr_stime); 285 pr_ttime = timestruc2hr (tmp->pr_ttime); 286 pr_tftime = timestruc2hr (tmp->pr_tftime); 287 pr_dftime = timestruc2hr (tmp->pr_dftime); 288 pr_kftime = timestruc2hr (tmp->pr_kftime); 289 pr_ltime = timestruc2hr (tmp->pr_ltime); 290 pr_slptime = timestruc2hr (tmp->pr_slptime); 291 pr_wtime = timestruc2hr (tmp->pr_wtime); 292 pr_stoptime = timestruc2hr (tmp->pr_stoptime); 293 pr_minf = tmp->pr_minf; 294 pr_majf = tmp->pr_majf; 295 pr_nswap = tmp->pr_nswap; 296 pr_inblk = tmp->pr_inblk; 297 pr_oublk = tmp->pr_oublk; 298 pr_msnd = tmp->pr_msnd; 299 pr_mrcv = tmp->pr_mrcv; 300 pr_sigs = tmp->pr_sigs; 301 pr_vctx = tmp->pr_vctx; 302 pr_ictx = tmp->pr_ictx; 303 pr_sysc = tmp->pr_sysc; 304 pr_ioch = tmp->pr_ioch; 305 return this; 306 } 307 308 Vector<long long> * 309 PrUsage::getMstateValues () 310 { 311 const PrUsage *prusage = this; 312 Vector<long long> *states = new Vector<long long>; 313 states->store (0, prusage->pr_utime); 314 states->store (1, prusage->pr_stime); 315 states->store (2, prusage->pr_ttime); 316 states->store (3, prusage->pr_tftime); 317 states->store (4, prusage->pr_dftime); 318 states->store (5, prusage->pr_kftime); 319 states->store (6, prusage->pr_ltime); 320 states->store (7, prusage->pr_slptime); 321 states->store (8, prusage->pr_wtime); 322 states->store (9, prusage->pr_stoptime); 323 assert (LMS_NUM_SOLARIS_MSTATES == states->size ()); 324 return states; 325 } 326 327 void* CommonPacket::jvm_overhead = NULL; 328 329 CommonPacket::CommonPacket () 330 { 331 for (int i = 0; i < NTAGS; i++) 332 tags[i] = 0; 333 tstamp = 0; 334 jthread_TBR = NULL; 335 frinfo = 0; 336 leafpc = 0; 337 nat_stack = NULL; 338 user_stack = NULL; 339 } 340 341 int 342 CommonPacket::cmp (const void *a, const void *b) 343 { 344 if ((*(CommonPacket **) a)->tstamp > (*(CommonPacket **) b)->tstamp) 345 return 1; 346 else if ((*(CommonPacket **) a)->tstamp < (*(CommonPacket **) b)->tstamp) 347 return -1; 348 else 349 return 0; 350 } 351 352 void * 353 CommonPacket::getStack (VMode view_mode) 354 { 355 if (view_mode == VMODE_MACHINE) 356 return nat_stack; 357 else if (view_mode == VMODE_USER) 358 { 359 if (jthread_TBR == JTHREAD_NONE || (jthread_TBR && jthread_TBR->is_system ())) 360 return jvm_overhead; 361 } 362 else if (view_mode == VMODE_EXPERT) 363 { 364 Histable *hist = CallStack::getStackPC (user_stack, 0); 365 if (hist->get_type () == Histable::INSTR) 366 { 367 DbeInstr *instr = (DbeInstr*) hist; 368 if (instr->func == dbeSession->get_JUnknown_Function ()) 369 return nat_stack; 370 } 371 else if (hist->get_type () == Histable::LINE) 372 { 373 DbeLine *line = (DbeLine *) hist; 374 if (line->func == dbeSession->get_JUnknown_Function ()) 375 return nat_stack; 376 } 377 } 378 return user_stack; 379 } 380 381 Histable * 382 CommonPacket::getStackPC (int n, VMode view_mode) 383 { 384 return CallStack::getStackPC (getStack (view_mode), n); 385 } 386 387 Vector<Histable*> * 388 CommonPacket::getStackPCs (VMode view_mode) 389 { 390 return CallStack::getStackPCs (getStack (view_mode)); 391 } 392 393 void * 394 getStack (VMode view_mode, DataView *dview, long idx) 395 { 396 void *stack = NULL; 397 if (view_mode == VMODE_MACHINE) 398 stack = dview->getObjValue (PROP_MSTACK, idx); 399 else if (view_mode == VMODE_USER) 400 stack = dview->getObjValue (PROP_USTACK, idx); 401 else if (view_mode == VMODE_EXPERT) 402 stack = dview->getObjValue (PROP_XSTACK, idx); 403 return stack; 404 } 405 406 int 407 stackSize (VMode view_mode, DataView *dview, long idx) 408 { 409 return CallStack::stackSize (getStack (view_mode, dview, idx)); 410 } 411 412 Histable * 413 getStackPC (int n, VMode view_mode, DataView *dview, long idx) 414 { 415 return CallStack::getStackPC (getStack (view_mode, dview, idx), n); 416 } 417 418 Vector<Histable*> * 419 getStackPCs (VMode view_mode, DataView *dview, long idx) 420 { 421 return CallStack::getStackPCs (getStack (view_mode, dview, idx)); 422 } 423