Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2831 → Rev 2832

/branches/tracing/uspace/app/sctrace/debug_api.c
0,0 → 1,58
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#include <stdio.h>
#include <syscall.h>
#include <ipc/ipc.h>
#include <udebug.h>
 
#include "debug_api.h"
 
int debug_begin(unsigned phoneid)
{
return ipc_call_sync_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN);
}
 
int debug_thread_read(unsigned phoneid, void *buffer, unsigned n,
unsigned *copied, unsigned *needed)
{
printf("send IPC_M_DEBUG_THREAD_READ message\n");
return ipc_call_sync_3_2(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
(sysarg_t)buffer, n, copied, needed);
}
 
int debug_mem_read(unsigned phoneid, void *buffer, unsigned addr, unsigned n)
{
return ipc_call_sync_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ,
(sysarg_t)buffer, addr, n);
}
 
int debug_args_read(unsigned phoneid, unsigned tid, unsigned *buffer)
{
unsigned copied;
int rc;
 
rc = ipc_call_sync_4_1(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
tid, (sysarg_t)buffer, 6 * sizeof(unsigned), &copied);
 
if (copied != 6 * sizeof(unsigned)) {
printf("Warning: read %d bytes from syscall args instead of 24!\n",
copied);
}
 
return rc;
}
 
int debug_go(unsigned phoneid, unsigned tid, unsigned *ev_type,
unsigned *sc_id, unsigned *sc_rc)
{
/* Run thread until a syscall is executed */
return ipc_call_sync_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
tid, (sysarg_t)ev_type, (sysarg_t)sc_id, (sysarg_t)sc_rc);
}
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/errors.h
0,0 → 1,20
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#ifndef ERRORS_H_
#define ERRORS_H_
 
typedef struct {
char *name; /**< Error value name (Exx) */
char *desc; /**< Error description */
} err_desc_t;
 
extern const err_desc_t err_desc[];
 
#endif
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/syscalls.h
0,0 → 1,28
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#ifndef SYSCALLS_H_
#define SYSCALLS_H_
 
typedef enum {
RV_INTEGER,
RV_HASH,
RV_ERRNO,
RV_INT_ERRNO
} rv_type_t;
 
typedef struct {
char *name;
int n_args;
rv_type_t rv_type;
} sc_desc_t;
 
extern const sc_desc_t syscall_desc[];
 
#endif
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/debug_api.h
0,0 → 1,22
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#ifndef DEBUG_API_H_
#define DEBUG_API_H_
 
int debug_begin(unsigned phoneid);
int debug_thread_read(unsigned phoneid, void *buffer, unsigned n,
unsigned *copied, unsigned *needed);
int debug_mem_read(unsigned phoneid, void *buffer, unsigned addr, unsigned n);
int debug_args_read(unsigned phoneid, unsigned tid, unsigned *buffer);
int debug_go(unsigned phoneid, unsigned tid, unsigned *ev_type,
unsigned *sc_id, unsigned *sc_rc);
 
 
#endif
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/sctrace.c
0,0 → 1,195
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#include <stdio.h>
#include <unistd.h>
#include <syscall.h>
#include <ipc/ipc.h>
#include <udebug.h>
 
#include "syscalls.h"
#include "errors.h"
#include "debug_api.h"
 
#define TIDBUF_SIZE 64
unsigned threadid_buf[TIDBUF_SIZE];
 
int phoneid;
 
