Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 2922 → Rev 2923

/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);
}
 
/** @}
*/