diff --git a/ChangeLog b/ChangeLog index 71cd7bf7..4bee8fe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Tue Sep 27 01:33:33 2005 Soeren Sandmann + + * process.c (process_lookup_symbol): If the address is 0x01, treat + as kernel, regardless of whether we have a map for that address or + not. + + * module/sysprof-module.c (timer_notify): Take a stack trace of + the current process, even when we are in kernel mode. This way we + can assign kernel activity to individual user space stacktraces. + + * TODO: updates. + Sat Sep 24 14:41:23 2005 Soeren Sandmann * configure.ac: Bump version number to 1.1.0 diff --git a/TODO b/TODO index 3b240e7a..0835ed95 100644 --- a/TODO +++ b/TODO @@ -42,6 +42,20 @@ Before 1.0.1: See also http://www.fedoraproject.org/wiki/Extras/KernelModuleProposal Before 1.2: + +* Figure out how to make sfile.[ch] use less memory. + - In general clean sfile.[ch] up a little: + - split out dfa in its own generic class + - make a generic representation of xml files with quarks for strings: + struct item { + int begin/end/text; + quark text: -> begin/end/value + int id; -> for begins that are pointed to + } + perhaps even with iterators. Should be compact and suitable for both + input and output.. + - make the api a little saner; add format/content structs + - * See if the auto-expanding can be made more intelligent @@ -412,6 +426,14 @@ Later: - Profiling a login session. + - Many applications are running at the same time, doing IPC. It would be useful + if we could figure out what other things a given process is waiting on. Eg., in + poll, find out what processes have the other ends of the fd's open. + Visualization: multiple lines on a graph. Lines join up where one process + is blocking on another. That would show processes holding up the progress + very clearly. + This was suggested by Federico. + - Need to report stat() as well. (Where do inode data end up? In the buffer-cache?) Also open() may cause disk reads (seeks). diff --git a/module/sysprof-module.c b/module/sysprof-module.c index 143f58e9..3c268221 100644 --- a/module/sysprof-module.c +++ b/module/sysprof-module.c @@ -452,53 +452,43 @@ timer_notify (struct pt_regs *regs) is_user = user_mode(regs); - if (!current || current->pid == 0) + if (!current || current->pid == 0 || !current->mm) return 0; if (is_user && current->state != TASK_RUNNING) return 0; + memset(trace, 0, sizeof (SysprofStackTrace)); + + trace->pid = current->pid; + + i = 0; if (!is_user) { - /* kernel */ - - trace->pid = current->pid; - trace->truncated = 0; - trace->n_addresses = 1; - - /* 0x1 is taken by sysprof to mean "in kernel" */ - trace->addresses[0] = (void *)0x1; + trace->addresses[i++] = 0x01; + regs = (void *)current->thread.esp0 - sizeof (struct pt_regs); } - else + + trace->addresses[i++] = (void *)regs->REG_INS_PTR; + + frame = (StackFrame *)regs->REG_FRAME_PTR; + + while (pages_present (frame) && + i < SYSPROF_MAX_ADDRESSES && + ((unsigned long)frame) < START_OF_STACK && + (unsigned long)frame >= regs->REG_STACK_PTR) { - memset(trace, 0, sizeof (SysprofStackTrace)); - - trace->pid = current->pid; - trace->truncated = 0; - - i = 0; - - trace->addresses[i++] = (void *)regs->REG_INS_PTR; - - frame = (StackFrame *)regs->REG_FRAME_PTR; - - while (pages_present (frame) && - i < SYSPROF_MAX_ADDRESSES && - ((unsigned long)frame) < START_OF_STACK && - (unsigned long)frame >= regs->REG_STACK_PTR) - { - trace->addresses[i++] = (void *)frame->return_address; - frame = (StackFrame *)frame->next; - } - - trace->n_addresses = i; - - if (i == SYSPROF_MAX_ADDRESSES) - trace->truncated = 1; - else - trace->truncated = 0; + trace->addresses[i++] = (void *)frame->return_address; + frame = (StackFrame *)frame->next; } + trace->n_addresses = i; + + if (i == SYSPROF_MAX_ADDRESSES) + trace->truncated = 1; + else + trace->truncated = 0; + if (head++ == &stack_traces[N_TRACES - 1]) head = &stack_traces[0]; diff --git a/process.c b/process.c index 5e1cd0d2..ff14b479 100644 --- a/process.c +++ b/process.c @@ -347,42 +347,21 @@ process_lookup_symbol (Process *process, gulong address) /* g_print ("addr: %x\n", address); */ - if (!map) + if (address == 0x1) { - if (address == 0x1) - { - kernel.name = "in kernel"; - kernel.address = 0x0001337; - return &kernel; - } - else - { - if (undefined.name) - g_free (undefined.name); - undefined.name = g_strdup_printf ("??? %s", process->cmdline); - undefined.address = 0xBABE0001; - } -#if 0 - g_print ("no map for %p (%s)\n", address, process->cmdline); -#endif - + kernel.name = "in kernel"; + kernel.address = 0x00001337; + return &kernel; + } + else if (!map) + { + if (undefined.name) + g_free (undefined.name); + undefined.name = g_strdup_printf ("??? %s", process->cmdline); + undefined.address = 0xBABE0001; + return &undefined; } -#if 0 - g_print ("has map: %s\n", process->cmdline); -#endif - -#if 0 - g_print ("has map: %s\n", process->cmdline); -#endif - -/* if (map->do_offset) */ -/* address -= map->start; */ - -#if 0 - /* convert address to file coordinates */ - g_print ("looking up %p ", address); -#endif address -= map->start; address += map->offset; diff --git a/sfile.h b/sfile.h index 4e39213c..3ab07577 100644 --- a/sfile.h +++ b/sfile.h @@ -42,6 +42,11 @@ typedef guint SType; * For formats consider: * * Format *format_new (void); + * void format_free (void); + * Content *format_create_record (Format *format, Content *c1, ...); + * Content *format_create_list (Format *format, Content *t); + * Content *format_create_pointer (Format *format, Content *pointer_type); + * * void format_set_record (Format *f, Content *r); * Content *new_record (Content *c1, ...); *