Mercurial > projects > ddbg_continued
view src/callstack.d @ 5:496dfd8f7342 default tip
added:
-repeat option for "in", "ov"
-run until a line option
-run until a function option
-break on a function start
-n is an alias for ov
author | marton@basel.hu |
---|---|
date | Sun, 17 Apr 2011 11:05:31 +0200 |
parents | 4a9dcbd9e54f |
children |
line wrap: on
line source
/* Ddbg - Win32 Debugger for the D programming language * Copyright (c) 2007 Jascha Wetzel * All rights reserved. See LICENSE.TXT for details. */ import util; import codeview.codeview; import expression.evaluationcontext; import std.string; /************************************************************************************************** Wraps the raw stack data with functions for unwinding it. **************************************************************************************************/ class CallStack { ubyte[] data; uint base_ptr, // the "base" of the stack, i.e. the largest address top_ptr, // the current top of the stack = Esp frame_ptr; // the current frame pointer /********************************************************************************************** Initializes the object with pointers to base, top (esp) and frame (ebp) of the stack. Resizes the data array to the required size. **********************************************************************************************/ this(uint base_ptr_, uint top_ptr_, uint frame_ptr_) { base_ptr = base_ptr_; top_ptr = top_ptr_; frame_ptr = frame_ptr_; data.length = base_ptr-top_ptr; } /********************************************************************************************** Calculates the first frame. Params: prev_index = first byte of previous frame pointer Returns: Array covering the frame. **********************************************************************************************/ ubyte[] firstFrame(out uint prev_index) { prev_index = frame_ptr-top_ptr; if ( prev_index >= data.length ) return data; return data[0..prev_index]; } /********************************************************************************************** Calculates the previous frame. Params: frame_index = start of desired frame in data array prev_index = start of previous to desired frame in data array Returns: Array covering the previous frame. **********************************************************************************************/ ubyte[] prevFrame(in uint frame_index, out uint prev_index) { if ( frame_index >= data.length-4 ) return null; uint prev_frame_ptr = (cast(uint[])data)[frame_index>>2]; if ( prev_frame_ptr < top_ptr || prev_frame_ptr > base_ptr ) return null; prev_index = prev_frame_ptr-top_ptr; assert( prev_index > frame_index && prev_index <= data.length ); return data[frame_index..prev_index]; } /********************************************************************************************** **********************************************************************************************/ ubyte[] getFrame(uint frame_level) { uint prev_frame_idx; ubyte[] frame = firstFrame(prev_frame_idx); for ( ; frame_level > 0; --frame_level ) frame = prevFrame(prev_frame_idx, prev_frame_idx); return frame; } /********************************************************************************************** Loads data from the stack for a given symbol. Returns: Array of bytes continaing the data **********************************************************************************************/ bool loadSymbolData(StackSymbol sym, SymbolData symdata, uint frame_level=0) { if ( sym is null ) return false; uint prev_frame_idx; ubyte[] frame = firstFrame(prev_frame_idx); for ( ; frame_level > 0; --frame_level ) frame = prevFrame(prev_frame_idx, prev_frame_idx); symdata.defered_load = true; bool loadSymbolData(uint offset) { // index is in this frame if ( offset <= frame.length-sym.size ) { symdata.len = sym.size; symdata.ptr = top_ptr + (frame.ptr - data.ptr) + offset; return true; } assert( offset >= frame.length ); // consider previous frame offset -= frame.length; frame = prevFrame(prev_frame_idx, prev_frame_idx); if ( frame !is null ) return loadSymbolData(offset); return false; } return loadSymbolData(frame.length+sym.cvdata.offset); } }