/branches/tracing/uspace/app/debug/include/arch.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup debug |
* @{ |
*/ |
/** @file |
*/ |
#ifndef ARCH_H_ |
#define ARCH_H_ |
#include <sys/types.h> |
#include <udebug.h> |
void arch_breakpoint_add(uintptr_t addr); |
void arch_event_breakpoint(thash_t thread_hash); |
void arch_event_trap(thash_t thread_hash); |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/app/debug/include/arch |
---|
0,0 → 1,0 |
link ../arch/ia32/include |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/tracing/uspace/app/debug/cmd.c |
---|
40,6 → 40,7 |
#include <sys/types.h> |
#include "main.h" |
#include "include/arch.h" |
#include "cmd.h" |
static void cmd_break(int argc, char *argv[]); |
60,32 → 61,12 |
static void cmd_break(int argc, char *argv[]) |
{ |
uintptr_t addr; |
char brkp[1]; |
int rc; |
breakpoint_t *brk; |
int i; |
brk = NULL; |
for (i = 0; i < MAX_BRKPTS; i++) |
if (brk_list[i].set == 0) brk = brk_list+i; |
if (!brk) { |
printf("too many breakpoints\n"); |
return; |
} |
(void)argc; |
addr = strtoul(argv[1], NULL, 0); |
printf("You requested a breakpoint at 0x%x\n", addr); |
rc = udebug_mem_read(app_phone, &brk->back, addr, 1); |
printf("udebug_mem_read() -> %d\n", rc); |
brkp[0] = 0xcc; |
rc = udebug_mem_write(app_phone, brkp, addr, 1); |
printf("udebug_mem_write() -> %d\n", rc); |
brk->addr = addr; |
brk->set = 1; |
arch_breakpoint_add(addr); |
} |
void cmd_help(int argc, char *argv[]) |
/branches/tracing/uspace/app/debug/main.c |
---|
44,6 → 44,7 |
#include <string.h> |
#include "cmd.h" |
#include "include/arch.h" |
#include "main.h" |
void thread_debug_start(unsigned thread_hash); |
221,10 → 222,44 |
static unsigned buffer[1024]; |
static void debug_event(thash_t thash, udebug_event_t ev_type, sysarg_t val0) |
{ |
switch (ev_type) { |
case UDEBUG_EVENT_STOP: |
printf("stop event\n"); |
printf("waiting for resume\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("resumed\n"); |
break; |
case UDEBUG_EVENT_THREAD_B: |
event_thread_b(val0); |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("thread 0x%x exited\n", val0); |
abort_debug = true; |
break; |
case UDEBUG_EVENT_BREAKPOINT: |
printf("breakpoint reached\n"); |
arch_event_breakpoint(thash); |
break; |
case UDEBUG_EVENT_TRAP: |
printf("trap event\n"); |
arch_event_trap(thash); |
break; |
default: |
printf("unknown event type %d\n", ev_type); |
break; |
} |
} |
void debug_loop(void *thread_hash_arg) |
{ |
int rc; |
unsigned ev_type; |
udebug_event_t ev_type; |
unsigned thread_hash; |
unsigned thread_id; |
unsigned val0, val1; |
241,78 → 276,12 |
rc = udebug_go(app_phone, thread_hash, |
&ev_type, &val0, &val1); |
printf("..ev type %d\n", ev_type); |
// printf("rc = %d, ev_type=%d\n", rc, ev_type); |
if (ev_type == UDEBUG_EVENT_FINISHED) { |
printf("thread %u debugging finished\n", thread_id); |
break; |
} |
if (rc >= 0) { |
switch (ev_type) { |
case UDEBUG_EVENT_STOP: |
printf("stop event\n"); |
printf("waiting for resume\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("resumed\n"); |
break; |
case UDEBUG_EVENT_THREAD_B: |
event_thread_b(val0); |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("thread 0x%x exited\n", val0); |
abort_debug = true; |
break; |
case UDEBUG_EVENT_BREAKPOINT: |
printf("breakpoint reached\n"); |
rc = udebug_regs_read(app_phone, thread_hash, buffer); |
printf("udebug_regs_read -> %d\n", rc); |
int eip_idx = 12; |
int efl_idx = 14; |
printf("EIP was 0x%08x\n", buffer[eip_idx]); |
int brk_addr = buffer[eip_idx] - 1; |
int bi; |
for (bi = 0; bi < MAX_BRKPTS; bi++) |
if (brk_list[bi].set && brk_list[bi].addr == brk_addr) |
break; |
if (bi < MAX_BRKPTS) { |
buffer[eip_idx] = brk_addr; |
buffer[efl_idx] |= 0x0100; /* trap flag */ |
printf("setting EIP to 0x%08x\n", buffer[eip_idx]); |
rc = udebug_regs_write(app_phone, thread_hash, buffer); |
rc = udebug_mem_write(app_phone, &brk_list[bi].back, brk_addr, 1); |
printf("udebug_mem_write(phone, 0x%x, 0x%02x, 1) -> %d\n", brk_addr, brk_list[bi].back, rc); |
lifted_brkpt = bi; |
} else { |
printf("unrecognized breakpoint at 0x%x\n", brk_addr); |
} |
break; |
case UDEBUG_EVENT_TRAP: |
printf("trap event\n"); |
unsigned char brkinstr[1]; |
breakpoint_t *lb = &brk_list[lifted_brkpt]; |
brkinstr[0] = 0xcc; |
rc = udebug_mem_write(app_phone, brkinstr, lb->addr, 1); |
printf("restore breakpoint -> %d\n", rc); |
rc = udebug_regs_read(app_phone, thread_hash, buffer); |
printf("udebug_regs_read -> %d\n", rc); |
int efl_idx2 = 14; |
buffer[efl_idx2] &= ~0x0100; /* trap flag */ |
rc = udebug_regs_write(app_phone, thread_hash, buffer); |
break; |
default: |
printf("unknown event type %d\n", ev_type); |
usleep(1000*1000); |
break; |
} |
} |
if (rc >= 0) debug_event(thread_hash, ev_type, val0); |
} |
printf("debug_loop(%d) exiting\n", thread_id); |
/branches/tracing/uspace/app/debug/main.h |
---|
35,10 → 35,12 |
#ifndef MAIN_H_ |
#define MAIN_H_ |
#include "include/arch/types.h" |
typedef struct { |
int set; |
unsigned char back; |
unsigned addr; |
breakpoint_arch_t arch; |
} breakpoint_t; |
#define MAX_BRKPTS 64 |
/branches/tracing/uspace/app/debug/Makefile |
---|
1,5 → 1,6 |
# |
# Copyright (c) 2005 Martin Decky |
# Copyright (c) 2008 Jiri Svoboda |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
32,6 → 33,7 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
include arch/$(ARCH)/Makefile.inc |
CFLAGS += -I../../srv/kbd/include |
41,15 → 43,19 |
# |
OUTPUT = debug |
SOURCES = cmd.c \ |
GENERIC_SOURCES = cmd.c \ |
main.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
.PHONY: all clean depend disasm |
.PHONY: all clean depend disasm inc |
all: $(OUTPUT) disasm |
all: inc $(OUTPUT) disasm |
inc: |
ln -sfn ../arch/$(ARCH)/include include/arch |
-include Makefile.depend |
clean: |
56,10 → 62,10 |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(CC) $(DEFS) $(CFLAGS) -M $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
/branches/tracing/uspace/app/debug/arch/ia32/include/types.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup debug |
* @{ |
*/ |
/** @file |
*/ |
#ifndef TYPES_H_ |
#define TYPES_H_ |
typedef struct { |
unsigned char back; |
} breakpoint_arch_t; |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/app/debug/arch/ia32/Makefile.inc |
---|
0,0 → 1,29 |
# |
# Copyright (c) 2008 Jiri Svoboda |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
ARCH_SOURCES := arch/$(ARCH)/src/ia32.c |
/branches/tracing/uspace/app/debug/arch/ia32/src/ia32.c |
---|
0,0 → 1,120 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup debug |
* @{ |
*/ |
/** @file |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <udebug.h> |
#include "../../../main.h" |
#include "../../../include/arch.h" |
#define OPCODE_INT3 0xCC |
#define ISTATE_OFF_EIP 12 |
#define ISTATE_OFF_EFLAGS 14 |
void arch_breakpoint_add(uintptr_t addr) |
{ |
char brkp[1]; |
int rc; |
breakpoint_t *brk; |
int i; |
brk = NULL; |
for (i = 0; i < MAX_BRKPTS; i++) |
if (brk_list[i].set == 0) brk = brk_list+i; |
if (!brk) { |
printf("too many breakpoints\n"); |
return; |
} |
rc = udebug_mem_read(app_phone, &brk->arch.back, addr, 1); |
printf("udebug_mem_read() -> %d\n", rc); |
brkp[0] = OPCODE_INT3; |
rc = udebug_mem_write(app_phone, brkp, addr, 1); |
printf("udebug_mem_write() -> %d\n", rc); |
brk->addr = addr; |
brk->set = 1; |
} |
static unsigned buffer[1024]; |
static breakpoint_t *lifted_brkpt; |
void arch_event_breakpoint(thash_t thread_hash) |
{ |
int rc; |
rc = udebug_regs_read(app_phone, thread_hash, buffer); |
printf("udebug_regs_read -> %d\n", rc); |
printf("EIP was 0x%08x\n", buffer[ISTATE_OFF_EIP]); |
int brk_addr = buffer[ISTATE_OFF_EIP] - 1; |
int bi; |
for (bi = 0; bi < MAX_BRKPTS; bi++) { |
if (brk_list[bi].set && brk_list[bi].addr == brk_addr) |
break; |
} |
if (bi < MAX_BRKPTS) { |
buffer[ISTATE_OFF_EIP] = brk_addr; |
buffer[ISTATE_OFF_EFLAGS] |= 0x0100; /* trap flag */ |
printf("setting EIP to 0x%08x\n", buffer[ISTATE_OFF_EIP]); |
rc = udebug_regs_write(app_phone, thread_hash, buffer); |
rc = udebug_mem_write(app_phone, &brk_list[bi].arch.back, brk_addr, 1); |
printf("udebug_mem_write(phone, 0x%x, 0x%02x, 1) -> %d\n", brk_addr, brk_list[bi].arch.back, rc); |
lifted_brkpt = &brk_list[bi]; |
} else { |
printf("unrecognized breakpoint at 0x%x\n", brk_addr); |
} |
} |
void arch_event_trap(thash_t thread_hash) |
{ |
unsigned char brkinstr[1]; |
int rc; |
breakpoint_t *lb = lifted_brkpt; |
brkinstr[0] = OPCODE_INT3; |
rc = udebug_mem_write(app_phone, brkinstr, lb->addr, 1); |
printf("restore breakpoint -> %d\n", rc); |
rc = udebug_regs_read(app_phone, thread_hash, buffer); |
printf("udebug_regs_read -> %d\n", rc); |
buffer[ISTATE_OFF_EFLAGS] &= ~0x0100; /* trap flag */ |
rc = udebug_regs_write(app_phone, thread_hash, buffer); |
} |
/** @} |
*/ |