#import <Cocoa/Cocoa.h>
#import "BSSourceView.h"
+#import "StackController.h"
@class GDBpConnection;
{
GDBpConnection *connection;
+ StackController *stackController;
+
IBOutlet NSArrayController *stackController2;
NSArray *stack;
{
if (self = [super initWithWindowNibName:@"Debugger"])
{
+ stackController = [[StackController alloc] init];
+
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
connection = [[GDBpConnection alloc] initWithWindowController:self
port:[defaults integerForKey:@"Port"]
{
[connection release];
[expandedRegisters release];
+ [stackController release];
[super dealloc];
}
*/
- (IBAction)stepIn:(id)sender
{
- [connection stepIn];
+ StackFrame *frame = [connection stepIn];
+ if ([frame isShiftedFrame:[stackController peek]])
+ [stackController pop];
+ [stackController push:frame];
+ NSLog(@"stack = %@", stackController.stack);
}
/**
*/
- (IBAction)stepOut:(id)sender
{
- [connection stepOut];
+ StackFrame *frame = [connection stepOut];
+ [stackController pop];
+ [stackController push:frame];
+ NSLog(@"stack = %@", stackController.stack);
}
/**
*/
- (IBAction)stepOver:(id)sender
{
- [connection stepOver];
+ StackFrame *frame = [connection stepOver];
+
+ [stackController pop];
+ [stackController push:frame];
+
+ NSLog(@"stack = %@", stackController.stack);
}
/**
#import "DebuggerController.h"
#import "SocketWrapper.h"
#import "Breakpoint.h"
+#import "StackFrame.h"
@interface GDBpConnection : NSObject
{
// communication
- (void)reconnect;
- (void)run;
-- (void)stepIn;
-- (void)stepOut;
-- (void)stepOver;
+- (StackFrame *)stepIn;
+- (StackFrame *)stepOut;
+- (StackFrame *)stepOver;
- (void)addBreakpoint:(Breakpoint *)bp;
- (void)removeBreakpoint:(Breakpoint *)bp;
- (void)refreshStatus;
@interface GDBpConnection (Private)
- (NSString *)createCommand:(NSString *)cmd;
- (NSXMLDocument *)processData:(NSString *)data;
+- (StackFrame *)createStackFrame;
@end
@implementation GDBpConnection
/**
* Tells the debugger to step into the current command.
*/
-- (void)stepIn
+- (StackFrame *)stepIn
{
[socket send:[self createCommand:@"step_into"]];
[socket receive];
+
+ StackFrame *frame = [self createStackFrame];
[self refreshStatus];
+
+ return frame;
}
/**
* Tells the debugger to step out of the current context
*/
-- (void)stepOut
+- (StackFrame *)stepOut
{
[socket send:[self createCommand:@"step_out"]];
[socket receive];
+
+ StackFrame *frame = [self createStackFrame];
[self refreshStatus];
+
+ return frame;
}
/**
* Tells the debugger to step over the current function
*/
-- (void)stepOver
+- (StackFrame *)stepOver
{
[socket send:[self createCommand:@"step_over"]];
[socket receive];
+
+ StackFrame *frame = [self createStackFrame];
[self refreshStatus];
+
+ return frame;
}
/**
return [doc autorelease];
}
+/**
+ * Creates a StackFrame based on the current position in the debugger
+ */
+- (StackFrame *)createStackFrame
+{
+ [socket send:[self createCommand:@"stack_get -d 0"]];
+ NSXMLDocument *doc = [self processData:[socket receive]];
+
+ NSXMLElement *xmlframe = [[[doc rootElement] children] objectAtIndex:0];
+ StackFrame *frame = [[StackFrame alloc]
+ initWithIndex:[[[xmlframe attributeForName:@"level"] stringValue] intValue]
+ withFilename:[[xmlframe attributeForName:@"filename"] stringValue]
+ withSource:nil
+ atLine:[[[xmlframe attributeForName:@"lineno"] stringValue] intValue]
+ inFunction:[[xmlframe attributeForName:@"where"] stringValue]
+ withContexts:nil
+ ];
+
+ return [frame autorelease];
+}
+
@end
@property(readonly) NSMutableArray *stack;
+- (StackFrame *)peek;
- (StackFrame *)pop;
- (void)push:(StackFrame *)frame;
[super dealloc];
}
+/**
+ * Returns a reference to the top of the stack
+ */
+- (StackFrame *)peek
+{
+ return [stack lastObject];
+}
+
/**
* Pops the current frame off the stack and returns the frame
*/
inFunction:(NSString *)function
withContexts:(NSDictionary *)contexts;
+- (BOOL)isShiftedFrame:(StackFrame *)frame;
+
@end
return self;
}
+/**
+ * Determines whether or not the given frame was shifted, rather than jumped. Essentially,
+ * this checks if it's in the same file/function.
+ */
+- (BOOL)isShiftedFrame:(StackFrame *)frame
+{
+ return ([filename isEqualToString:frame.filename]);
+}
+
+/**
+ * Returns a human-readable representation
+ */
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"#%d %@ [%@:%d]", index, function, filename, lineNumber];
+}
+
@end