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

Side by Side Diff: src/frames.cc

Issue 3436006: Enhance SafeStackFrameIterator to avoid triggering assertions in debug mode. (Closed)
Patch Set: Created 10 years, 3 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 | « src/frames.h ('k') | src/ia32/frames-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 if (thread_ != NULL) { 136 if (thread_ != NULL) {
137 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state); 137 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state);
138 handler_ = StackHandler::FromAddress(Top::handler(thread_)); 138 handler_ = StackHandler::FromAddress(Top::handler(thread_));
139 } else { 139 } else {
140 ASSERT(fp_ != NULL); 140 ASSERT(fp_ != NULL);
141 state.fp = fp_; 141 state.fp = fp_;
142 state.sp = sp_; 142 state.sp = sp_;
143 state.pc_address = 143 state.pc_address =
144 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); 144 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_));
145 type = StackFrame::ComputeType(&state); 145 type = StackFrame::ComputeType(&state);
146 if (SingletonFor(type) == NULL) return;
147 } 146 }
147 if (SingletonFor(type) == NULL) return;
148 frame_ = SingletonFor(type, &state); 148 frame_ = SingletonFor(type, &state);
149 } 149 }
150 150
151 151
152 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, 152 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type,
153 StackFrame::State* state) { 153 StackFrame::State* state) {
154 if (type == StackFrame::NONE) return NULL; 154 if (type == StackFrame::NONE) return NULL;
155 StackFrame* result = SingletonFor(type); 155 StackFrame* result = SingletonFor(type);
156 ASSERT(result != NULL); 156 ASSERT(result != NULL);
157 result->state_ = *state; 157 result->state_ = *state;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 Object* script = JSFunction::cast(frame()->function())->shared()->script(); 196 Object* script = JSFunction::cast(frame()->function())->shared()->script();
197 // Don't show functions from native scripts to user. 197 // Don't show functions from native scripts to user.
198 return (script->IsScript() && 198 return (script->IsScript() &&
199 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); 199 Script::TYPE_NATIVE != Script::cast(script)->type()->value());
200 } 200 }
201 201
202 202
203 // ------------------------------------------------------------------------- 203 // -------------------------------------------------------------------------
204 204
205 205
206 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) {
207 if (!validator_.IsValid(fp)) return false;
208 Address sp = ExitFrame::ComputeStackPointer(fp);
209 if (!validator_.IsValid(sp)) return false;
210 StackFrame::State state;
211 ExitFrame::FillState(fp, sp, &state);
212 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) {
213 return false;
214 }
215 return *state.pc_address != NULL;
216 }
217
218
206 SafeStackFrameIterator::SafeStackFrameIterator( 219 SafeStackFrameIterator::SafeStackFrameIterator(
207 Address fp, Address sp, Address low_bound, Address high_bound) : 220 Address fp, Address sp, Address low_bound, Address high_bound) :
208 maintainer_(), low_bound_(low_bound), high_bound_(high_bound), 221 maintainer_(),
209 is_valid_top_( 222 stack_validator_(low_bound, high_bound),
210 IsWithinBounds(low_bound, high_bound, 223 is_valid_top_(IsValidTop(low_bound, high_bound)),
211 Top::c_entry_fp(Top::GetCurrentThread())) &&
212 Top::handler(Top::GetCurrentThread()) != NULL),
213 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), 224 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
214 is_working_iterator_(is_valid_top_ || is_valid_fp_), 225 is_working_iterator_(is_valid_top_ || is_valid_fp_),
215 iteration_done_(!is_working_iterator_), 226 iteration_done_(!is_working_iterator_),
216 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { 227 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
217 } 228 }
218 229
219 230
231 bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) {
232 Address fp = Top::c_entry_fp(Top::GetCurrentThread());
233 ExitFrameValidator validator(low_bound, high_bound);
234 if (!validator.IsValidFP(fp)) return false;
235 return Top::handler(Top::GetCurrentThread()) != NULL;
236 }
237
238
220 void SafeStackFrameIterator::Advance() { 239 void SafeStackFrameIterator::Advance() {
221 ASSERT(is_working_iterator_); 240 ASSERT(is_working_iterator_);
222 ASSERT(!done()); 241 ASSERT(!done());
223 StackFrame* last_frame = iterator_.frame(); 242 StackFrame* last_frame = iterator_.frame();
224 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 243 Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
225 // Before advancing to the next stack frame, perform pointer validity tests 244 // Before advancing to the next stack frame, perform pointer validity tests
226 iteration_done_ = !IsValidFrame(last_frame) || 245 iteration_done_ = !IsValidFrame(last_frame) ||
227 !CanIterateHandles(last_frame, iterator_.handler()) || 246 !CanIterateHandles(last_frame, iterator_.handler()) ||
228 !IsValidCaller(last_frame); 247 !IsValidCaller(last_frame);
229 if (iteration_done_) return; 248 if (iteration_done_) return;
(...skipping 21 matching lines...) Expand all
251 270
252 271
253 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { 272 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
254 StackFrame::State state; 273 StackFrame::State state;
255 if (frame->is_entry() || frame->is_entry_construct()) { 274 if (frame->is_entry() || frame->is_entry_construct()) {
256 // See EntryFrame::GetCallerState. It computes the caller FP address 275 // See EntryFrame::GetCallerState. It computes the caller FP address
257 // and calls ExitFrame::GetStateForFramePointer on it. We need to be 276 // and calls ExitFrame::GetStateForFramePointer on it. We need to be
258 // sure that caller FP address is valid. 277 // sure that caller FP address is valid.
259 Address caller_fp = Memory::Address_at( 278 Address caller_fp = Memory::Address_at(
260 frame->fp() + EntryFrameConstants::kCallerFPOffset); 279 frame->fp() + EntryFrameConstants::kCallerFPOffset);
261 if (!IsValidStackAddress(caller_fp)) { 280 ExitFrameValidator validator(stack_validator_);
262 return false; 281 if (!validator.IsValidFP(caller_fp)) return false;
263 }
264 } else if (frame->is_arguments_adaptor()) { 282 } else if (frame->is_arguments_adaptor()) {
265 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that 283 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
266 // the number of arguments is stored on stack as Smi. We need to check 284 // the number of arguments is stored on stack as Smi. We need to check
267 // that it really an Smi. 285 // that it really an Smi.
268 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> 286 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
269 GetExpression(0); 287 GetExpression(0);
270 if (!number_of_args->IsSmi()) { 288 if (!number_of_args->IsSmi()) {
271 return false; 289 return false;
272 } 290 }
273 } 291 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 IteratePc(v, pc_address(), code()); 426 IteratePc(v, pc_address(), code());
409 v->VisitPointer(&code_slot()); 427 v->VisitPointer(&code_slot());
410 } 428 }
411 429
412 430
413 Address ExitFrame::GetCallerStackPointer() const { 431 Address ExitFrame::GetCallerStackPointer() const {
414 return fp() + ExitFrameConstants::kCallerSPDisplacement; 432 return fp() + ExitFrameConstants::kCallerSPDisplacement;
415 } 433 }
416 434
417 435
436 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
437 if (fp == 0) return NONE;
438 Address sp = ComputeStackPointer(fp);
439 FillState(fp, sp, state);
440 ASSERT(*state->pc_address != NULL);
441 return EXIT;
442 }
443
444
445 void ExitFrame::FillState(Address fp, Address sp, State* state) {
446 state->sp = sp;
447 state->fp = fp;
448 state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize);
449 }
450
451
418 Address StandardFrame::GetExpressionAddress(int n) const { 452 Address StandardFrame::GetExpressionAddress(int n) const {
419 const int offset = StandardFrameConstants::kExpressionsOffset; 453 const int offset = StandardFrameConstants::kExpressionsOffset;
420 return fp() + offset - n * kPointerSize; 454 return fp() + offset - n * kPointerSize;
421 } 455 }
422 456
423 457
424 int StandardFrame::ComputeExpressionsCount() const { 458 int StandardFrame::ComputeExpressionsCount() const {
425 const int offset = 459 const int offset =
426 StandardFrameConstants::kExpressionsOffset + kPointerSize; 460 StandardFrameConstants::kExpressionsOffset + kPointerSize;
427 Address base = fp() + offset; 461 Address base = fp() + offset;
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 ZoneList<StackFrame*> list(10); 932 ZoneList<StackFrame*> list(10);
899 for (StackFrameIterator it; !it.done(); it.Advance()) { 933 for (StackFrameIterator it; !it.done(); it.Advance()) {
900 StackFrame* frame = AllocateFrameCopy(it.frame()); 934 StackFrame* frame = AllocateFrameCopy(it.frame());
901 list.Add(frame); 935 list.Add(frame);
902 } 936 }
903 return list.ToVector(); 937 return list.ToVector();
904 } 938 }
905 939
906 940
907 } } // namespace v8::internal 941 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/ia32/frames-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698