ReturnOop VMEventModifier::new_modifier(PacketInputStream *in, PacketOutputStream *out, bool& error) { UsingFastOops fast_oops; jbyte mod_kind = in->read_byte(); VMEventModifier::Fast newMod; Thread::Fast thread; newMod = allocate_modifier(); if (newMod.is_null()) { error = true; out->set_error(JDWP_Error_OUT_OF_MEMORY); return NULL; } newMod().set_mod_kind(mod_kind); #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Modifier: modkind = %d", mod_kind); } #endif switch(mod_kind) { case JDWP_EventRequest_Set_Out_modifiers_Modifier_FieldOnly: // unsupported in->read_class_id(); in->read_class_id(); in->read_int(); return NULL; case JDWP_EventRequest_Set_Out_modifiers_Modifier_Conditional: // unsupported in->read_int(); return NULL; case JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassExclude: // unsupported in->read_string(); return NULL; case JDWP_EventRequest_Set_Out_modifiers_Modifier_ThreadOnly: newMod().set_thread_id(in->read_thread_id()); return newMod; case JDWP_EventRequest_Set_Out_modifiers_Modifier_Count: newMod().set_count(in->read_int()); return newMod; case JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassOnly: { newMod().set_clazz_id(in->read_class_id()); #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Modifier: class_id = %d", newMod().clazz_id()); } #endif return newMod; } case JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassMatch: { UsingFastOops fast_oops_2; int length; SETUP_ERROR_CHECKER_ARG; TypeArray::Fast ta = in->read_raw_string(length JVM_NO_CHECK); if (ta.is_null()) { // Out of memory?? Things will fall apart soon enough, // We just punt on this modifier return newMod; } for (int i = length - 1; i >= 0; i--) { if (ta().byte_at(i) == '.') { ta().byte_at_put(i, '/'); } } Symbol::Fast tmpName = Universe::new_symbol(&ta, (utf8)(ta().base_address()), length JVM_NO_CHECK); if (tmpName.is_null()) { error = true; out->set_error(JDWP_Error_OUT_OF_MEMORY); return NULL; } #ifdef AZZERT if (TraceDebugger) { tty->print("Modifier: class match = "); tmpName().print_symbol_on(tty); tty->cr(); } #endif ClassMatchModifier::Fast class_match_modifier = newMod().obj(); class_match_modifier().set_class_match_name(&tmpName); return newMod; } case JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly: { UsingFastOops fast_oops_3; jbyte tag = in->read_byte(); (void)tag; LocationModifier::Fast lmod = newMod.obj(); lmod().set_clazz_id(in->read_class_id()); if (lmod().clazz_id() == 0) { return NULL; /* Class ID == 0 is invalid */ } lmod().set_method_id(in->read_method_id()); lmod().set_offset(in->read_long()); #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Loc: class: 0x%x, method: 0x%x, off: 0x%x", lmod().clazz_id(), (int)(lmod().method_id() & 0xFFFFFFFF), lmod().offset()); } #endif return lmod; } case JDWP_EventRequest_Set_Out_modifiers_Modifier_ExceptionOnly: { UsingFastOops fast_oops_4; ExceptionModifier::Fast emod = newMod.obj(); emod().set_clazz_id(in->read_class_id()); emod().set_sig_caught(in->read_boolean()); emod().set_sig_uncaught(in->read_boolean()); return emod; } case JDWP_EventRequest_Set_Out_modifiers_Modifier_Step: { UsingFastOops fast_oops_5; int thread_id = in->read_thread_id(); thread = JavaDebugger::get_thread_by_id(thread_id); if (!JavaDebugger::is_valid_thread(&thread) || !thread().last_java_frame_exists()) { error = true; out->set_error(JDWP_Error_INVALID_THREAD); return NULL; } Frame fr(&thread); GUARANTEE(fr.is_java_frame(), "Single step must start at JavaFrame"); JavaFrame jf = fr.as_JavaFrame(); LocationModifier::Fast loc = LocationModifier::new_location(&jf); if (loc.is_null()) { error = true; out->set_error(JDWP_Error_OUT_OF_MEMORY); return NULL; } #ifdef AZZERT if (TraceDebugger) { tty->print_cr("StepLoc: thread: 0x%x, class: 0x%x, method: 0x%x, off: 0x%x", thread_id, loc().clazz_id(), (int)(loc().method_id() & 0xFFFFFFFF), loc().offset()); } #endif loc().set_mod_kind(mod_kind); StepModifier::Fast smod = loc.obj(); smod().set_thread_id(thread_id); if (thread.is_null() /* || (thread.state() & THREAD_DEAD) */) { /* * If you try to single step after suspending because * of an uncaught exception event we'll get sent the * thread id of the thread that had the exception. * That thread is dead though. */ error = true; out->set_error(JDWP_Error_INVALID_THREAD); return NULL; } smod().set_step_size(in->read_int()); smod().set_step_depth(in->read_int()); /* query the _proxy_ for next line location */ { UsingFastOops fast_oops_6; DebuggerEvent d_event; d_event.set_event_kind((jbyte)VM_STEPINFO_EVENT); VMEvent::stepping_info_request(&d_event, in->transport(), &smod); /* * At this point, the proxy has made sure no more commands * from the debugger get sent until we get our line number * info from the proxy */ JavaDebugger::set_loop_count(1); JavaDebugger::process_command_loop(); /* * Once we get back here, then we know we've gotten the * command from the proxy with the line number info put into * the StepModifier object in the step_info_event above. */ /* setup the relevant info */ thread().set_is_stepping(true); // set the _debugger_active flag for the interpreter loop JavaDebugger::set_stepping(true); // smod = step_info_event().mods(); // smod().set_step_target_offset(stepData().step_target_offset()); smod().unlink_method(); if (smod().step_depth() == JDWP_StepDepth_OUT) { // if stepping out to the caller, we really should unlink any // compiled code from here to the caller frame, for now assume // one frame up. It could be re-compiled but we may luck out. Method::Fast m; Frame caller(jf); jf.caller_is(caller); if (!caller.is_entry_frame()) { m = caller.as_JavaFrame().method(); #if ENABLE_COMPILER if (m().has_compiled_code()) { m().unlink_compiled_code(); } #endif } } smod().set_step_starting_fp(DISTANCE(thread().stack_base(), jf.fp())); smod().set_step_starting_offset(jf.bci()); // smod().set_dup_current_line_offset(stepData().dup_current_line_offset()); // smod().set_post_dup_line_offset(stepData().post_dup_line_offset()); thread().set_step_info(&smod); } return smod; } } error = true; out->set_error(JDWP_Error_NOT_IMPLEMENTED); return NULL; }
void ReferenceTypeImpl::static_field_getter_setter(PacketInputStream *in, PacketOutputStream *out, bool is_setter) { UsingFastOops fast_oops; InstanceClass::Fast clazz = in->read_class_ref(); jint num = in->read_int(); int i; #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Static %s: class=0x%lx, count=%ld", (is_setter ? "Set" : "Get"), clazz.obj(), num); } #endif // Prevent compiler warnings clazz = clazz; // Create a buffered output stream so we can asynchronously send an error // Calculate the size based on half of the items being 'longs' if (!is_setter) { out->write_int(num); } for (i = 0; i < num; i++) { UsingFastOops fast_oops_2; InstanceClass::Fast field_clazz = in->read_class_ref(); TypeArray::Fast fields; jint field_id = in->read_int(); char type_tag; if (field_clazz.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } fields = field_clazz().fields(); if (fields.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } if (field_id >= fields().length() / Field::NUMBER_OF_SLOTS) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } Field field(&field_clazz, field_id * Field::NUMBER_OF_SLOTS); if (!field.is_static() || (is_setter && field.is_final())) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } type_tag = (field.type() < T_OBJECT ) ? JavaDebugger::get_tag_from_type(field.type()) : JDWP_Tag_OBJECT; Oop::Fast p; #if ENABLE_ISOLATES // Statics don't live at the end of the JavaClassDesc, we need to // find the correct task mirror for this task { SETUP_ERROR_CHECKER_ARG; TaskGCContext tmp(in->transport()->task_id()); TaskMirror::Fast tm = field_clazz().task_mirror_no_check(); if (!TaskMirrorDesc::is_initialized_mirror((TaskMirrorDesc*)tm.obj())) { GUARANTEE(field_clazz().is_interface(), "Non-interface class not initialized"); if (field_clazz().is_interface()) { SAVE_CURRENT_EXCEPTION; // If an interface contains only non-object data then // it will not get initialized since javac will only // create a reference to the interface class if you // are accessing some static object like a static array // We need to at least initialized the statics tm = task_barrier(Thread::current(), field_clazz.obj() JVM_NO_CHECK); if (tm.is_null()) { // oome RESTORE_CURRENT_EXCEPTION; out->send_error(JDWP_Error_OUT_OF_MEMORY); return; } RESTORE_CURRENT_EXCEPTION; } } p = tm(); } #else p = field_clazz(); #endif if (is_setter) { ObjectReferenceImpl::read_value_to_address(in, &p, field.offset(), type_tag, true); } else { ObjectReferenceImpl::write_value_from_address(out, &p, field.offset(), type_tag, true, true); } #ifdef AZZERT if (TraceDebugger) { tty->print(" "); JavaDebugger::print_class(&field_clazz); tty->print("."); JavaDebugger::print_field(&field); tty->print(": "); ObjectReferenceImpl::print_value_from_address(&p, field.offset(), type_tag); tty->print_cr(""); } #endif } out->send_packet(); }
void ObjectReferenceImpl::object_field_getter_setter(PacketInputStream *in, PacketOutputStream *out, bool is_setter) { UsingFastOops fast_oops; int i; Oop::Fast object = in->read_object(); jint num = in->read_int(); if (object.is_null()) { out->send_error(JDWP_Error_INVALID_OBJECT); return; } // Create a buffered output stream so we can asynchronously send an error // Calculate the size based on half of the items being 'longs' #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Object %s, objectID=%ld, object=0x%lx, count=%ld", (is_setter ? "Set" : "Get"), JavaDebugger::get_object_id_by_ref_nocreate(&object), object.obj(), num); } #endif if (!is_setter) { out->write_int(num); } for (i = 0; i < num; i++) { UsingFastOops fast_oops_2; InstanceClass::Fast fieldClazz = in->read_class_ref(); TypeArray::Fast fields; jint field_id = in->read_int(); if (fieldClazz.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } fields = fieldClazz().fields(); if (fields.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } if (field_id >=fields().length() / Field::NUMBER_OF_SLOTS) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } Field field(&fieldClazz, field_id * Field::NUMBER_OF_SLOTS); char type_tag = (field.type() < T_OBJECT) ? JavaDebugger::get_tag_from_type(field.type()) : JDWP_Tag_OBJECT; if (is_setter) { read_value_to_address(in, &object, field.offset(), type_tag, false); } else { write_value_from_address(out, &object, field.offset(), type_tag, true, false); } #ifdef AZZERT if (TraceDebugger) { //AccessFlags field_access_flags = field.access_flags(); tty->print(" "); JavaDebugger::print_class(&fieldClazz), tty->print("."); JavaDebugger::print_field(&field); tty->print(": "); print_value_from_address(&object, field.offset(), type_tag); tty->print_cr(""); } #endif } out->send_packet(); }
void VMEvent::exception_event(Throwable *exception, JavaFrame *catch_frame, DebuggerEvent *d_event, int catch_offset) { check_notify_wanted(Dbg_EventKind_EXCEPTION); UsingFastOops fast_oops; VMEvent::Fast ep, ep_2; jlong throw_offset = 0; int event_count = 0; jbyte suspend_policy = JDWP_SuspendPolicy_NONE; InstanceClass::Fast ic; LocationModifier::Fast location; Method::Fast catch_method; Method::Fast throw_method; int data_len = JDWP_EVENT_LEN; ep = ep_2 = get_event_request(d_event, event_count, suspend_policy); if (ep.is_null()) { return; } // Flush any packets waiting in the queue. This helps avoid a race // condition where we may have a resume command in the queue for a // previous event, we send this event, process the resume command // out of order JavaDebugger::dispatch(0); // Calculate packet length data_len += (JDWP_EVENT_EXCEPTION_LEN * event_count); Transport::Fast transport = ep().transport(); PacketOutputStream out(&transport, data_len, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); // Create a buffered output stream so we can asynchronously send an error // Calculate the size based on half of the items being 'longs' UsingFastOops fast_oops_2; Thread::Fast thread = JavaDebugger::get_thread_by_id(d_event->thread_id()); VMEventModifier::deoptimize_frame(&thread, true); VMEvent::Fast info_event = find_event((jbyte)VM_EXCEPTION_INFO_EVENT); if (!info_event.is_null()) { location = get_modifier(&info_event, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!location.is_null(), "No location modifier in info event"); throw_method = location().method(); throw_offset = location().offset(); remove_event_request(&info_event); } else { UsingFastOops fast_oops_3; ObjArray::Fast trace, methods; TypeArray::Fast offsets; trace = exception->backtrace(); if (!trace.is_null()) { methods = trace().obj_at(0); offsets = trace().obj_at(1); if (!methods.is_null() && !offsets.is_null()) { throw_method = methods().obj_at(0); throw_offset = (jlong)(offsets().int_at(0)); } } } DEBUGGER_EVENT(("Exception")); out.write_byte(suspend_policy); out.write_int(event_count); while (ep.not_null()) { out.write_byte(JDWP_EventKind_EXCEPTION); out.write_int(ep().event_id()); // thread with exception out.write_int(d_event->thread_id()); // location of exception throw if (throw_method.not_null()) { ic = throw_method().holder(); } DebuggerEvent throw_event(JDWP_EventKind_EXCEPTION, 0, // don't need thread JavaDebugger::get_object_id_by_ref(&ic), JavaDebugger::get_method_id(&ic, &throw_method), (jlong)throw_offset); throw_event.write_as_location(&out); // thrown exception out.write_byte('L'); out.write_object(exception); // location of catch, or 0 if not caught if (catch_frame == NULL) { LocationModifier::write_null_location(&out); } else { catch_method = catch_frame->method(); ic = catch_method().holder(); DebuggerEvent catch_event(JDWP_EventKind_EXCEPTION, 0, // don't need thread JavaDebugger::get_object_id_by_ref(&ic), JavaDebugger::get_method_id(&ic, &catch_method), (jlong)catch_offset); catch_event.write_as_location(&out); } ep = ep().send_next(); } out.send_packet(); JavaDebugger::process_suspend_policy(suspend_policy, &thread, true); }