Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2910 → Rev 2911

/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 $@
/branches/tracing/uspace/Makefile
45,6 → 45,7
srv/fs/tmpfs \
srv/vfs \
srv/devmap \
app/debug \
app/sctrace \
app/tetris \
app/tester \
/branches/tracing/boot/arch/ia32/grub/menu.lst
18,3 → 18,4
module /boot/tetris
module /boot/tester
module /boot/klog
module /boot/debug
/branches/tracing/boot/arch/ia32/Makefile.inc
40,7 → 40,8
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/debug/debug
 
build: $(BASE)/image.iso