int task_connect(int taskid)
{
int rc;
 
printf("ipc_connect_task(%d)...\n", taskid);
rc = ipc_connect_kbox(taskid);
printf("-> %d\n", rc);
phoneid = rc;
if (rc < 0) return rc;
 
printf("debug_begin()\n");
rc = debug_begin(phoneid);
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 = debug_thread_read(phoneid, (unsigned)threadid_buf,
TIDBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
printf("-> %d\n", rc);
if (rc < 0) return rc;
 
printf("thread IDs:");
for (i=0; i<tb_copied / sizeof(unsigned); i++) {
printf(" %u", threadid_buf[i]);
}
printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
 
return 0;
}
 
void print_sc_retval(int retval, rv_type_t rv_type)
{
printf (" -> ");
if (rv_type == RV_INTEGER) {
printf("%d", retval);
} else if (rv_type == RV_HASH) {
printf("0x%08x", retval);
} else if (rv_type == RV_ERRNO) {
if (retval >= -15 && retval <= 0) {
printf("%d %s (%s)", retval,
err_desc[retval].name,
err_desc[retval].desc);
} else {
printf("%d", retval);
}
} else if (rv_type == RV_INT_ERRNO) {
if (retval >= -15 && retval < 0) {
printf("%d %s (%s)", retval,
err_desc[retval].name,
err_desc[retval].desc);
} else {
printf("%d", retval);
}
}
putchar('\n');
}
 
void print_sc_args(unsigned *sc_args, int n)
{
int i;
 
putchar('(');
if (n > 0) printf("%d", sc_args[0]);
for (i=1; i<n; i++) {
printf(", %d", sc_args[i]);
}
putchar(')');
}
 
void sc_ipc_call_async_slow(unsigned *sc_args)
{
unsigned ipc_args[6];
int rc;
 
memset(ipc_args, 0, sizeof(ipc_args));
rc = debug_mem_read(phoneid, ipc_args, sc_args[1], sizeof(ipc_args));
 
if (rc >= 0) {
printf("args: (%u, %u, %u, %u, %u, %u)\n",
ipc_args[0], ipc_args[1], ipc_args[2],
ipc_args[3], ipc_args[4], ipc_args[5]);
}
}
 
void trace_loop(void)
{
int rc;
unsigned sc_args[6];
unsigned copied;
unsigned ev_type;
unsigned sc_id;
int sc_rc;
int rv_type;
 
while (1) {
/* Run thread until a syscall is executed */
rc = debug_go(phoneid, threadid_buf[0],
&ev_type, &sc_id, &sc_rc);
 
/* Read syscall arguments */
if (rc >= 0) {
rc = debug_args_read(phoneid, threadid_buf[0],
sc_args);
}
 
/* Print syscall name, id and arguments */
if (rc >= 0) {
printf("%s", syscall_desc[sc_id].name);
print_sc_args(sc_args, syscall_desc[sc_id].n_args);
rv_type = syscall_desc[sc_id].rv_type;
print_sc_retval(sc_rc, rv_type);
}
 
switch (sc_id) {
case SYS_IPC_CALL_ASYNC_SLOW:
sc_ipc_call_async_slow(sc_args);
break;
default:
break;
}
}
}
 
 
void trace_active_task(void)
{
int taskid;
int i;
int rc;
 
printf("Syscall Tracer\n");
printf("Press 'c' to connect\n");
while ((i = getchar()) != 'c')
putchar(i);
 
taskid = 13;
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;
}
 
trace_loop();
 
printf("done\n");
return;
}
 
int main(void)
{
trace_active_task();
}
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/Makefile
0,0 → 1,76
#
# 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 = sctrace
SOURCES = sctrace.c \
syscalls.c \
errors.c \
debug_api.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/app/sctrace/errors.c
0,0 → 1,32
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#include "errors.h"
 
const err_desc_t err_desc[] = {
/* 0 */ { "EOK", "No error" },
/* -1 */ { "ENOENT", "No such entry" },
/* -2 */ { "ENOMEM", "Not enough memory" },
/* -3 */ { "ELIMIT", "Limit exceeded" },
/* -4 */ { "EREFUSED", "Connection refused" },
 
/* -5 */ { "EFORWARD", "Forward error" },
/* -6 */ { "EPERM", "Permission denied" },
/* -7 */ { "EHANGUP", "Answerbox closed connection" },
/* -8 */ { "EEXISTS", "Entry already exists" },
/* -9 */ { "EBADMEM", "Bad memory pointer" },
 
/* -10 */ { "ENOTSUP", "Not supported" },
/* -11 */ { "EADDRNOTAVAIL", "Address not available." },
/* -12 */ { "ETIMEOUT", "Timeout expired" },
/* -13 */ { "EINVAL", "Invalid value" },
/* -14 */ { "EBUSY", "Resource is busy" },
 
/* -15 */ { "EOVERFLOW", "The result does not fit its size." }
};
 
