2008-12-25 15:46:41 +00:00
|
|
|
/*
|
|
|
|
** PCDebuggerView
|
|
|
|
**
|
|
|
|
** Copyright (c) 2008
|
|
|
|
**
|
|
|
|
** Author: Gregory Casamento <greg_casamento@yahoo.com>
|
|
|
|
**
|
|
|
|
** This program is free software; you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** This program is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with this program; if not, write to the Free Software
|
|
|
|
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
2008-12-16 21:31:41 +00:00
|
|
|
|
|
|
|
#include "PCDebuggerView.h"
|
2008-12-28 07:19:45 +00:00
|
|
|
#include "PCDebugger.h"
|
|
|
|
|
2008-12-26 06:38:46 +00:00
|
|
|
#include <ProjectCenter/PCProject.h>
|
|
|
|
#include <Foundation/NSScanner.h>
|
|
|
|
|
2008-12-28 07:19:45 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <signal.h>
|
|
|
|
|
2008-12-26 06:38:46 +00:00
|
|
|
#ifndef NOTIFICATION_CENTER
|
|
|
|
#define NOTIFICATION_CENTER [NSNotificationCenter defaultCenter]
|
|
|
|
#endif
|
2008-12-16 21:31:41 +00:00
|
|
|
|
|
|
|
@implementation PCDebuggerView
|
2008-12-22 00:38:35 +00:00
|
|
|
|
|
|
|
-(void)setDebugger:(PCDebugger *)theDebugger
|
|
|
|
{
|
|
|
|
debugger = theDebugger;
|
|
|
|
}
|
|
|
|
|
2008-12-25 15:46:41 +00:00
|
|
|
/**
|
|
|
|
* Log string to the view.
|
|
|
|
*/
|
|
|
|
- (void) logString:(NSString *)str
|
|
|
|
newLine:(BOOL)newLine
|
2008-12-22 00:38:35 +00:00
|
|
|
{
|
2008-12-25 15:46:41 +00:00
|
|
|
NSRange range;
|
2008-12-27 05:43:41 +00:00
|
|
|
BOOL printLine = YES;
|
2008-12-22 00:38:35 +00:00
|
|
|
|
2008-12-27 05:43:41 +00:00
|
|
|
range = [str rangeOfString: @"\032\032"]; // Breakpoint"];
|
2008-12-26 06:38:46 +00:00
|
|
|
if (range.location != NSNotFound)
|
|
|
|
{
|
2008-12-27 05:43:41 +00:00
|
|
|
NSScanner *scanner = [NSScanner scannerWithString: str];
|
|
|
|
NSCharacterSet *empty = [NSCharacterSet characterSetWithCharactersInString: @""];
|
|
|
|
NSString *file = nil;
|
|
|
|
NSString *line = nil;
|
|
|
|
NSString *bytes = nil;
|
|
|
|
int l = 0, b = 0;
|
|
|
|
|
|
|
|
[scanner setCharactersToBeSkipped: empty];
|
|
|
|
[scanner scanUpToString: @"\032\032" intoString: NULL];
|
|
|
|
[scanner scanString: @"\032\032" intoString: NULL];
|
2008-12-26 06:38:46 +00:00
|
|
|
[scanner scanUpToString: @":" intoString: &file];
|
|
|
|
[scanner scanString: @":" intoString: NULL];
|
2008-12-27 05:43:41 +00:00
|
|
|
[scanner scanUpToString: @":" intoString: &line];
|
|
|
|
if (line != nil)
|
2008-12-26 06:38:46 +00:00
|
|
|
{
|
2008-12-27 05:43:41 +00:00
|
|
|
l = [line intValue];
|
|
|
|
[scanner scanString: @":" intoString: NULL];
|
|
|
|
[scanner scanUpToString: @":" intoString: &bytes];
|
|
|
|
|
|
|
|
if (bytes != nil)
|
|
|
|
{
|
|
|
|
b = [bytes intValue];
|
|
|
|
if (l != 0 && b != 0) // if the line & bytes are parsable, then send the notification.
|
|
|
|
{
|
|
|
|
NSDictionary *dict = [NSDictionary
|
|
|
|
dictionaryWithObjectsAndKeys:
|
|
|
|
file, @"file", line, @"line", nil];
|
2008-12-28 07:19:45 +00:00
|
|
|
NSString *statusString = [NSString stringWithFormat: @"Stopped, %@:%@",file,line];
|
|
|
|
|
|
|
|
[debugger setStatus: statusString];
|
2008-12-27 05:43:41 +00:00
|
|
|
[NOTIFICATION_CENTER
|
|
|
|
postNotificationName: PCProjectBreakpointNotification
|
|
|
|
object: dict];
|
|
|
|
[[self window] makeKeyAndOrderFront: self];
|
|
|
|
printLine = NO;
|
|
|
|
}
|
|
|
|
}
|
2008-12-26 06:38:46 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-27 05:43:41 +00:00
|
|
|
|
2008-12-28 16:19:27 +00:00
|
|
|
// NOTE: This works on certain versions of gdb, but we need to come up with another way of getting
|
|
|
|
// the process id in a more generic way.
|
|
|
|
range = [str rangeOfString: @"[New Thread"];
|
|
|
|
if (range.location != NSNotFound)
|
|
|
|
{
|
|
|
|
NSScanner *scanner = [NSScanner scannerWithString: str];
|
|
|
|
NSString *process = nil;
|
|
|
|
|
|
|
|
[scanner scanUpToString: @"(LWP" intoString: NULL];
|
|
|
|
[scanner scanString: @"(LWP" intoString: NULL];
|
|
|
|
[scanner scanUpToString: @")" intoString: &process];
|
|
|
|
subProcessId = [process intValue];
|
|
|
|
}
|
|
|
|
|
2008-12-27 05:43:41 +00:00
|
|
|
// FIXME: Filter this error, until we find a better way to deal with it.
|
|
|
|
range = [str rangeOfString: @"[tcsetpgrp failed in terminal_inferior:"];
|
|
|
|
if (range.location != NSNotFound)
|
|
|
|
{
|
|
|
|
printLine = NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the line is not filtered, print it...
|
|
|
|
if(printLine)
|
|
|
|
{
|
|
|
|
[super logString: str newLine: newLine];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCurrentFile: (NSString *)fileName
|
|
|
|
{
|
|
|
|
ASSIGN(currentFile,fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) currentFile
|
|
|
|
{
|
|
|
|
return currentFile;
|
2008-12-22 00:38:35 +00:00
|
|
|
}
|
2008-12-28 07:19:45 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lookup the process id.
|
|
|
|
*/
|
|
|
|
/*
|
2008-12-28 16:19:27 +00:00
|
|
|
- (int) subProcessId
|
2008-12-28 07:19:45 +00:00
|
|
|
{
|
|
|
|
int task_pid = [task processIdentifier];
|
|
|
|
int child_pid = 0;
|
|
|
|
NSArray *entries = [[NSFileManager defaultManager] directoryContentsAtPath: @"/proc"];
|
|
|
|
NSEnumerator *en = [entries objectEnumerator];
|
|
|
|
NSString *entry = nil;
|
|
|
|
|
|
|
|
// FIXME: I'm looking for a generic way to do this, what we have here is very /proc specific.
|
|
|
|
// which I don't like since it ties this functionality to systems which have /proc.
|
|
|
|
while((entry = [en nextObject]) != nil)
|
|
|
|
{
|
|
|
|
int pid = [entry intValue];
|
|
|
|
if (pid != 0)
|
|
|
|
{
|
|
|
|
int ppid = getppid(pid);
|
|
|
|
if (ppid == task_pid)
|
|
|
|
{
|
|
|
|
child_pid = pid;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return child_pid;
|
|
|
|
}
|
2008-12-28 16:19:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
- (int) subProcessId
|
|
|
|
{
|
|
|
|
return subProcessId;
|
|
|
|
}
|
2008-12-28 07:19:45 +00:00
|
|
|
|
|
|
|
- (void) interrupt
|
|
|
|
{
|
2008-12-28 16:19:27 +00:00
|
|
|
int pid = [self subProcessId];
|
2008-12-28 07:19:45 +00:00
|
|
|
kill(pid,SIGINT);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) terminate
|
|
|
|
{
|
|
|
|
[super terminate];
|
2008-12-29 05:25:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) mouseDown: (NSEvent *)event
|
|
|
|
{
|
|
|
|
// do nothing...
|
2008-12-28 07:19:45 +00:00
|
|
|
}
|
2008-12-16 21:31:41 +00:00
|
|
|
@end
|