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

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

Issue 9726017: Fix use-after-free bug in debugger (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 ASSERT(!func.HasOptimizedCode()); 310 ASSERT(!func.HasOptimizedCode());
311 Code& code = Code::Handle(func.unoptimized_code()); 311 Code& code = Code::Handle(func.unoptimized_code());
312 ASSERT(!code.IsNull()); // Function must be compiled. 312 ASSERT(!code.IsNull()); // Function must be compiled.
313 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 313 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
314 ASSERT(pc_desc_index < desc.Length()); 314 ASSERT(pc_desc_index < desc.Length());
315 token_index_ = desc.TokenIndex(pc_desc_index); 315 token_index_ = desc.TokenIndex(pc_desc_index);
316 ASSERT(token_index_ >= 0); 316 ASSERT(token_index_ >= 0);
317 pc_ = desc.PC(pc_desc_index); 317 pc_ = desc.PC(pc_desc_index);
318 ASSERT(pc_ != 0); 318 ASSERT(pc_ != 0);
319 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); 319 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index);
320 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) ||
321 (breakpoint_kind_ == PcDescriptors::kFuncCall) ||
322 (breakpoint_kind_ == PcDescriptors::kReturn));
320 } 323 }
321 324
322 325
323 CodeBreakpoint::~CodeBreakpoint() { 326 CodeBreakpoint::~CodeBreakpoint() {
324 // Make sure we don't leave patched code behind. 327 // Make sure we don't leave patched code behind.
325 ASSERT(!IsEnabled()); 328 ASSERT(!IsEnabled());
329 // Poison the data so we catch use after free errors.
330 #ifdef DEBUG
331 function_ = Function::null();
332 pc_ = 0ul;
333 src_bpt_ = NULL;
334 next_ = NULL;
335 breakpoint_kind_ = PcDescriptors::kOther;
336 #endif
326 } 337 }
327 338
328 339
329 RawScript* CodeBreakpoint::SourceCode() { 340 RawScript* CodeBreakpoint::SourceCode() {
330 const Function& func = Function::Handle(function_); 341 const Function& func = Function::Handle(function_);
331 const Class& cls = Class::Handle(func.owner()); 342 const Class& cls = Class::Handle(func.owner());
332 return cls.script(); 343 return cls.script();
333 } 344 }
334 345
335 346
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } 518 }
508 519
509 520
510 void Debugger::InstrumentForStepping(const Function& target_function) { 521 void Debugger::InstrumentForStepping(const Function& target_function) {
511 if (target_function.HasCode()) { 522 if (target_function.HasCode()) {
512 EnsureFunctionIsDeoptimized(target_function); 523 EnsureFunctionIsDeoptimized(target_function);
513 } else { 524 } else {
514 Compiler::CompileFunction(target_function); 525 Compiler::CompileFunction(target_function);
515 // If there were any errors, ignore them silently and return without 526 // If there were any errors, ignore them silently and return without
516 // adding breakpoints to target. 527 // adding breakpoints to target.
517 if (!target_function.HasCode()) { 528 if (!target_function.HasCode()) {
siva 2012/03/19 22:45:22 If this path is taken internal breakpoints would n
hausner 2012/03/19 23:35:15 See comments below.
518 return; 529 return;
519 } 530 }
520 } 531 }
532 RemoveInternalBreakpoints();
521 Code& code = Code::Handle(target_function.unoptimized_code()); 533 Code& code = Code::Handle(target_function.unoptimized_code());
522 ASSERT(!code.IsNull()); 534 ASSERT(!code.IsNull());
523 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 535 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
524 for (int i = 0; i < desc.Length(); i++) { 536 for (int i = 0; i < desc.Length(); i++) {
525 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); 537 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i));
526 if (bpt != NULL) { 538 if (bpt != NULL) {
527 // There is already a breakpoint for this address. Leave it alone. 539 // There is already a breakpoint for this address. Leave it alone.
528 continue; 540 continue;
529 } 541 }
530 PcDescriptors::Kind kind = desc.DescriptorKind(i); 542 PcDescriptors::Kind kind = desc.DescriptorKind(i);
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 885
874 if (resume_action_ == kContinue) { 886 if (resume_action_ == kContinue) {
875 RemoveInternalBreakpoints(); 887 RemoveInternalBreakpoints();
876 } else if (resume_action_ == kStepOver) { 888 } else if (resume_action_ == kStepOver) {
877 Function& func = Function::Handle(bpt->function()); 889 Function& func = Function::Handle(bpt->function());
878 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) { 890 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) {
879 // If we are at the function return, do a StepOut action. 891 // If we are at the function return, do a StepOut action.
880 if (stack_trace->Length() > 1) { 892 if (stack_trace->Length() > 1) {
881 ActivationFrame* caller = stack_trace->ActivationFrameAt(1); 893 ActivationFrame* caller = stack_trace->ActivationFrameAt(1);
882 func = caller->DartFunction().raw(); 894 func = caller->DartFunction().raw();
883 RemoveInternalBreakpoints();
884 } 895 }
885 } 896 }
886 InstrumentForStepping(func); 897 InstrumentForStepping(func);
887 } else if (resume_action_ == kStepInto) { 898 } else if (resume_action_ == kStepInto) {
888 RemoveInternalBreakpoints();
889 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) { 899 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) {
890 int num_args, num_named_args; 900 int num_args, num_named_args;
891 uword target; 901 uword target;
892 CodePatcher::GetInstanceCallAt(bpt->pc_, NULL, 902 CodePatcher::GetInstanceCallAt(bpt->pc_, NULL,
893 &num_args, &num_named_args, &target); 903 &num_args, &num_named_args, &target);
894 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); 904 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0);
895 Instance& receiver = Instance::Handle( 905 Instance& receiver = Instance::Handle(
896 top_frame->GetInstanceCallReceiver(num_args)); 906 top_frame->GetInstanceCallReceiver(num_args));
897 Code& code = Code::Handle( 907 Code& code = Code::Handle(
898 ResolveCompileInstanceCallTarget(isolate_, receiver)); 908 ResolveCompileInstanceCallTarget(isolate_, receiver));
899 if (!code.IsNull()) { 909 if (!code.IsNull()) {
900 Function& callee = Function::Handle(code.function()); 910 Function& callee = Function::Handle(code.function());
901 InstrumentForStepping(callee); 911 InstrumentForStepping(callee);
902 } 912 }
siva 2012/03/19 22:45:22 What happens if code.IsNull() is true? (internal b
hausner 2012/03/19 23:35:15 Ok, mixing the instrumenting function and deleting
903 } else if (bpt->breakpoint_kind_ == PcDescriptors::kFuncCall) { 913 } else if (bpt->breakpoint_kind_ == PcDescriptors::kFuncCall) {
904 Function& callee = Function::Handle(); 914 Function& callee = Function::Handle();
905 uword target; 915 uword target;
906 CodePatcher::GetStaticCallAt(bpt->pc_, &callee, &target); 916 CodePatcher::GetStaticCallAt(bpt->pc_, &callee, &target);
907 InstrumentForStepping(callee); 917 InstrumentForStepping(callee);
908 } else { 918 } else {
909 ASSERT(bpt->breakpoint_kind_ == PcDescriptors::kReturn); 919 ASSERT(bpt->breakpoint_kind_ == PcDescriptors::kReturn);
910 // Treat like stepping out to caller. 920 // Treat like stepping out to caller.
911 if (stack_trace->Length() > 1) { 921 if (stack_trace->Length() > 1) {
912 ActivationFrame* caller = stack_trace->ActivationFrameAt(1); 922 ActivationFrame* caller = stack_trace->ActivationFrameAt(1);
913 InstrumentForStepping(caller->DartFunction()); 923 InstrumentForStepping(caller->DartFunction());
914 } 924 }
siva 2012/03/19 22:45:22 What about the case when stack_trace->Length() ==
hausner 2012/03/19 23:35:15 Ditto.
915 } 925 }
916 } else { 926 } else {
917 ASSERT(resume_action_ == kStepOut); 927 ASSERT(resume_action_ == kStepOut);
918 // Set stepping breakpoints in the caller. 928 // Set stepping breakpoints in the caller.
919 RemoveInternalBreakpoints();
920 if (stack_trace->Length() > 1) { 929 if (stack_trace->Length() > 1) {
921 ActivationFrame* caller = stack_trace->ActivationFrameAt(1); 930 ActivationFrame* caller = stack_trace->ActivationFrameAt(1);
922 InstrumentForStepping(caller->DartFunction()); 931 InstrumentForStepping(caller->DartFunction());
siva 2012/03/19 22:45:22 Ditto question.
hausner 2012/03/19 23:35:15 Ditto.
923 } 932 }
924 } 933 }
925 } 934 }
926 935
927 936
928 void Debugger::Initialize(Isolate* isolate) { 937 void Debugger::Initialize(Isolate* isolate) {
929 if (initialized_) { 938 if (initialized_) {
930 return; 939 return;
931 } 940 }
932 isolate_ = isolate; 941 isolate_ = isolate;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 } 1080 }
1072 1081
1073 1082
1074 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 1083 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
1075 ASSERT(bpt->next() == NULL); 1084 ASSERT(bpt->next() == NULL);
1076 bpt->set_next(code_breakpoints_); 1085 bpt->set_next(code_breakpoints_);
1077 code_breakpoints_ = bpt; 1086 code_breakpoints_ = bpt;
1078 } 1087 }
1079 1088
1080 } // namespace dart 1089 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698