/** @}
*/
/branches/tracing/uspace/app/sctrace/syscalls.c
0,0 → 1,50
/** @addtogroup sctrace
* @{
*/
/** @file
*/
 
#include "syscalls.h"
 
const sc_desc_t syscall_desc[] = {
{ "io", 3, RV_INT_ERRNO },
{ "tls_set", 1, RV_ERRNO },
{ "thread_create", 3, RV_ERRNO },
{ "thread_exit", 1, RV_ERRNO },
{ "thread_get_id", 1, RV_ERRNO },
 
{ "task_get_id", 1, RV_ERRNO },
{ "futex_sleep_timeout", 3, RV_ERRNO },
{ "futex_wakeup", 1, RV_ERRNO },
 
{ "as_area_create", 3, RV_ERRNO },
{ "as_area_resize", 3, RV_ERRNO },
{ "as_area_destroy", 1, RV_ERRNO },
 
{ "ipc_call_sync_fast", 6, RV_ERRNO },
{ "ipc_call_sync_slow", 3, RV_ERRNO },
{ "ipc_call_async_fast", 6, RV_HASH },
{ "ipc_call_async_slow", 2, RV_HASH },
 
{ "ipc_answer_fast", 6, RV_ERRNO },
{ "ipc_answer_slow", 2, RV_ERRNO },
{ "ipc_forward_fast", 6, RV_ERRNO },
{ "ipc_wait_for_call", 3, RV_HASH },
{ "ipc_hangup", 1, RV_ERRNO },
{ "ipc_register_irq", 4, RV_ERRNO },
{ "ipc_unregister_irq", 2, RV_ERRNO },
 
{ "cap_grant", 2, RV_ERRNO },
{ "cap_revoke", 2, RV_ERRNO },
{ "physmem_map", 4, RV_ERRNO },
{ "iospace_enable", 1, RV_ERRNO },
{ "preempt_control", 1, RV_ERRNO },
 
{ "sysinfo_valid", 2, RV_HASH },
{ "sysinfo_value", 2, RV_HASH },
{ "debug_enable_console", 0, RV_ERRNO },
{ "ipc_connect_kbox", 1, RV_ERRNO }
};
 
/** @}
*/
/branches/tracing/uspace/Makefile
45,6 → 45,7
srv/fs/tmpfs \
srv/vfs \
srv/devmap \
app/sctrace \
app/tetris \
app/tester \
app/klog \
/branches/tracing/boot/arch/sparc64/loader/Makefile
91,6 → 91,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/ia64/loader/Makefile
91,6 → 91,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/arm32/loader/Makefile
89,6 → 89,7
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/branches/tracing/boot/arch/ppc32/loader/Makefile
88,6 → 88,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/ia32xen/grub/menu.lst
15,6 → 15,7
module /boot/tmpfs
module /boot/fat
module /boot/devmap
module /boot/sctrace
module /boot/tetris
module /boot/tester
module /boot/klog
/branches/tracing/boot/arch/ia32xen/grub/menu.debug.lst
11,6 → 11,7
module /boot/fb
module /boot/kbd
module /boot/console
module /boot/sctrace
module /boot/tetris
module /boot/tester
module /boot/klog
/branches/tracing/boot/arch/ia32xen/Makefile.inc
37,6 → 37,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/amd64/grub/menu.lst
10,6 → 10,7
module /boot/fb
module /boot/kbd
module /boot/console
module /boot/sctrace
module /boot/tetris
module /boot/tester
module /boot/klog
/branches/tracing/boot/arch/amd64/Makefile.inc
37,6 → 37,7
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/ppc64/loader/Makefile
88,6 → 88,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/mips32/loader/Makefile
87,6 → 87,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog
/branches/tracing/boot/arch/ia32/grub/menu.lst
14,6 → 14,7
module /boot/tmpfs
module /boot/fat
module /boot/devmap
module /boot/sctrace
module /boot/tetris
module /boot/tester
module /boot/klog
/branches/tracing/boot/arch/ia32/Makefile.inc
37,6 → 37,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/app/sctrace/sctrace \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog