372 };
373
374
375 inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
376 if (_sender_decode_offset == DebugInformationRecorder::serialized_null) {
377 return false;
378 }
379 fill_from_compiled_frame(_sender_decode_offset);
380 return true;
381 }
382
383
384 inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
385 _mode = compiled_mode;
386
387 // Range check to detect ridiculous offsets.
388 if (decode_offset == DebugInformationRecorder::serialized_null ||
389 decode_offset < 0 ||
390 decode_offset >= nm()->scopes_data_size()) {
391 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
392 // If we attempt to read nmethod::scopes_data at serialized_null (== 0),
393 // or if we read some at other crazy offset,
394 // we will decode garbage and make wild references into the heap,
395 // leading to crashes in product mode.
396 // (This isn't airtight, of course, since there are internal
397 // offsets which are also crazy.)
398 #ifdef ASSERT
399 if (WizardMode) {
400 tty->print_cr("Error in fill_from_frame: pc_desc for "
401 INTPTR_FORMAT " not found or invalid at %d",
402 p2i(_frame.pc()), decode_offset);
403 nm()->print();
404 nm()->method()->print_codes();
405 nm()->print_code();
406 nm()->print_pcs();
407 }
408 #endif
409 // Provide a cheap fallback in product mode. (See comment above.)
410 found_bad_method_frame();
411 fill_from_compiled_native_frame();
412 return;
413 }
414
415 // Decode first part of scopeDesc
416 DebugInfoReadStream buffer(nm(), decode_offset);
417 _sender_decode_offset = buffer.read_int();
497 fill_from_compiled_frame(decode_offset);
498 }
499 return true;
500 }
501
502 // End of stack?
503 if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
504 _mode = at_end_mode;
505 return true;
506 }
507
508 return false;
509 }
510
511
512 inline void vframeStreamCommon::fill_from_interpreter_frame() {
513 Method* method = _frame.interpreter_frame_method();
514 intptr_t bcx = _frame.interpreter_frame_bcx();
515 int bci = method->validate_bci_from_bcx(bcx);
516 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
517 if (bci < 0) {
518 found_bad_method_frame();
519 bci = 0; // pretend it's on the point of entering
520 }
521 _mode = interpreted_mode;
522 _method = method;
523 _bci = bci;
524 }
525
526 #endif // SHARE_VM_RUNTIME_VFRAME_HPP
|
372 };
373
374
375 inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
376 if (_sender_decode_offset == DebugInformationRecorder::serialized_null) {
377 return false;
378 }
379 fill_from_compiled_frame(_sender_decode_offset);
380 return true;
381 }
382
383
384 inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
385 _mode = compiled_mode;
386
387 // Range check to detect ridiculous offsets.
388 if (decode_offset == DebugInformationRecorder::serialized_null ||
389 decode_offset < 0 ||
390 decode_offset >= nm()->scopes_data_size()) {
391 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
392 // If we read nmethod::scopes_data at serialized_null (== 0)
393 // or if read some at other invalid offset, invalid values will be decoded.
394 // Based on these values, invalid heap locations could be referenced
395 // that could lead to crashes in product mode.
396 // Therefore, do not use the decode offset if invalid, but fill the frame
397 // as it were a native compiled frame (no Java-level assumptions).
398 #ifdef ASSERT
399 if (WizardMode) {
400 tty->print_cr("Error in fill_from_frame: pc_desc for "
401 INTPTR_FORMAT " not found or invalid at %d",
402 p2i(_frame.pc()), decode_offset);
403 nm()->print();
404 nm()->method()->print_codes();
405 nm()->print_code();
406 nm()->print_pcs();
407 }
408 #endif
409 // Provide a cheap fallback in product mode. (See comment above.)
410 found_bad_method_frame();
411 fill_from_compiled_native_frame();
412 return;
413 }
414
415 // Decode first part of scopeDesc
416 DebugInfoReadStream buffer(nm(), decode_offset);
417 _sender_decode_offset = buffer.read_int();
497 fill_from_compiled_frame(decode_offset);
498 }
499 return true;
500 }
501
502 // End of stack?
503 if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
504 _mode = at_end_mode;
505 return true;
506 }
507
508 return false;
509 }
510
511
512 inline void vframeStreamCommon::fill_from_interpreter_frame() {
513 Method* method = _frame.interpreter_frame_method();
514 intptr_t bcx = _frame.interpreter_frame_bcx();
515 int bci = method->validate_bci_from_bcx(bcx);
516 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
517 // AsyncGetCallTrace interrupts the VM asynchronously. As a result
518 // it is possible to access an interpreter frame for which
519 // no Java-level information is yet available (e.g., becasue
520 // the frame was being created when the VM interrupted it).
521 // In this scenario, pretend that the interpreter is at the point
522 // of entering the method.
523 if (bci < 0) {
524 found_bad_method_frame();
525 bci = 0;
526 }
527 _mode = interpreted_mode;
528 _method = method;
529 _bci = bci;
530 }
531
532 #endif // SHARE_VM_RUNTIME_VFRAME_HPP
|