Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: runtime/vm/debugger.cc

Issue 2815863002: Detect unhandled exceptions in async functions without an awaiter (Closed)
Patch Set: rmacnak review Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debugger.h" 5 #include "vm/debugger.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "platform/address_sanitizer.h" 9 #include "platform/address_sanitizer.h"
10 10
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 intptr_t var_desc_len = var_descriptors_.Length(); 932 intptr_t var_desc_len = var_descriptors_.Length();
933 for (intptr_t i = 0; i < var_desc_len; i++) { 933 for (intptr_t i = 0; i < var_desc_len; i++) {
934 RawLocalVarDescriptors::VarInfo var_info; 934 RawLocalVarDescriptors::VarInfo var_info;
935 var_descriptors_.GetInfo(i, &var_info); 935 var_descriptors_.GetInfo(i, &var_info);
936 const int8_t kind = var_info.kind(); 936 const int8_t kind = var_info.kind();
937 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { 937 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
938 if (FLAG_trace_debugger_stacktrace) { 938 if (FLAG_trace_debugger_stacktrace) {
939 OS::PrintErr("\tFound saved current ctx at index %d\n", 939 OS::PrintErr("\tFound saved current ctx at index %d\n",
940 var_info.index()); 940 var_info.index());
941 } 941 }
942 ctx_ ^= GetStackVar(var_info.index()); 942 const Object& obj = Object::Handle(GetStackVar(var_info.index()));
siva 2017/04/13 01:22:58 This handle could be hoisted outside the for loop.
Cutch 2017/04/13 14:34:44 Done.
943 if (obj.IsClosure()) {
944 ASSERT(function().name() == Symbols::Call().raw());
945 ASSERT(function().IsInvokeFieldDispatcher());
946 // Closure.call frames.
947 ctx_ ^= Closure::Cast(obj).context();
948 } else if (obj.IsContext()) {
949 ctx_ ^= Context::Cast(obj).raw();
950 } else {
951 ASSERT(obj.IsNull());
952 }
943 return ctx_; 953 return ctx_;
944 } 954 }
945 } 955 }
946 return Context::ZoneHandle(Context::null()); 956 return Context::ZoneHandle(Context::null());
siva 2017/04/13 01:30:06 Why is it not ok to use the same ctx_ as above i.e
Cutch 2017/04/13 14:34:44 Done.
947 } 957 }
948 958
949 959
950 RawObject* ActivationFrame::GetAsyncOperation() { 960 RawObject* ActivationFrame::GetAsyncOperation() {
951 GetVarDescriptors(); 961 GetVarDescriptors();
952 intptr_t var_desc_len = var_descriptors_.Length(); 962 intptr_t var_desc_len = var_descriptors_.Length();
953 for (intptr_t i = 0; i < var_desc_len; i++) { 963 for (intptr_t i = 0; i < var_desc_len; i++) {
954 RawLocalVarDescriptors::VarInfo var_info; 964 RawLocalVarDescriptors::VarInfo var_info;
955 var_descriptors_.GetInfo(i, &var_info); 965 var_descriptors_.GetInfo(i, &var_info);
956 if (var_descriptors_.GetName(i) == Symbols::AsyncOperation().raw()) { 966 if (var_descriptors_.GetName(i) == Symbols::AsyncOperation().raw()) {
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 } 1978 }
1969 // Follow the link. 1979 // Follow the link.
1970 async_stack_trace = async_stack_trace.async_link(); 1980 async_stack_trace = async_stack_trace.async_link();
1971 } 1981 }
1972 1982
1973 return stack_trace; 1983 return stack_trace;
1974 } 1984 }
1975 1985
1976 1986
1977 DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { 1987 DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
1978 if (!FLAG_causal_async_stacks) { 1988 if (!FLAG_async_debugger) {
1979 return NULL; 1989 return NULL;
1980 } 1990 }
1981 // Causal async stacks are not supported in the AOT runtime. 1991 // Causal async stacks are not supported in the AOT runtime.
1982 ASSERT(!FLAG_precompiled_runtime); 1992 ASSERT(!FLAG_precompiled_runtime);
1983 1993
1984 Thread* thread = Thread::Current(); 1994 Thread* thread = Thread::Current();
1985 Zone* zone = thread->zone(); 1995 Zone* zone = thread->zone();
1986 Isolate* isolate = thread->isolate(); 1996 Isolate* isolate = thread->isolate();
1987 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1997 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1988 1998
1989 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); 1999 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames);
1990 2000
1991 Code& code = Code::Handle(zone); 2001 Code& code = Code::Handle(zone);
1992 Smi& offset = Smi::Handle(zone); 2002 Smi& offset = Smi::Handle(zone);
1993 Function& function = Function::Handle(zone); 2003 Function& function = Function::Handle(zone);
1994 Code& inlined_code = Code::Handle(zone); 2004 Code& inlined_code = Code::Handle(zone);
1995 Closure& async_activation = Closure::Handle(zone); 2005 Closure& async_activation = Closure::Handle(zone);
1996 Object& next_async_activation = Object::Handle(zone); 2006 Object& next_async_activation = Object::Handle(zone);
1997 Array& deopt_frame = Array::Handle(zone); 2007 Array& deopt_frame = Array::Handle(zone);
1998 class StackTrace& async_stack_trace = StackTrace::Handle(zone); 2008 class StackTrace& async_stack_trace = StackTrace::Handle(zone);
1999 2009 bool stack_has_async_function = false;
2000 for (StackFrame* frame = iterator.NextFrame(); frame != NULL; 2010 for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
2001 frame = iterator.NextFrame()) { 2011 frame = iterator.NextFrame()) {
2002 ASSERT(frame->IsValid()); 2012 ASSERT(frame->IsValid());
2003 if (FLAG_trace_debugger_stacktrace) { 2013 if (FLAG_trace_debugger_stacktrace) {
2004 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", 2014 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
2005 frame->ToCString()); 2015 frame->ToCString());
2006 } 2016 }
2007 if (frame->IsDartFrame()) { 2017 if (frame->IsDartFrame()) {
2008 code = frame->LookupDartCode(); 2018 code = frame->LookupDartCode();
2009 if (code.is_optimized()) { 2019 if (code.is_optimized()) {
2010 deopt_frame = DeoptimizeToArray(thread, frame, code); 2020 deopt_frame = DeoptimizeToArray(thread, frame, code);
2011 bool found_async_awaiter = false; 2021 bool found_async_awaiter = false;
2012 for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done(); 2022 for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
2013 it.Advance()) { 2023 it.Advance()) {
2014 inlined_code = it.code(); 2024 inlined_code = it.code();
2015 function = it.function(); 2025 function = it.function();
2016 if (FLAG_trace_debugger_stacktrace) { 2026 if (FLAG_trace_debugger_stacktrace) {
2017 ASSERT(!function.IsNull()); 2027 ASSERT(!function.IsNull());
2018 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", 2028 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n",
2019 function.ToFullyQualifiedCString()); 2029 function.ToFullyQualifiedCString());
2020 } 2030 }
2021 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); 2031 intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
2022 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { 2032 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
2023 ActivationFrame* activation = CollectDartFrame( 2033 ActivationFrame* activation = CollectDartFrame(
2024 isolate, it.pc(), frame, inlined_code, deopt_frame, 2034 isolate, it.pc(), frame, inlined_code, deopt_frame,
2025 deopt_frame_offset, ActivationFrame::kAsyncActivation); 2035 deopt_frame_offset, ActivationFrame::kAsyncActivation);
2026 ASSERT(activation != NULL); 2036 ASSERT(activation != NULL);
2027 stack_trace->AddActivation(activation); 2037 stack_trace->AddActivation(activation);
2038 stack_has_async_function = true;
2028 // Grab the awaiter. 2039 // Grab the awaiter.
2029 async_activation ^= activation->GetAsyncAwaiter(); 2040 async_activation ^= activation->GetAsyncAwaiter();
2030 found_async_awaiter = true; 2041 found_async_awaiter = true;
2031 break; 2042 break;
2032 } else { 2043 } else {
2033 stack_trace->AddActivation( 2044 stack_trace->AddActivation(
2034 CollectDartFrame(isolate, it.pc(), frame, inlined_code, 2045 CollectDartFrame(isolate, it.pc(), frame, inlined_code,
2035 deopt_frame, deopt_frame_offset)); 2046 deopt_frame, deopt_frame_offset));
2036 } 2047 }
2037 } 2048 }
2038 // Break out of outer loop. 2049 // Break out of outer loop.
2039 if (found_async_awaiter) { 2050 if (found_async_awaiter) {
2040 break; 2051 break;
2041 } 2052 }
2042 } else { 2053 } else {
2043 function = code.function(); 2054 function = code.function();
2044 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { 2055 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
2045 ActivationFrame* activation = CollectDartFrame( 2056 ActivationFrame* activation = CollectDartFrame(
2046 isolate, frame->pc(), frame, code, Object::null_array(), 0, 2057 isolate, frame->pc(), frame, code, Object::null_array(), 0,
2047 ActivationFrame::kAsyncActivation); 2058 ActivationFrame::kAsyncActivation);
2048 ASSERT(activation != NULL); 2059 ASSERT(activation != NULL);
2049 stack_trace->AddActivation(activation); 2060 stack_trace->AddActivation(activation);
2061 stack_has_async_function = true;
2050 // Grab the awaiter. 2062 // Grab the awaiter.
2051 async_activation ^= activation->GetAsyncAwaiter(); 2063 async_activation ^= activation->GetAsyncAwaiter();
2064 async_stack_trace ^= activation->GetCausalStack();
2052 break; 2065 break;
2053 } else { 2066 } else {
2054 stack_trace->AddActivation(CollectDartFrame( 2067 stack_trace->AddActivation(CollectDartFrame(
2055 isolate, frame->pc(), frame, code, Object::null_array(), 0)); 2068 isolate, frame->pc(), frame, code, Object::null_array(), 0));
2056 } 2069 }
2057 } 2070 }
2058 } 2071 }
2059 } 2072 }
2060 2073
2061 // Return NULL to indicate that there is no useful information in this stack 2074 // If the stack doesn't have any async functions on it, return NULL.
2062 // trace because we never found an awaiter. 2075 if (!stack_has_async_function) {
2063 if (async_activation.IsNull()) {
2064 return NULL; 2076 return NULL;
2065 } 2077 }
2066 2078
2067 // Append the awaiter return call stack. 2079 // Append the awaiter return call stack.
2068 while (!async_activation.IsNull()) { 2080 while (!async_activation.IsNull()) {
2069 ActivationFrame* activation = new (zone) ActivationFrame(async_activation); 2081 ActivationFrame* activation = new (zone) ActivationFrame(async_activation);
2070 activation->ExtractTokenPositionFromAsyncClosure(); 2082 activation->ExtractTokenPositionFromAsyncClosure();
2071 stack_trace->AddActivation(activation); 2083 stack_trace->AddActivation(activation);
2072 next_async_activation = activation->GetAsyncAwaiter(); 2084 next_async_activation = activation->GetAsyncAwaiter();
2073 if (next_async_activation.IsNull()) { 2085 if (next_async_activation.IsNull()) {
(...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after
4354 4366
4355 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 4367 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
4356 ASSERT(bpt->next() == NULL); 4368 ASSERT(bpt->next() == NULL);
4357 bpt->set_next(code_breakpoints_); 4369 bpt->set_next(code_breakpoints_);
4358 code_breakpoints_ = bpt; 4370 code_breakpoints_ = bpt;
4359 } 4371 }
4360 4372
4361 #endif // !PRODUCT 4373 #endif // !PRODUCT
4362 4374
4363 } // namespace dart 4375 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698