* [Linux-ia64] One other question
@ 2001-04-18 5:11 Weihaw CHUANG
2001-04-18 6:21 ` Stephane Eranian
2001-04-18 7:05 ` David Mosberger
0 siblings, 2 replies; 3+ messages in thread
From: Weihaw CHUANG @ 2001-04-18 5:11 UTC (permalink / raw)
To: linux-ia64
In regards to my previous email.
What I'm really trying to get at is, is there a method to single step
instructions with user level interrupts?
-Wei
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Linux-ia64] One other question
2001-04-18 5:11 [Linux-ia64] One other question Weihaw CHUANG
@ 2001-04-18 6:21 ` Stephane Eranian
2001-04-18 7:05 ` David Mosberger
1 sibling, 0 replies; 3+ messages in thread
From: Stephane Eranian @ 2001-04-18 6:21 UTC (permalink / raw)
To: linux-ia64
Hi,
On Tue, Apr 17, 2001 at 10:11:19PM -0700, Weihaw CHUANG wrote:
> In regards to my previous email.
>
> What I'm really trying to get at is, is there a method to single step
> instructions with user level interrupts?
>
I believe you can simply do this using the ptrace() system call and
giving it the PTRACE_SINGLESTEP command. Look at arch/ia64/kernel/ptrace.c
for more details.
--
-Stephane
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Linux-ia64] One other question
2001-04-18 5:11 [Linux-ia64] One other question Weihaw CHUANG
2001-04-18 6:21 ` Stephane Eranian
@ 2001-04-18 7:05 ` David Mosberger
1 sibling, 0 replies; 3+ messages in thread
From: David Mosberger @ 2001-04-18 7:05 UTC (permalink / raw)
To: linux-ia64
>>>>> On Tue, 17 Apr 2001 23:21:03 -0700, Stephane Eranian <eranian@frankl.hpl.hp.com> said:
Stephane> Hi, On Tue, Apr 17, 2001 at 10:11:19PM -0700, Weihaw
Stephane> CHUANG wrote:
>> In regards to my previous email.
>>
>> What I'm really trying to get at is, is there a method to single
>> step instructions with user level interrupts?
Stephane> I believe you can simply do this using the ptrace() system
Stephane> call and giving it the PTRACE_SINGLESTEP command. Look at
Stephane> arch/ia64/kernel/ptrace.c for more details.
That's correct. I'm attaching a small test program I wrote a while
ago. It shows how to single step individual instructions, basic
blocks, and system calls.
--david
/*
utrace -- micro tracing tool
Copyright (C) 1999-2001 Hewlett-Packard Company
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
char *prog_name;
#if defined(__ia64__)
#include <asm/fpu.h>
#include <asm/ptrace.h>
#include <asm/ptrace_offsets.h>
#include <asm/rse.h>
int singlestep;
static inline double
fpreg_to_double (struct ia64_fpreg *fp)
{
double result;
asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp));
return result;
}
void
print_syscall (int child_pid, int state)
{
long scnum, result, error, val;
#if 0
struct ia64_fpreg fp;
#endif
unsigned long bsp;
int i;
if (state = 0)
return;
errno = 0;
scnum = ptrace (PTRACE_PEEKUSER, child_pid, PT_R15, 0);
result = ptrace (PTRACE_PEEKUSER, child_pid, PT_R8, 0);
error = ptrace (PTRACE_PEEKUSER, child_pid, PT_R10, 0);
bsp = ptrace (PTRACE_PEEKUSER, child_pid, PT_AR_BSP, 0);
#if 0
fp.u.bits[0] = ptrace (PTRACE_PEEKUSER, child_pid, PT_F32 + 0, 0);
fp.u.bits[1] = ptrace (PTRACE_PEEKUSER, child_pid, PT_F32 + 8, 0);
printf ("f32=%f\n", fpreg_to_double (&fp));
#endif
if (errno)
{
printf ("%s: ptrace() failed, errno=%d\n", prog_name, errno);
return;
}
printf ("<sc%04ld(", scnum);
for (i = 0; i < 4; ++i)
{
val = ptrace (PTRACE_PEEKDATA, child_pid,
(long) ia64_rse_skip_regs ((long *) bsp, i), 0);
printf ("%lx,", val);
}
if (error)
printf ("...) -> errno=%ld\n", result);
else
printf ("...) -> %ld\n", result);
}
void
print_state (int child_pid, int with_slot)
{
long ip, slot;
ip = ptrace (PTRACE_PEEKUSER, child_pid, PT_CR_IIP, 0);
if (with_slot)
{
slot = (ptrace (PTRACE_PEEKUSER, child_pid, PT_CR_IPSR, 0) >> 41) & 0x3;
printf ("%016lx:%ld\n", ip, slot);
}
else
printf ("%016lx\n", ip);
}
#elif defined(__i386__)
void
print_syscall (int child_pid, int state)
{
int scnum, result;
scnum = ptrace (PTRACE_PEEKUSER, child_pid, 11*4, 0); /* read EAX */
errno = 0;
result = ptrace (PTRACE_PEEKUSER, child_pid, 6*4, 0); /* read ORIG_EAX */
if (result = -ENOSYS)
return;
if (errno)
{
printf ("%s: ptrace() failed, errno=%d\n", prog_name, errno);
return;
}
printf ("<sc%03d>() -> %d\n", scnum, result);
}
#else
# error Sorry, you're architecture isn't supported.
#endif
int
main (int argc, char **argv, char **envp)
{
int status, pid, child_pid, state = 1, arg;
prog_name = argv[0];
if (argc < 2 || strcmp (argv[1], "-h") = 0)
{
printf ("Usage: %s [-abB] command args...\n", prog_name);
printf (" -a: trace instruction execution\n");
printf (" -b: trace basic block execution\n");
printf (" -s: trace system call execution (default)\n");
exit (-1);
}
arg = 1;
if (strcmp (argv[arg], "-a") = 0)
{
singlestep = 1;
++arg;
}
if (strcmp (argv[arg], "-b") = 0)
{
singlestep = 2;
++arg;
}
if (strcmp (argv[arg], "-s") = 0)
{
singlestep = 0;
++arg;
}
child_pid = fork ();
if (child_pid = 0)
{
ptrace (PTRACE_TRACEME, 0, 0, 0);
execve (argv[arg], argv + arg, envp);
printf ("%s: execve failed (errno=%d)\n", prog_name, errno);
exit (-2);
}
while (1)
{
pid = wait4 (-1, &status, 0, 0);
if (pid = -1)
{
if (errno = EINTR)
continue;
printf ("%s: wait4() failed (errno=%d)\n", prog_name, errno);
}
if (WIFSIGNALED (status) || WIFEXITED (status)
|| (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP))
{
if (WIFEXITED (status))
{
printf ("%s: exit status %d\n", prog_name, WEXITSTATUS (status));
break;
}
else if (WIFSIGNALED (status))
{
printf ("%s: terminated by signal %d\n",
prog_name, WTERMSIG (status));
}
else
printf ("%s: got signal %d\n", prog_name, WSTOPSIG (status));
}
if (singlestep)
{
/* single stepping through program: */
if (singlestep = 2)
{
print_state (child_pid, 0);
ptrace (PTRACE_SINGLEBLOCK, child_pid, 0, 0);
}
else
{
print_state (child_pid, 1);
ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0);
}
}
else
{
/* syscall tracing */
print_syscall (child_pid, state);
state = (state + 1) & 1;
ptrace (PTRACE_SYSCALL, child_pid, 0, 0); /* continue */
}
}
return 0;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2001-04-18 7:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-04-18 5:11 [Linux-ia64] One other question Weihaw CHUANG
2001-04-18 6:21 ` Stephane Eranian
2001-04-18 7:05 ` David Mosberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox