libjvm_db.c revision 6759:ecdcd96f051a
1/* 2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <errno.h> 29#include <gelf.h> 30 31#include "libjvm_db.h" 32#include "JvmOffsets.h" 33 34#define LIBJVM_SO "libjvm.so" 35 36#if defined(i386) || defined(__i386) || defined(__amd64) 37#ifdef COMPILER2 38#define X86_COMPILER2 39#endif /* COMPILER2 */ 40#endif /* i386 */ 41 42typedef struct { 43 short vf_cnt; /* number of recognized java vframes */ 44 short bci; /* current frame method byte code index */ 45 int line; /* current frame method source line */ 46 uint64_t new_fp; /* fp for the next frame */ 47 uint64_t new_pc; /* pc for the next frame */ 48 uint64_t new_sp; /* "raw" sp for the next frame (includes extension by interpreter/adapter */ 49 char locinf; /* indicates there is valid location info */ 50} Jframe_t; 51 52int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name, 53 size_t size, Jframe_t *jframe); 54 55int main(int arg) { return arg; } 56 57static int debug = 0; 58 59static void failed(int err, const char * file, int line) { 60 if (debug) { 61 fprintf(stderr, "failed %d at %s:%d\n", err, file, line); 62 } 63} 64 65static void warn(const char * file, int line, const char * msg) { 66 if (debug) { 67 fprintf(stderr, "warning: %s at %s:%d\n", msg, file, line); 68 } 69} 70 71static void warn1(const char * file, int line, const char * msg, intptr_t arg1) { 72 if (debug) { 73 fprintf(stderr, "warning: "); 74 fprintf(stderr, msg, arg1); 75 fprintf(stderr, " at %s:%d\n", file, line); 76 } 77} 78 79#define CHECK_FAIL(err) \ 80 if (err != PS_OK) { failed(err, __FILE__, __LINE__); goto fail; } 81#define WARN(msg) warn(__FILE__, __LINE__, msg) 82#define WARN1(msg, arg1) warn1(__FILE__, __LINE__, msg, arg1) 83 84typedef struct VMStructEntry { 85 const char * typeName; /* The type name containing the given field (example: "Klass") */ 86 const char * fieldName; /* The field name within the type (example: "_name") */ 87 uint64_t address; /* Address of field; only used for static fields */ 88 /* ("offset" can not be reused because of apparent SparcWorks compiler bug */ 89 /* in generation of initializer data) */ 90} VMStructEntry; 91 92/* Prototyping inlined methods */ 93 94int sprintf(char *s, const char *format, ...); 95 96#define SZ16 sizeof(int16_t) 97#define SZ32 sizeof(int32_t) 98 99#define COMP_METHOD_SIGN '*' 100 101#define MAX_VFRAMES_CNT 256 102 103typedef struct vframe { 104 uint64_t method; 105 int32_t sender_decode_offset; 106 int32_t methodIdx; 107 int32_t bci; 108 int32_t line; 109} Vframe_t; 110 111typedef struct frame { 112 uintptr_t fp; 113 uintptr_t pc; 114 uintptr_t sp; 115 uintptr_t sender_sp; // The unextended sp of the caller 116} Frame_t; 117 118typedef struct Nmethod_t { 119 struct jvm_agent* J; 120 Jframe_t *jframe; 121 122 uint64_t nm; /* _nmethod */ 123 uint64_t pc; 124 uint64_t pc_desc; 125 126 int32_t orig_pc_offset; /* _orig_pc_offset */ 127 int32_t instrs_beg; /* _code_offset */ 128 int32_t instrs_end; 129 int32_t deopt_beg; /* _deoptimize_offset */ 130 int32_t scopes_data_beg; /* _scopes_data_offset */ 131 int32_t scopes_data_end; 132 int32_t metadata_beg; /* _metadata_offset */ 133 int32_t metadata_end; 134 int32_t scopes_pcs_beg; /* _scopes_pcs_offset */ 135 int32_t scopes_pcs_end; 136 137 int vf_cnt; 138 Vframe_t vframes[MAX_VFRAMES_CNT]; 139} Nmethod_t; 140 141struct jvm_agent { 142 struct ps_prochandle* P; 143 144 uint64_t nmethod_vtbl; 145 uint64_t CodeBlob_vtbl; 146 uint64_t BufferBlob_vtbl; 147 uint64_t RuntimeStub_vtbl; 148 uint64_t Method_vtbl; 149 150 uint64_t Use_Compressed_Oops_address; 151 uint64_t Universe_narrow_oop_base_address; 152 uint64_t Universe_narrow_oop_shift_address; 153 uint64_t CodeCache_heap_address; 154 155 /* Volatiles */ 156 uint8_t Use_Compressed_Oops; 157 uint64_t Universe_narrow_oop_base; 158 uint32_t Universe_narrow_oop_shift; 159 uint64_t CodeCache_low; 160 uint64_t CodeCache_high; 161 uint64_t CodeCache_segmap_low; 162 uint64_t CodeCache_segmap_high; 163 164 int32_t SIZE_CodeCache_log2_segment; 165 166 uint64_t methodPtr; 167 uint64_t bcp; 168 169 Nmethod_t *N; /*Inlined methods support */ 170 Frame_t prev_fr; 171 Frame_t curr_fr; 172}; 173 174static int 175read_string(struct ps_prochandle *P, 176 char *buf, /* caller's buffer */ 177 size_t size, /* upper limit on bytes to read */ 178 uintptr_t addr) /* address in process */ 179{ 180 int err = PS_OK; 181 while (size-- > 1 && err == PS_OK) { 182 err = ps_pread(P, addr, buf, 1); 183 if (*buf == '\0') { 184 return PS_OK; 185 } 186 addr += 1; 187 buf += 1; 188 } 189 return -1; 190} 191 192static int read_compressed_pointer(jvm_agent_t* J, uint64_t base, uint32_t *ptr) { 193 int err = -1; 194 uint32_t ptr32; 195 err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t)); 196 *ptr = ptr32; 197 return err; 198} 199 200static int read_pointer(jvm_agent_t* J, uint64_t base, uint64_t* ptr) { 201 int err = -1; 202 uint32_t ptr32; 203 204 switch (DATA_MODEL) { 205 case PR_MODEL_LP64: 206 err = ps_pread(J->P, base, ptr, sizeof(uint64_t)); 207 break; 208 case PR_MODEL_ILP32: 209 err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t)); 210 *ptr = ptr32; 211 break; 212 } 213 214 return err; 215} 216 217static int read_string_pointer(jvm_agent_t* J, uint64_t base, const char ** stringp) { 218 uint64_t ptr; 219 int err; 220 char buffer[1024]; 221 222 *stringp = NULL; 223 err = read_pointer(J, base, &ptr); 224 CHECK_FAIL(err); 225 if (ptr != 0) { 226 err = read_string(J->P, buffer, sizeof(buffer), ptr); 227 CHECK_FAIL(err); 228 *stringp = strdup(buffer); 229 } 230 return PS_OK; 231 232 fail: 233 return err; 234} 235 236static int parse_vmstruct_entry(jvm_agent_t* J, uint64_t base, VMStructEntry* vmp) { 237 uint64_t ptr; 238 int err; 239 240 err = read_string_pointer(J, base + OFFSET_VMStructEntrytypeName, &vmp->typeName); 241 CHECK_FAIL(err); 242 err = read_string_pointer(J, base + OFFSET_VMStructEntryfieldName, &vmp->fieldName); 243 CHECK_FAIL(err); 244 err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address); 245 CHECK_FAIL(err); 246 247 return PS_OK; 248 249 fail: 250 if (vmp->typeName != NULL) free((void*)vmp->typeName); 251 if (vmp->fieldName != NULL) free((void*)vmp->fieldName); 252 return err; 253} 254 255static int parse_vmstructs(jvm_agent_t* J) { 256 VMStructEntry vmVar; 257 VMStructEntry* vmp = &vmVar; 258 uint64_t gHotSpotVMStructs; 259 psaddr_t sym_addr; 260 uint64_t base; 261 int err; 262 263 err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr); 264 CHECK_FAIL(err); 265 err = read_pointer(J, sym_addr, &gHotSpotVMStructs); 266 CHECK_FAIL(err); 267 base = gHotSpotVMStructs; 268 269 err = PS_OK; 270 while (err == PS_OK) { 271 memset(vmp, 0, sizeof(VMStructEntry)); 272 err = parse_vmstruct_entry(J, base, vmp); 273 if (err != PS_OK || vmp->typeName == NULL) { 274 break; 275 } 276 277 if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) { 278 if (strcmp("_heap", vmp->fieldName) == 0) { 279 err = read_pointer(J, vmp->address, &J->CodeCache_heap_address); 280 } 281 } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) { 282 if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) { 283 J->Universe_narrow_oop_base_address = vmp->address; 284 } 285 if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) { 286 J->Universe_narrow_oop_shift_address = vmp->address; 287 } 288 } 289 CHECK_FAIL(err); 290 291 base += SIZE_VMStructEntry; 292 if (vmp->typeName != NULL) free((void*)vmp->typeName); 293 if (vmp->fieldName != NULL) free((void*)vmp->fieldName); 294 } 295 296 return PS_OK; 297 298 fail: 299 if (vmp->typeName != NULL) free((void*)vmp->typeName); 300 if (vmp->fieldName != NULL) free((void*)vmp->fieldName); 301 return -1; 302} 303 304static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) { 305 psaddr_t sym_addr; 306 int err; 307 308 err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); 309 if (err != PS_OK) goto fail; 310 *valuep = sym_addr; 311 return PS_OK; 312 313 fail: 314 return err; 315} 316 317static int read_volatiles(jvm_agent_t* J) { 318 uint64_t ptr; 319 int err; 320 321 err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address); 322 if (err == PS_OK) { 323 err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t)); 324 CHECK_FAIL(err); 325 } else { 326 J->Use_Compressed_Oops = 0; 327 } 328 329 err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base); 330 CHECK_FAIL(err); 331 err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t)); 332 CHECK_FAIL(err); 333 334 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + 335 OFFSET_VirtualSpace_low, &J->CodeCache_low); 336 CHECK_FAIL(err); 337 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + 338 OFFSET_VirtualSpace_high, &J->CodeCache_high); 339 CHECK_FAIL(err); 340 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap + 341 OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low); 342 CHECK_FAIL(err); 343 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap + 344 OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high); 345 CHECK_FAIL(err); 346 347 err = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size, 348 &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment)); 349 CHECK_FAIL(err); 350 351 return PS_OK; 352 353 fail: 354 return err; 355} 356 357 358static int codecache_contains(jvm_agent_t* J, uint64_t ptr) { 359 /* make sure the code cache is up to date */ 360 return (J->CodeCache_low <= ptr && ptr < J->CodeCache_high); 361} 362 363static uint64_t segment_for(jvm_agent_t* J, uint64_t p) { 364 return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment; 365} 366 367static uint64_t block_at(jvm_agent_t* J, int i) { 368 return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment); 369} 370 371static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) { 372 int err; 373 374 *startp = 0; 375 if (J->CodeCache_low <= ptr && ptr < J->CodeCache_high) { 376 int32_t used; 377 uint64_t segment = segment_for(J, ptr); 378 uint64_t block = J->CodeCache_segmap_low; 379 uint8_t tag; 380 err = ps_pread(J->P, block + segment, &tag, sizeof(tag)); 381 CHECK_FAIL(err); 382 if (tag == 0xff) 383 return PS_OK; 384 while (tag > 0) { 385 err = ps_pread(J->P, block + segment, &tag, sizeof(tag)); 386 CHECK_FAIL(err); 387 segment -= tag; 388 } 389 block = block_at(J, segment); 390 err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used)); 391 CHECK_FAIL(err); 392 if (used) { 393 *startp = block + SIZE_HeapBlockHeader; 394 } 395 } 396 return PS_OK; 397 398 fail: 399 return -1; 400} 401 402static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) { 403 psaddr_t sym_addr; 404 int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); 405 if (err == PS_OK) { 406 err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t)); 407 return err; 408 } 409 *valuep = -1; 410 return -1; 411} 412 413jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) { 414 jvm_agent_t* J; 415 int err; 416 417 if (vers != JVM_DB_VERSION) { 418 errno = ENOTSUP; 419 return NULL; 420 } 421 422 J = (jvm_agent_t*)calloc(sizeof(struct jvm_agent), 1); 423 424 debug = getenv("LIBJVMDB_DEBUG") != NULL; 425 if (debug) debug = 3; 426 427 if (debug) { 428 fprintf(stderr, "Jagent_create: debug=%d\n", debug); 429#ifdef X86_COMPILER2 430 fprintf(stderr, "Jagent_create: R_SP=%d, R_FP=%d, POINTER_SIZE=%d\n", R_SP, R_FP, POINTER_SIZE); 431#endif /* X86_COMPILER2 */ 432 } 433 434 J->P = P; 435 436 // Initialize the initial previous frame 437 438 J->prev_fr.fp = 0; 439 J->prev_fr.pc = 0; 440 J->prev_fr.sp = 0; 441 J->prev_fr.sender_sp = 0; 442 443 err = find_symbol(J, "__1cHnmethodG__vtbl_", &J->nmethod_vtbl); 444 CHECK_FAIL(err); 445 err = find_symbol(J, "__1cKBufferBlobG__vtbl_", &J->BufferBlob_vtbl); 446 if (err != PS_OK) J->BufferBlob_vtbl = 0; 447 err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl); 448 CHECK_FAIL(err); 449 err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl); 450 CHECK_FAIL(err); 451 err = find_symbol(J, "__1cGMethodG__vtbl_", &J->Method_vtbl); 452 CHECK_FAIL(err); 453 454 err = parse_vmstructs(J); 455 CHECK_FAIL(err); 456 err = read_volatiles(J); 457 CHECK_FAIL(err); 458 459 return J; 460 461 fail: 462 Jagent_destroy(J); 463 return NULL; 464} 465 466void Jagent_destroy(jvm_agent_t *J) { 467 if (J != NULL) { 468 free(J); 469 } 470} 471 472static int is_method(jvm_agent_t* J, uint64_t methodPtr) { 473 uint64_t klass; 474 int err = read_pointer(J, methodPtr, &klass); 475 if (err != PS_OK) goto fail; 476 return klass == J->Method_vtbl; 477 478 fail: 479 return 0; 480} 481 482static int 483name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t size) 484{ 485 short nameIndex; 486 short signatureIndex; 487 uint64_t constantPool; 488 uint64_t constMethod; 489 uint64_t nameSymbol; 490 uint64_t signatureSymbol; 491 uint64_t klassPtr; 492 uint64_t klassSymbol; 493 short klassSymbolLength; 494 short nameSymbolLength; 495 short signatureSymbolLength; 496 char * nameString = NULL; 497 char * klassString = NULL; 498 char * signatureString = NULL; 499 int err; 500 501 err = read_pointer(J, methodPtr + OFFSET_Method_constMethod, &constMethod); 502 CHECK_FAIL(err); 503 err = read_pointer(J, constMethod + OFFSET_ConstMethod_constants, &constantPool); 504 CHECK_FAIL(err); 505 506 /* To get name string */ 507 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_name_index, &nameIndex, 2); 508 CHECK_FAIL(err); 509 err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_ConstantPool, &nameSymbol); 510 CHECK_FAIL(err); 511 // The symbol is a CPSlot and has lower bit set to indicate metadata 512 nameSymbol &= (~1); // remove metadata lsb 513 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2); 514 CHECK_FAIL(err); 515 nameString = (char*)calloc(nameSymbolLength + 1, 1); 516 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength); 517 CHECK_FAIL(err); 518 519 /* To get signature string */ 520 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2); 521 CHECK_FAIL(err); 522 err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol); 523 CHECK_FAIL(err); 524 signatureSymbol &= (~1); // remove metadata lsb 525 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2); 526 CHECK_FAIL(err); 527 signatureString = (char*)calloc(signatureSymbolLength + 1, 1); 528 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength); 529 CHECK_FAIL(err); 530 531 /* To get klass string */ 532 err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr); 533 CHECK_FAIL(err); 534 err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol); 535 CHECK_FAIL(err); 536 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2); 537 CHECK_FAIL(err); 538 klassString = (char*)calloc(klassSymbolLength + 1, 1); 539 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength); 540 CHECK_FAIL(err); 541 542 result[0] = '\0'; 543 strncat(result, klassString, size); 544 size -= strlen(klassString); 545 strncat(result, ".", size); 546 size -= 1; 547 strncat(result, nameString, size); 548 size -= strlen(nameString); 549 strncat(result, signatureString, size); 550 551 if (nameString != NULL) free(nameString); 552 if (klassString != NULL) free(klassString); 553 if (signatureString != NULL) free(signatureString); 554 555 return PS_OK; 556 557 fail: 558 if (debug) { 559 fprintf(stderr, "name_for_methodPtr: FAIL \n\n"); 560 } 561 if (nameString != NULL) free(nameString); 562 if (klassString != NULL) free(klassString); 563 if (signatureString != NULL) free(signatureString); 564 return -1; 565} 566 567static int nmethod_info(Nmethod_t *N) 568{ 569 jvm_agent_t *J = N->J; 570 uint64_t nm = N->nm; 571 int32_t err; 572 573 if (debug > 2 ) 574 fprintf(stderr, "\t nmethod_info: BEGIN \n"); 575 576 /* Instructions */ 577 err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32); 578 CHECK_FAIL(err); 579 err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32); 580 CHECK_FAIL(err); 581 err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32); 582 CHECK_FAIL(err); 583 err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32); 584 CHECK_FAIL(err); 585 586 /* Metadata */ 587 err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32); 588 CHECK_FAIL(err); 589 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->metadata_end, SZ32); 590 CHECK_FAIL(err); 591 592 /* scopes_pcs */ 593 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32); 594 CHECK_FAIL(err); 595 err = ps_pread(J->P, nm + OFFSET_nmethod_handler_table_offset, &N->scopes_pcs_end, SZ32); 596 CHECK_FAIL(err); 597 598 /* scopes_data */ 599 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32); 600 CHECK_FAIL(err); 601 602 if (debug > 2 ) { 603 N->scopes_data_end = N->scopes_pcs_beg; 604 605 fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n", 606 N->instrs_beg, N->instrs_end); 607 608 fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n", 609 N->deopt_beg); 610 611 fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n", 612 N->orig_pc_offset); 613 614 fprintf(stderr, "\t nmethod_info: metadata_beg: %#x, metadata_end: %#x\n", 615 N->metadata_beg, N->metadata_end); 616 617 fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n", 618 N->scopes_data_beg, N->scopes_data_end); 619 620 fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n", 621 N->scopes_pcs_beg, N->scopes_pcs_end); 622 623 fprintf(stderr, "\t nmethod_info: END \n\n"); 624 } 625 return PS_OK; 626 627 fail: 628 return err; 629} 630 631static int 632raw_read_int(jvm_agent_t* J, uint64_t *buffer, int32_t *val) 633{ 634 int shift = 0; 635 int value = 0; 636 uint8_t ch = 0; 637 int32_t err; 638 int32_t sum; 639 // Constants for UNSIGNED5 coding of Pack200 640 // see compressedStream.hpp 641 enum { 642 lg_H = 6, 643 H = 1<<lg_H, 644 BitsPerByte = 8, 645 L = (1<<BitsPerByte)-H, 646 }; 647 int i; 648 649 err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t)); 650 CHECK_FAIL(err); 651 if (debug > 2) 652 fprintf(stderr, "\t\t\t raw_read_int: *buffer: %#llx, ch: %#x\n", *buffer, ch); 653 654 sum = ch; 655 if ( sum >= L ) { 656 int32_t lg_H_i = lg_H; 657 // Read maximum of 5 total bytes (we've already read 1). 658 // See CompressedReadStream::read_int_mb 659 for ( i = 0; i < 4; i++) { 660 err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t)); 661 CHECK_FAIL(err); 662 sum += ch << lg_H_i; 663 if (ch < L ) { 664 *val = sum; 665 return PS_OK; 666 } 667 lg_H_i += lg_H; 668 } 669 } 670 *val = sum; 671 return PS_OK; 672 673 fail: 674 return err; 675} 676 677static int 678read_pair(jvm_agent_t* J, uint64_t *buffer, int32_t *bci, int32_t *line) 679{ 680 uint8_t next = 0; 681 int32_t bci_delta; 682 int32_t line_delta; 683 int32_t err; 684 685 if (debug > 2) 686 fprintf(stderr, "\t\t read_pair: BEGIN\n"); 687 688 err = ps_pread(J->P, (*buffer)++, &next, sizeof(uint8_t)); 689 CHECK_FAIL(err); 690 691 if (next == 0) { 692 if (debug > 2) 693 fprintf(stderr, "\t\t read_pair: END: next == 0\n"); 694 return 1; /* stream terminated */ 695 } 696 if (next == 0xFF) { 697 if (debug > 2) 698 fprintf(stderr, "\t\t read_pair: END: next == 0xFF\n"); 699 700 /* Escape character, regular compression used */ 701 702 err = raw_read_int(J, buffer, &bci_delta); 703 CHECK_FAIL(err); 704 705 err = raw_read_int(J, buffer, &line_delta); 706 CHECK_FAIL(err); 707 708 *bci += bci_delta; 709 *line += line_delta; 710 711 if (debug > 2) { 712 fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n", 713 line_delta, bci_delta); 714 fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n", 715 *line, *bci); 716 } 717 } else { 718 /* Single byte compression used */ 719 *bci += next >> 3; 720 *line += next & 0x7; 721 if (debug > 2) { 722 fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n", 723 next & 0x7, next >> 3); 724 fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n", 725 *line, *bci); 726 } 727 } 728 if (debug > 2) 729 fprintf(stderr, "\t\t read_pair: END\n"); 730 return PS_OK; 731 732 fail: 733 if (debug) 734 fprintf(stderr, "\t\t read_pair: FAIL\n"); 735 return err; 736} 737 738static int 739line_number_from_bci(jvm_agent_t* J, Vframe_t *vf) 740{ 741 uint64_t buffer; 742 uint16_t code_size; 743 uint64_t code_end_delta; 744 uint64_t constMethod; 745 int8_t access_flags; 746 int32_t best_bci = 0; 747 int32_t stream_bci = 0; 748 int32_t stream_line = 0; 749 int32_t err; 750 751 if (debug > 2) { 752 char name[256]; 753 err = name_for_methodPtr(J, vf->method, name, 256); 754 CHECK_FAIL(err); 755 fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n", 756 name, vf->bci); 757 } 758 759 err = read_pointer(J, vf->method + OFFSET_Method_constMethod, &constMethod); 760 CHECK_FAIL(err); 761 762 vf->line = 0; 763 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_flags, &access_flags, sizeof(int8_t)); 764 CHECK_FAIL(err); 765 766 if (!(access_flags & ConstMethod_has_linenumber_table)) { 767 if (debug > 2) 768 fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n"); 769 return PS_OK; 770 } 771 772 /* The line numbers are a short array of 2-tuples [start_pc, line_number]. 773 * Not necessarily sorted and not necessarily one-to-one. 774 */ 775 776 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_code_size, &code_size, SZ16); 777 CHECK_FAIL(err); 778 779 /* inlined_table_start() */ 780 code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0; 781 buffer = constMethod + (uint64_t) SIZE_ConstMethod + (uint64_t) code_size + code_end_delta; 782 783 if (debug > 2) { 784 fprintf(stderr, "\t\t line_number_from_bci: method: %#llx, native: %d\n", 785 vf->method, (access_flags & AccessFlags_NATIVE)); 786 fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n", 787 buffer, (int) code_size); 788 } 789 790 while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) { 791 if (stream_bci == vf->bci) { 792 /* perfect match */ 793 if (debug > 2) 794 fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line); 795 vf->line = stream_line; 796 return PS_OK; 797 } else { 798 /* update best_bci/line */ 799 if (stream_bci < vf->bci && stream_bci >= best_bci) { 800 best_bci = stream_bci; 801 vf->line = stream_line; 802 if (debug > 2) { 803 fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n", 804 best_bci, vf->line); 805 } 806 } 807 } 808 } 809 if (debug > 2) 810 fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line); 811 return PS_OK; 812 813 fail: 814 if (debug) 815 fprintf(stderr, "\t line_number_from_bci: FAIL\n"); 816 return err; 817} 818 819static int 820get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc) 821{ 822 int32_t pc_offset; 823 int32_t err; 824 825 err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32); 826 CHECK_FAIL(err); 827 828 *real_pc = N->nm + N->instrs_beg + pc_offset; 829 if (debug > 2) { 830 fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n", 831 pc_offset, *real_pc); 832 } 833 return PS_OK; 834 835 fail: 836 return err; 837} 838 839/* Finds a PcDesc with real-pc equal to N->pc */ 840static int pc_desc_at(Nmethod_t *N) 841{ 842 uint64_t pc_diff; 843 int32_t offs; 844 int32_t err; 845 846 if (debug > 2) 847 fprintf(stderr, "\t pc_desc_at: BEGIN\n"); 848 849 N->vf_cnt = 0; 850 N->pc_desc = 0; 851 852 for (offs = N->scopes_pcs_beg; offs < N->scopes_pcs_end; offs += SIZE_PcDesc) { 853 uint64_t pd; 854 uint64_t best_pc_diff = 16; /* some approximation */ 855 uint64_t real_pc = 0; 856 857 pd = N->nm + offs; 858 err = get_real_pc(N, pd, &real_pc); 859 CHECK_FAIL(err); 860 861 pc_diff = real_pc - N->pc; 862 863 /* In general, this fragment should work */ 864 if (pc_diff == 0) { 865 N->pc_desc = pd; 866 if (debug) { 867 fprintf(stderr, "\t pc_desc_at: END: pc_desc: FOUND: %#lx \n\n", pd); 868 } 869 return PS_OK; 870 } 871 /* This fragment is to be able to find out an appropriate 872 * pc_desc entry even if pc_desc info is inaccurate. 873 */ 874 if (best_pc_diff > pc_diff && pc_diff > 0) { 875 best_pc_diff = pc_diff; 876 N->pc_desc = pd; 877 } 878 } 879 if (debug) { 880 fprintf(stderr, "\t pc_desc_at: END: pc_desc NOT FOUND"); 881 if (pc_diff < 20) 882 fprintf(stderr, ", best pc_diff: %d\n\n", pc_diff); 883 else 884 fprintf(stderr, "\n\n"); 885 } 886 return PS_OK; 887 888 fail: 889 return err; 890} 891 892static int 893scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf) 894{ 895 uint64_t buffer; 896 int32_t err; 897 898 if (debug > 2) { 899 fprintf(stderr, "\t\t scope_desc_at: BEGIN \n"); 900 } 901 902 buffer = N->nm + N->scopes_data_beg + decode_offset; 903 904 err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset); 905 CHECK_FAIL(err); 906 907 err = raw_read_int(N->J, &buffer, &vf->methodIdx); 908 CHECK_FAIL(err); 909 910 err = raw_read_int(N->J, &buffer, &vf->bci); 911 CHECK_FAIL(err); 912 913 if (debug > 2) { 914 fprintf(stderr, "\t\t scope_desc_at: sender_decode_offset: %#x\n", 915 vf->sender_decode_offset); 916 fprintf(stderr, "\t\t scope_desc_at: methodIdx: %d\n", vf->methodIdx); 917 fprintf(stderr, "\t\t scope_desc_at: bci: %d\n", vf->bci); 918 919 fprintf(stderr, "\t\t scope_desc_at: END \n\n"); 920 } 921 return PS_OK; 922 923 fail: 924 return err; 925} 926 927static int scopeDesc_chain(Nmethod_t *N) { 928 int32_t decode_offset = 0; 929 int32_t err; 930 931 if (debug > 2) { 932 fprintf(stderr, "\t scopeDesc_chain: BEGIN\n"); 933 } 934 935 err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset, 936 &decode_offset, SZ32); 937 CHECK_FAIL(err); 938 939 while (decode_offset > 0) { 940 Vframe_t *vf = &N->vframes[N->vf_cnt]; 941 942 if (debug > 2) { 943 fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset); 944 } 945 946 err = scope_desc_at(N, decode_offset, vf); 947 CHECK_FAIL(err); 948 949 if (vf->methodIdx > ((N->metadata_end - N->metadata_beg) / POINTER_SIZE)) { 950 fprintf(stderr, "\t scopeDesc_chain: (methodIdx > metadata length) !\n"); 951 return -1; 952 } 953 err = read_pointer(N->J, N->nm + N->metadata_beg + (vf->methodIdx-1)*POINTER_SIZE, 954 &vf->method); 955 CHECK_FAIL(err); 956 957 if (vf->method) { 958 N->vf_cnt++; 959 err = line_number_from_bci(N->J, vf); 960 CHECK_FAIL(err); 961 if (debug > 2) { 962 fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %ld\n", 963 vf->method, vf->line); 964 } 965 } 966 decode_offset = vf->sender_decode_offset; 967 } 968 if (debug > 2) { 969 fprintf(stderr, "\t scopeDesc_chain: END \n\n"); 970 } 971 return PS_OK; 972 973 fail: 974 if (debug) { 975 fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n"); 976 } 977 return err; 978} 979 980 981static int 982name_for_nmethod(jvm_agent_t* J, 983 uint64_t nm, 984 uint64_t pc, 985 uint64_t method, 986 char *result, 987 size_t size, 988 Jframe_t *jframe 989) { 990 Nmethod_t *N; 991 Vframe_t *vf; 992 int32_t err; 993 int deoptimized = 0; 994 995 if (debug) { 996 fprintf(stderr, "name_for_nmethod: BEGIN: nmethod: %#llx, pc: %#llx\n", nm, pc); 997 } 998 if (J->N == NULL) { 999 J->N = (Nmethod_t *) malloc(sizeof(Nmethod_t)); 1000 } 1001 memset(J->N, 0, sizeof(Nmethod_t)); /* Initial stat: all values are zeros */ 1002 N = J->N; 1003 N->J = J; 1004 N->nm = nm; 1005 N->pc = pc; 1006 N->jframe = jframe; 1007 1008 err = nmethod_info(N); 1009 CHECK_FAIL(err); 1010 if (debug) { 1011 fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc: %#llx\n", 1012 pc, N->nm + N->deopt_beg); 1013 } 1014 1015 /* check for a deoptimized frame */ 1016 if ( pc == N->nm + N->deopt_beg) { 1017 uint64_t base; 1018 if (debug) { 1019 fprintf(stderr, "name_for_nmethod: found deoptimized frame\n"); 1020 } 1021 if (J->prev_fr.sender_sp != 0) { 1022 base = J->prev_fr.sender_sp + N->orig_pc_offset; 1023 } else { 1024 base = J->curr_fr.sp + N->orig_pc_offset; 1025 } 1026 err = read_pointer(J, base, &N->pc); 1027 CHECK_FAIL(err); 1028 if (debug) { 1029 fprintf(stderr, "name_for_nmethod: found deoptimized frame converting pc from %#8llx to %#8llx\n", 1030 pc, N->pc); 1031 } 1032 deoptimized = 1; 1033 } 1034 1035 err = pc_desc_at(N); 1036 CHECK_FAIL(err); 1037 1038 if (N->pc_desc > 0) { 1039 jframe->locinf = 1; 1040 err = scopeDesc_chain(N); 1041 CHECK_FAIL(err); 1042 } 1043 result[0] = COMP_METHOD_SIGN; 1044 vf = &N->vframes[0]; 1045 if (N->vf_cnt > 0) { 1046 jframe->vf_cnt = N->vf_cnt; 1047 jframe->bci = vf->bci; 1048 jframe->line = vf->line; 1049 err = name_for_methodPtr(J, N->vframes[0].method, result+1, size-1); 1050 CHECK_FAIL(err); 1051 } else { 1052 err = name_for_methodPtr(J, method, result+1, size-1); 1053 CHECK_FAIL(err); 1054 } 1055 if (deoptimized) { 1056 strncat(result + 1, " [deoptimized frame]; ", size-1); 1057 } else { 1058 strncat(result + 1, " [compiled] ", size-1); 1059 } 1060 if (debug) 1061 fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n", 1062 result, N->vf_cnt); 1063 return PS_OK; 1064 1065 fail: 1066 if (debug) 1067 fprintf(stderr, "name_for_nmethod: FAIL \n\n"); 1068 return err; 1069} 1070 1071static int 1072name_for_imethod(jvm_agent_t* J, 1073 uint64_t bcp, 1074 uint64_t method, 1075 char *result, 1076 size_t size, 1077 Jframe_t *jframe 1078) { 1079 uint64_t bci; 1080 uint64_t constMethod; 1081 Vframe_t vframe = {0}; 1082 Vframe_t *vf = &vframe; 1083 int32_t err; 1084 1085 err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod); 1086 CHECK_FAIL(err); 1087 1088 bci = bcp - (constMethod + (uint64_t) SIZE_ConstMethod); 1089 1090 if (debug) 1091 fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method); 1092 1093 err = name_for_methodPtr(J, method, result, size); 1094 CHECK_FAIL(err); 1095 if (debug) 1096 fprintf(stderr, "\t name_for_imethod: method name: %s\n", result); 1097 1098 if (bci > 0) { 1099 vf->method = method; 1100 vf->bci = bci; 1101 err = line_number_from_bci(J, vf); 1102 CHECK_FAIL(err); 1103 } 1104 jframe->bci = vf->bci; 1105 jframe->line = vf->line; 1106 jframe->locinf = 1; 1107 1108 if (debug) { 1109 fprintf(stderr, "\t name_for_imethod: END: bci: %d, line: %d\n\n", 1110 vf->bci, vf->line); 1111 } 1112 return PS_OK; 1113 1114 fail: 1115 if (debug) 1116 fprintf(stderr, "\t name_for_imethod: FAIL\n"); 1117 return err; 1118} 1119 1120static int 1121name_for_codecache(jvm_agent_t* J, uint64_t fp, uint64_t pc, char * result, 1122 size_t size, Jframe_t *jframe, int* is_interpreted) 1123{ 1124 uint64_t start; 1125 uint64_t vtbl; 1126 int32_t err; 1127 *is_interpreted = 0; 1128 1129 result[0] = '\0'; 1130 1131 err = find_start(J, pc, &start); 1132 CHECK_FAIL(err); 1133 1134 err = read_pointer(J, start, &vtbl); 1135 CHECK_FAIL(err); 1136 1137 if (vtbl == J->nmethod_vtbl) { 1138 uint64_t method; 1139 1140 err = read_pointer(J, start + OFFSET_nmethod_method, &method); 1141 CHECK_FAIL(err); 1142 1143 if (debug) { 1144 fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n", 1145 start, pc, method); 1146 } 1147 err = name_for_nmethod(J, start, pc, method, result, size, jframe); 1148 CHECK_FAIL(err); 1149 } else if (vtbl == J->BufferBlob_vtbl) { 1150 const char * name; 1151 1152 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name); 1153 1154 /* 1155 * Temporary usage of string "Interpreter". 1156 * We need some other way to distinguish "StubRoutines" 1157 * and regular interpreted frames. 1158 */ 1159 if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) { 1160 *is_interpreted = 1; 1161 if (is_method(J, J->methodPtr)) { 1162 return name_for_imethod(J, J->bcp, J->methodPtr, result, size, jframe); 1163 } 1164 } 1165 1166 if (err == PS_OK) { 1167 strncpy(result, name, size); 1168 free((void*)name); 1169 } else { 1170 strncpy(result, "<unknown BufferBlob>", size); 1171 } 1172 /* return PS_OK; */ 1173 } else { 1174 const char * name; 1175 1176 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name); 1177 if (err == PS_OK) { 1178 strncpy(result, name, size); 1179 free((void*)name); 1180 } else { 1181 strncpy(result, "<unknown CodeBlob>", size); 1182 WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl); 1183 } 1184 } 1185 result[size-1] = '\0'; 1186 1187#ifdef X86_COMPILER2 1188 if (vtbl != J->RuntimeStub_vtbl) { 1189 uint64_t trial_pc; 1190 int frame_size; 1191 err = ps_pread(J->P, start + OFFSET_CodeBlob_frame_size, 1192 &frame_size, SZ32); 1193 CHECK_FAIL(err); 1194 1195 // frame_size is in words, we want bytes. 1196 frame_size *= POINTER_SIZE; /* word => byte conversion */ 1197 1198 /* 1199 Because c2 doesn't use FP as a framepointer the value of sp/fp we receive 1200 in the initial entry to a set of stack frames containing server frames 1201 will pretty much be nonsense. We can detect that nonsense by looking to 1202 see if the PC we received is correct if we look at the expected storage 1203 location in relation to the FP (ie. POINTER_SIZE(FP) ) 1204 */ 1205 1206 err = read_pointer(J, fp + POINTER_SIZE , &trial_pc); 1207 if ( (err != PS_OK || trial_pc != pc) && frame_size > 0 ) { 1208 // Either we couldn't even read at the "fp" or the pc didn't match 1209 // both are sure clues that the fp is bogus. We no search the stack 1210 // for a reasonable number of words trying to find the bogus fp 1211 // and the current pc in adjacent words. The we will be able to 1212 // deduce an approximation of the frame pointer and actually get 1213 // the correct stack pointer. Which we can then unwind for the 1214 // next frame. 1215 int i; 1216 uint64_t check; 1217 uint64_t base = J->curr_fr.sp; 1218 uint64_t prev_fp = 0; 1219 for ( i = 0; i < frame_size * 5 ; i++, base += POINTER_SIZE ) { 1220 err = read_pointer(J, base , &check); 1221 CHECK_FAIL(err); 1222 if (check == fp) { 1223 base += POINTER_SIZE; 1224 err = read_pointer(J, base , &check); 1225 CHECK_FAIL(err); 1226 if (check == pc) { 1227 if (debug) { 1228 fprintf(stderr, "name_for_codecache: found matching fp/pc combo at 0x%llx\n", base - POINTER_SIZE); 1229 } 1230 prev_fp = base - 2 * POINTER_SIZE; 1231 break; 1232 } 1233 } 1234 } 1235 if ( prev_fp != 0 ) { 1236 // real_sp is the sp we should have received for this frame 1237 uint64_t real_sp = prev_fp + 2 * POINTER_SIZE; 1238 // +POINTER_SIZE because callee owns the return address so caller's sp is +1 word 1239 jframe->new_sp = real_sp + frame_size + POINTER_SIZE; 1240 err = read_pointer(J, jframe->new_sp - POINTER_SIZE , &jframe->new_pc); 1241 CHECK_FAIL(err); 1242 err = read_pointer(J, jframe->new_sp - 2*POINTER_SIZE, &jframe->new_fp); 1243 CHECK_FAIL(err); 1244 return PS_OK; 1245 } 1246 } 1247 1248 /* A prototype to workaround FP absence */ 1249 /* 1250 * frame_size can be 0 for StubRoutines (1) frame. 1251 * In this case it should work with fp as usual. 1252 */ 1253 if (frame_size > 0) { 1254 jframe->new_fp = J->prev_fr.fp + frame_size; 1255 jframe->new_sp = jframe->new_fp + 2 * POINTER_SIZE; 1256 } else { 1257 memset(&J->curr_fr, 0, sizeof(Frame_t)); 1258 err = read_pointer(J, fp, &jframe->new_fp); 1259 CHECK_FAIL(err); 1260 1261 err = read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc); 1262 CHECK_FAIL(err); 1263 } 1264 if (debug) { 1265 fprintf(stderr, "name_for_codecache: %s, frame_size=%#lx\n", 1266 result, frame_size); 1267 fprintf(stderr, "name_for_codecache: prev_fr.fp=%#lx, fp=%#lx\n", 1268 J->prev_fr.fp, jframe->new_fp); 1269 } 1270 } 1271#endif /* X86_COMPILER2 */ 1272 1273 return PS_OK; 1274 1275 fail: 1276 return err; 1277} 1278 1279int Jget_vframe(jvm_agent_t* J, int vframe_no, 1280 char *name, size_t size, Jframe_t *jframe) 1281{ 1282 Nmethod_t *N = J->N; 1283 Vframe_t *vf; 1284 int32_t err; 1285 1286 if (vframe_no >= N->vf_cnt) { 1287 (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no); 1288 return -1; 1289 } 1290 vf = N->vframes + vframe_no; 1291 name[0] = COMP_METHOD_SIGN; 1292 err = name_for_methodPtr(J, vf->method, name + 1, size); 1293 CHECK_FAIL(err); 1294 1295 jframe->bci = vf->bci; 1296 jframe->line = vf->line; 1297 if (debug) { 1298 fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n", 1299 name, vf->line); 1300 } 1301 return PS_OK; 1302 1303 fail: 1304 if (debug) { 1305 fprintf(stderr, "\t Jget_vframe: FAIL\n"); 1306 } 1307 return err; 1308} 1309 1310#define MAX_SYM_SIZE 256 1311 1312int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name, 1313 size_t size, Jframe_t *jframe) { 1314 uintptr_t fp; 1315 uintptr_t pc; 1316 /* arguments given to read_pointer need to be worst case sized */ 1317 uint64_t methodPtr = 0; 1318 uint64_t sender_sp; 1319 uint64_t bcp = 0; 1320 int is_interpreted = 0; 1321 int result = PS_OK; 1322 int err = PS_OK; 1323 1324 if (J == NULL) { 1325 return -1; 1326 } 1327 1328 jframe->vf_cnt = 1; 1329 jframe->new_fp = 0; 1330 jframe->new_pc = 0; 1331 jframe->line = 0; 1332 jframe->bci = 0; 1333 jframe->locinf = 0; 1334 1335 read_volatiles(J); 1336 pc = (uintptr_t) regs[R_PC]; 1337 J->curr_fr.pc = pc; 1338 J->curr_fr.fp = regs[R_FP]; 1339 J->curr_fr.sp = regs[R_SP]; 1340 1341 if (debug) 1342 fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc); 1343 1344#if defined(sparc) || defined(__sparc) 1345 /* The following workaround is for SPARC. CALL instruction occupates 8 bytes. 1346 * In the pcDesc structure return pc offset is recorded for CALL instructions. 1347 * regs[R_PC] contains a CALL instruction pc offset. 1348 */ 1349 pc += 8; 1350 bcp = (uintptr_t) regs[R_L1]; 1351 methodPtr = (uintptr_t) regs[R_L2]; 1352 sender_sp = regs[R_I5]; 1353 if (debug > 2) { 1354 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n", 1355 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]); 1356 } 1357#elif defined(i386) || defined(__i386) || defined(__amd64) 1358 1359 fp = (uintptr_t) regs[R_FP]; 1360 if (J->prev_fr.fp == 0) { 1361#ifdef X86_COMPILER2 1362 /* A workaround for top java frames */ 1363 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE); 1364#else 1365 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE); 1366#endif /* COMPILER2 */ 1367 } 1368 if (debug > 2) { 1369 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp); 1370 } 1371 1372 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) { 1373 methodPtr = 0; 1374 } 1375 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) { 1376 sender_sp = 0; 1377 } 1378 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcp_offset, &bcp) != PS_OK) { 1379 bcp = 0; 1380 } 1381#endif /* i386 */ 1382 1383 J->methodPtr = methodPtr; 1384 J->bcp = bcp; 1385 1386 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP] 1387 * For example: JVM_SuspendThread frame poins to the top interpreted frame. 1388 * If we call is_method(J, methodPtr) before codecache_contains(J, pc) 1389 * then we go over and omit both: nmethod and I2CAdapter frames. 1390 * Note, that regs[R_PC] is always correct if frame defined correctly. 1391 * So it is better to call codecache_contains(J, pc) from the beginning. 1392 */ 1393#ifndef X86_COMPILER2 1394 if (is_method(J, J->methodPtr)) { 1395 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); 1396 /* If the methodPtr is a method then this is highly likely to be 1397 an interpreter frame */ 1398 if (result >= 0) { 1399 is_interpreted = 1; 1400 } 1401 } else 1402#endif /* ! X86_COMPILER2 */ 1403 1404 if (codecache_contains(J, pc)) { 1405 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted); 1406 } 1407#ifdef X86_COMPILER2 1408 else if (is_method(J, J->methodPtr)) { 1409 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); 1410 /* If the methodPtr is a method then this is highly likely to be 1411 an interpreter frame */ 1412 if (result >= 0) { 1413 is_interpreted = 1; 1414 } 1415 } 1416#endif /* X86_COMPILER2 */ 1417 else { 1418 if (debug) { 1419 fprintf(stderr, "Jlookup_by_regs: END with -1\n\n"); 1420 } 1421 result = -1; 1422 } 1423 if (!is_interpreted) { 1424 sender_sp = 0; 1425 } 1426 J->curr_fr.sender_sp = sender_sp; 1427 1428#ifdef X86_COMPILER2 1429 if (!J->curr_fr.fp) { 1430 J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP]; 1431 } 1432 if (!jframe->new_pc && jframe->new_fp) { 1433 // This seems dubious 1434 read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc); 1435 CHECK_FAIL(err); 1436 if (debug > 2) { 1437 printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n", 1438 jframe->new_fp, jframe->new_pc); 1439 } 1440 } 1441 1442#endif /* X86_COMPILER2 */ 1443 J->prev_fr = J->curr_fr; 1444 1445 if (debug) 1446 fprintf(stderr, "Jlookup_by_regs: END\n\n"); 1447 1448 return result; 1449 1450 fail: 1451 return err; 1452} 1453 1454void update_gregs(prgregset_t gregs, Jframe_t jframe) { 1455#ifdef X86_COMPILER2 1456 if (debug > 0) { 1457 fprintf(stderr, "update_gregs: before update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); 1458 } 1459 /* 1460 * A workaround for java C2 frames with unconventional FP. 1461 * may have to modify regset with new values for FP/PC/SP when needed. 1462 */ 1463 if (jframe.new_sp) { 1464 *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp; 1465 } else { 1466 // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE; 1467 } 1468 1469 if (jframe.new_fp) { 1470 *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp; 1471 } 1472 if (jframe.new_pc) { 1473 *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc; 1474 } 1475 if (debug > 0) { 1476 fprintf(stderr, "update_gregs: after update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); 1477 } 1478#endif /* X86_COMPILER2 */ 1479} 1480 1481/* 1482 * Iterates over java frames at current location given by 'gregs'. 1483 * 1484 * Returns -1 if no java frames are present or if an error is encountered. 1485 * Returns the result of calling 'func' if the return value is non-zero. 1486 * Returns 0 otherwise. 1487 */ 1488int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) { 1489 char buf[MAX_SYM_SIZE + 1]; 1490 Jframe_t jframe; 1491 int i = 0, res; 1492#ifdef X86_COMPILER2 1493 if (debug > 0) { 1494 fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); 1495 } 1496#endif /* X86_COMPILER2 */ 1497 1498 memset(&jframe, 0, sizeof(Jframe_t)); 1499 memset(buf, 0, sizeof(buf)); 1500 res = Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe); 1501 if (res != PS_OK) 1502 return (-1); 1503 1504 1505 res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, 1506 jframe.line, NULL); 1507 if (res != 0) { 1508 update_gregs(gregs, jframe); 1509 return (res); 1510 } 1511 for (i = 1; i < jframe.vf_cnt; i++) { 1512 Jget_vframe(J, i, buf, sizeof(buf), &jframe); 1513 res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, 1514 jframe.line, NULL); 1515 if (res != 0) { 1516 update_gregs(gregs, jframe); 1517 return (res); 1518 } 1519 } 1520 update_gregs(gregs, jframe); 1521 return (0); 1522} 1523