mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
*** empty log message ***
This commit is contained in:
@ -394,7 +394,9 @@ bin_file_lookup_symbol (BinFile *bf,
|
|||||||
|
|
||||||
data = bf->symbols;
|
data = bf->symbols;
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("looking up %p in %s ", address, bf->filename);
|
g_print ("looking up %p in %s ", address, bf->filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (address < data[last].address)
|
if (address < data[last].address)
|
||||||
{
|
{
|
||||||
@ -418,7 +420,9 @@ bin_file_lookup_symbol (BinFile *bf,
|
|||||||
result = &data[last];
|
result = &data[last];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("-> %s\n", result->name);
|
g_print ("-> %s\n", result->name);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If the name is "call_gmon_start", the file probably doesn't
|
/* If the name is "call_gmon_start", the file probably doesn't
|
||||||
* have any other symbols
|
* have any other symbols
|
||||||
|
|||||||
39
process.c
39
process.c
@ -22,7 +22,7 @@ struct Map
|
|||||||
char * filename;
|
char * filename;
|
||||||
gulong start;
|
gulong start;
|
||||||
gulong end;
|
gulong end;
|
||||||
gulong offset;
|
gulong offset;
|
||||||
gboolean do_offset;
|
gboolean do_offset;
|
||||||
|
|
||||||
BinFile * bin_file;
|
BinFile * bin_file;
|
||||||
@ -34,6 +34,8 @@ struct Process
|
|||||||
|
|
||||||
GList *maps;
|
GList *maps;
|
||||||
GList *bad_pages;
|
GList *bad_pages;
|
||||||
|
|
||||||
|
int pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -68,15 +70,6 @@ should_offset (const char *filename, int pid)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_do_offset (const Map *map, int pid)
|
|
||||||
{
|
|
||||||
if (map->filename)
|
|
||||||
return should_offset (map->filename, pid);
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
read_maps (int pid)
|
read_maps (int pid)
|
||||||
{
|
{
|
||||||
@ -99,21 +92,25 @@ read_maps (int pid)
|
|||||||
guint start;
|
guint start;
|
||||||
guint end;
|
guint end;
|
||||||
guint offset;
|
guint offset;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
g_print ("buffer: %s\n", buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
count = sscanf (
|
count = sscanf (
|
||||||
buffer, "%x-%x %*15s %x %*u:%*u %*u %255s",
|
buffer, "%x-%x %*15s %x %*x:%*x %*u %255s",
|
||||||
&start, &end, &offset, file);
|
&start, &end, &offset, file);
|
||||||
if (count == 4)
|
if (count == 4)
|
||||||
{
|
{
|
||||||
Map *map;
|
Map *map;
|
||||||
|
|
||||||
map = g_new (Map, 1);
|
map = g_new (Map, 1);
|
||||||
|
|
||||||
map->filename = g_strdup (file);
|
map->filename = g_strdup (file);
|
||||||
map->start = start;
|
map->start = start;
|
||||||
map->end = end;
|
map->end = end;
|
||||||
|
|
||||||
map->offset = offset; //check_do_offset (map, pid);
|
map->offset = offset;
|
||||||
|
|
||||||
map->bin_file = NULL;
|
map->bin_file = NULL;
|
||||||
|
|
||||||
@ -137,6 +134,7 @@ create_process (const char *cmdline, int pid)
|
|||||||
p->cmdline = g_strdup_printf ("[%s]", cmdline);
|
p->cmdline = g_strdup_printf ("[%s]", cmdline);
|
||||||
p->bad_pages = NULL;
|
p->bad_pages = NULL;
|
||||||
p->maps = NULL;
|
p->maps = NULL;
|
||||||
|
p->pid = pid;
|
||||||
|
|
||||||
g_assert (!g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid)));
|
g_assert (!g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid)));
|
||||||
g_assert (!g_hash_table_lookup (processes_by_cmdline, cmdline));
|
g_assert (!g_hash_table_lookup (processes_by_cmdline, cmdline));
|
||||||
@ -269,7 +267,7 @@ process_lookup_symbol (Process *process, gulong address)
|
|||||||
g_free (undefined.name);
|
g_free (undefined.name);
|
||||||
undefined.name = g_strdup_printf ("??? (%s)", process->cmdline);
|
undefined.name = g_strdup_printf ("??? (%s)", process->cmdline);
|
||||||
undefined.address = 0xBABE0001;
|
undefined.address = 0xBABE0001;
|
||||||
|
|
||||||
return &undefined;
|
return &undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,17 +280,22 @@ process_lookup_symbol (Process *process, gulong address)
|
|||||||
if (!map->bin_file)
|
if (!map->bin_file)
|
||||||
map->bin_file = bin_file_new (map->filename);
|
map->bin_file = bin_file_new (map->filename);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* FIXME - this seems to work with prelinked binaries, but is
|
/* FIXME - this seems to work with prelinked binaries, but is
|
||||||
* it correct? IE., will normal binaries always have a preferred_addres of 0?
|
* it correct? IE., will normal binaries always have a preferred_addres of 0?
|
||||||
*/
|
*/
|
||||||
/* address = address - map->start + map->offset + bin_file_get_load_address (map->bin_file); */
|
address = address - map->start + map->offset + bin_file_get_load_address (map->bin_file);
|
||||||
/* address -= map->start; */
|
address -= map->start;
|
||||||
/* address += map->offset; */
|
address += map->offset;
|
||||||
/* address += bin_file_get_load_address (map->bin_file); */
|
address += bin_file_get_load_address (map->bin_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* g_print ("%s: start: %p, load: %p\n", */
|
/* g_print ("%s: start: %p, load: %p\n", */
|
||||||
/* map->filename, map->start, bin_file_get_load_address (map->bin_file)); */
|
/* map->filename, map->start, bin_file_get_load_address (map->bin_file)); */
|
||||||
|
|
||||||
|
if (should_offset (map->filename, process->pid))
|
||||||
|
address -= map->start;
|
||||||
|
|
||||||
result = bin_file_lookup_symbol (map->bin_file, address);
|
result = bin_file_lookup_symbol (map->bin_file, address);
|
||||||
|
|
||||||
/* g_print ("(%x) %x %x name; %s\n", address, map->start, map->offset, result->name); */
|
/* g_print ("(%x) %x %x name; %s\n", address, map->start, map->offset, result->name); */
|
||||||
|
|||||||
@ -7,14 +7,13 @@
|
|||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <linux/kernel.h> /* Needed for KERN_ALERT */
|
#include <linux/kernel.h> /* Needed for KERN_ALERT */
|
||||||
#include <linux/module.h> /* Needed by all modules */
|
#include <linux/module.h> /* Needed by all modules */
|
||||||
#ifdef KERNEL24
|
|
||||||
# include <linux/tqueue.h>
|
|
||||||
#endif
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
|
#include <linux/pagemap.h>
|
||||||
|
|
||||||
#include "sysprof-module.h"
|
#include "sysprof-module.h"
|
||||||
|
|
||||||
@ -79,13 +78,76 @@ init_userspace_reader (userspace_reader *reader,
|
|||||||
reader->page = NULL;
|
reader->page = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Access another process' address space.
|
||||||
|
* Source/target buffer must be kernel space,
|
||||||
|
* Do not walk the page table directly, use get_user_pages
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int x_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
|
||||||
|
{
|
||||||
|
struct mm_struct *mm;
|
||||||
|
struct vm_area_struct *vma;
|
||||||
|
struct page *page;
|
||||||
|
void *old_buf = buf;
|
||||||
|
|
||||||
|
mm = tsk->mm;
|
||||||
|
if (!mm)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
down_read(&mm->mmap_sem);
|
||||||
|
/* ignore errors, just check how much was sucessfully transfered */
|
||||||
|
while (len) {
|
||||||
|
int bytes, ret, offset;
|
||||||
|
void *maddr;
|
||||||
|
|
||||||
|
ret = get_user_pages(tsk, mm, addr, 1,
|
||||||
|
write, 1, &page, &vma);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bytes = len;
|
||||||
|
offset = addr & (PAGE_SIZE-1);
|
||||||
|
if (bytes > PAGE_SIZE-offset)
|
||||||
|
bytes = PAGE_SIZE-offset;
|
||||||
|
|
||||||
|
flush_cache_page(vma, addr);
|
||||||
|
|
||||||
|
maddr = kmap(page);
|
||||||
|
if (write) {
|
||||||
|
copy_to_user_page(vma, page, addr,
|
||||||
|
maddr + offset, buf, bytes);
|
||||||
|
set_page_dirty_lock(page);
|
||||||
|
} else {
|
||||||
|
copy_from_user_page(vma, page, addr,
|
||||||
|
buf, maddr + offset, bytes);
|
||||||
|
}
|
||||||
|
kunmap(page);
|
||||||
|
page_cache_release(page);
|
||||||
|
len -= bytes;
|
||||||
|
buf += bytes;
|
||||||
|
addr += bytes;
|
||||||
|
}
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
|
return buf - old_buf;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_user_space (userspace_reader *reader,
|
read_user_space (userspace_reader *reader,
|
||||||
unsigned long address,
|
unsigned long address,
|
||||||
unsigned long *result)
|
unsigned long *result)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
unsigned long user_page = (address & PAGE_MASK);
|
unsigned long user_page = (address & PAGE_MASK);
|
||||||
int res;
|
int res;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return x_access_process_vm(reader->task, address, result, 4, 0);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
|
||||||
|
|
||||||
if (user_page == 0)
|
if (user_page == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -93,19 +155,24 @@ read_user_space (userspace_reader *reader,
|
|||||||
if (!reader->user_page || user_page != reader->user_page) {
|
if (!reader->user_page || user_page != reader->user_page) {
|
||||||
int found;
|
int found;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
pte_t pte;
|
||||||
|
|
||||||
found = get_user_pages (reader->task, reader->task->mm, user_page,
|
found = get_user_pages (reader->task, reader->task->mm,
|
||||||
1, 0, 0, &page, NULL);
|
user_page, 1, 0, 0, &page, NULL);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!pte_present (page))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (reader->user_page)
|
if (reader->user_page)
|
||||||
kunmap (reader->page);
|
kunmap (reader->page);
|
||||||
|
|
||||||
reader->user_page = user_page;
|
|
||||||
reader->kernel_page = (unsigned long)kmap (page);
|
reader->kernel_page = (unsigned long)kmap (page);
|
||||||
|
reader->user_page = user_page;
|
||||||
reader->page = page;
|
reader->page = page;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_user (res, (int *)(reader->kernel_page + (address - user_page))) != 0)
|
if (get_user (res, (int *)(reader->kernel_page + (address - user_page))) != 0)
|
||||||
@ -115,6 +182,7 @@ read_user_space (userspace_reader *reader,
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
done_userspace_reader (userspace_reader *reader)
|
done_userspace_reader (userspace_reader *reader)
|
||||||
|
|||||||
@ -110,10 +110,12 @@ on_read (gpointer data)
|
|||||||
|
|
||||||
rd = read (app->input_fd, &trace, sizeof (trace));
|
rd = read (app->input_fd, &trace, sizeof (trace));
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("pid: %d\n", trace.pid);
|
g_print ("pid: %d\n", trace.pid);
|
||||||
for (i=0; i < trace.n_addresses; ++i)
|
for (i=0; i < trace.n_addresses; ++i)
|
||||||
g_print ("rd: %08x\n", trace.addresses[i]);
|
g_print ("rd: %08x\n", trace.addresses[i]);
|
||||||
g_print ("-=-\n");
|
g_print ("-=-\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rd > 0 && app->profiling && !app->generating_profile)
|
if (rd > 0 && app->profiling && !app->generating_profile)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user