/branches/tracing/uspace/app/debug/cmd.c |
---|
0,0 → 1,84 |
/* |
* 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 <string.h> |
#include <bool.h> |
#include "cmd.h" |
static void cmd_break(int argc, char *argv[]); |
void cmd_help(int argc, char *argv[]); |
static void cmd_quit(int argc, char *argv[]); |
volatile bool quit = false; |
cmd_desc_t cmd_table[] = { |
{ 1, "break", cmd_break }, |
{ 0, "help", cmd_help }, |
{ 0, "quit", cmd_quit }, |
{ -1, NULL, NULL } |
}; |
static void cmd_break(int argc, char *argv[]) |
{ |
uintptr_t addr; |
(void)argc; |
addr = strtoul(argv[1], NULL, 0); |
printf("You requested a breakpoint at 0x%x\n", addr); |
} |
void cmd_help(int argc, char *argv[]) |
{ |
int i; |
(void)argc; (void)argv; |
i = 0; |
while (cmd_table[i].name != NULL) { |
printf("%s\n", cmd_table[i].name); |
++i; |
} |
} |
static void cmd_quit(int argc, char *argv[]) |
{ |
(void)argc; (void)argv; |
quit = true; |
} |
/** @} |
*/ |
/branches/tracing/uspace/app/debug/main.c |
---|
0,0 → 1,351 |
/* |
* 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 <unistd.h> |
#include <syscall.h> |
#include <ipc/ipc.h> |
#include <fibril.h> |
#include <errno.h> |
#include <udebug.h> |
#include <async.h> |
#include <string.h> |
#include "cmd.h" |
void thread_debug_start(unsigned thread_hash); |
#define INBUF_SIZE 64 |
char in_buf[INBUF_SIZE]; |
#define MAX_ARGC 10 |
int cmd_argc; |
char *cmd_argv[MAX_ARGC + 1]; /* need one spare field for cmd_split() */ |
#define THBUF_SIZE 64 |
thash_t thread_hash_buf[THBUF_SIZE]; |
unsigned n_threads; |
int next_thread_id; |
int app_phone; |
volatile bool abort_debug; |
thash_t thash; |
volatile int paused; |
void read_line(char *buffer, int n) |
{ |
char c; |
int i; |
i = 0; |
while (i < n - 1) { |
c = getchar(); |
if (c == '\n') break; |
if (c == '\b') { |
if (i > 0) { |
putchar('\b'); |
--i; |
} |
continue; |
} |
putchar(c); |
buffer[i++] = c; |
} |
putchar('\n'); |
buffer[i] = '\0'; |
} |
void command_split(char *cmd_str) |
{ |
char *p = cmd_str; |
if (*p == '\0') { |
cmd_argc = 0; |
return; |
} |
cmd_argc = 1; |
cmd_argv[0] = p; |
while (*p != '\0') { |
if (*p == ' ') { |
cmd_argv[cmd_argc++] = p + 1; |
*p = '\0'; |
} |
++p; |
} |
} |
void command_run(void) |
{ |
int i; |
int cmp_len; |
int len; |
int idx_found; |
int num_found; |
len = strlen(cmd_argv[0]); |
cmp_len = 1; |
while (cmp_len <= len + 1) { |
num_found = 0; |
i = 0; |
while (cmd_table[i].name != NULL) { |
if (strncmp(cmd_table[i].name, cmd_argv[0], cmp_len) == 0) { |
idx_found = i; |
++num_found; |
} |
++i; |
} |
if (num_found < 2) break; |
--cmp_len; |
} |
if (num_found == 0) { |
printf("Unknown command. Try one of:\n"); |
cmd_help(0, NULL); |
return; |
} |
if (cmd_argc - 1 != cmd_table[idx_found].argc) { |
printf("Command '%s' expects %d arguments\n", |
cmd_table[idx_found].name, cmd_table[idx_found].argc); |
return; |
} |
(*cmd_table[idx_found].proc)(cmd_argc, cmd_argv); |
} |
int task_connect(int taskid) |
{ |
int rc; |
printf("ipc_connect_kbox(%d)... ", taskid); |
rc = ipc_connect_kbox(taskid); |
printf("-> %d\n", rc); |
app_phone = rc; |
if (rc < 0) return rc; |
printf("udebug_begin()... "); |
rc = udebug_begin(app_phone); |
printf("-> %d\n", rc); |
if (rc < 0) return rc; |
printf("udebug_set_evmask(0x%x)... ", UDEBUG_EM_ALL); |
rc = udebug_set_evmask(app_phone, UDEBUG_EM_ALL); |
printf("-> %d\n", rc); |
if (rc < 0) return rc; |
return 0; |
} |
int get_thread_list(void) |
{ |
int rc; |
int tb_copied; |
int tb_needed; |
int i; |
printf("send IPC_M_DEBUG_THREAD_READ message\n"); |
rc = udebug_thread_read(app_phone, (unsigned)thread_hash_buf, |
THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
printf("-> %d\n", rc); |
if (rc < 0) return rc; |
n_threads = tb_copied / sizeof(unsigned); |
printf("thread IDs:"); |
for (i=0; i<n_threads; i++) { |
printf(" %u", thread_hash_buf[i]); |
} |
printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
return 0; |
} |
void event_thread_b(unsigned hash) |
{ |
async_serialize_start(); |
printf("new thread, hash 0x%x\n", hash); |
async_serialize_end(); |
thread_debug_start(hash); |
} |
void debug_loop(void *thread_hash_arg) |
{ |
int rc; |
unsigned ev_type; |
unsigned thread_hash; |
unsigned thread_id; |
unsigned val0, val1; |
thread_hash = (unsigned)thread_hash_arg; |
thread_id = next_thread_id++; |
printf("debug_loop(%d)\n", thread_id); |
while (!abort_debug) { |
/* Run thread until an event occurs */ |
rc = udebug_go(app_phone, thread_hash, |
&ev_type, &val0, &val1); |
// 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; |
default: |
printf("unknown event type %d\n", ev_type); |
break; |
} |
} |
} |
printf("debug_loop(%d) exiting\n", thread_id); |
} |
void thread_debug_start(unsigned thread_hash) |
{ |
fid_t fid; |
thash = thread_hash; |
fid = fibril_create(debug_loop, (void *)thread_hash); |
if (fid == 0) { |
printf("Warning: Failed creating fibril\n"); |
} |
fibril_add_ready(fid); |
} |
void debug_active_task(void) |
{ |
int taskid; |
int i; |
int rc; |
int c; |
printf("Breakpoint Debugger\n"); |
printf("Press 'c' to connect\n"); |
while ((i = getchar()) != 'c') |
putchar(i); |
taskid = 14; |
rc = task_connect(taskid); |
if (rc < 0) { |
printf("Failed to connect to task %d\n", taskid); |
return; |
} |
printf("Connected to task %d\n", taskid); |
rc = get_thread_list(); |
if (rc < 0) { |
printf("Failed to get thread list (error %d)\n", rc); |
return; |
} |
abort_debug = false; |
for (i = 0; i < n_threads; i++) { |
thread_debug_start(thread_hash_buf[i]); |
} |
while (!quit) { |
printf("> "); |
read_line(in_buf, INBUF_SIZE); |
command_split(in_buf); |
if (cmd_argc == 0) continue; |
command_run(); |
} |
printf("terminate debugging session...\n"); |
abort_debug = true; |
udebug_end(app_phone); |
ipc_hangup(app_phone); |
printf("done\n"); |
return; |
} |
static void main_init(void) |
{ |
next_thread_id = 1; |
paused = 0; |
} |
int main(void) |
{ |
main_init(); |
while (1) { |
debug_active_task(); |
} |
} |
/** @} |
*/ |
/branches/tracing/uspace/app/debug/cmd.h |
---|
0,0 → 1,56 |
/* |
* 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 CMD_H_ |
#define CMD_H_ |
#include <bool.h> |
typedef void (*cmd_proc_t)(int argc, char *argv[]); |
typedef struct { |
int argc; |
char *name; |
cmd_proc_t proc; |
} cmd_desc_t; |
extern cmd_desc_t cmd_table[]; |
extern volatile bool quit; |
void cmd_help(int argc, char *argv[]); |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/app/debug/Makefile |
---|
0,0 → 1,74 |
# |
# Copyright (c) 2005 Martin Decky |
# 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. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = debug |
SOURCES = cmd.c \ |
main.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |