Bug 5554 - sytemtap.syscall failures on ia64.
Summary: sytemtap.syscall failures on ia64.
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: testsuite (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-01-08 20:07 UTC by Masami Hiramatsu
Modified: 2008-01-29 16:36 UTC (History)
0 users

See Also:
Host: ia64
Target:
Build:
Last reconfirmed:


Attachments
Fix alarm testcase on ia64 (324 bytes, patch)
2008-01-09 21:13 UTC, Masami Hiramatsu
Details | Diff
Fix stat testcase on ia64 (336 bytes, patch)
2008-01-09 21:13 UTC, Masami Hiramatsu
Details | Diff
Fix syscall.fork to check kernel_thread/clone (448 bytes, patch)
2008-01-09 21:21 UTC, Masami Hiramatsu
Details | Diff
Fix syscall.fork to check kernel_thread/clone take2 (786 bytes, patch)
2008-01-22 22:48 UTC, Masami Hiramatsu
Details | Diff
Avoid depending on linux-2.6.24 defines (301 bytes, patch)
2008-01-25 15:33 UTC, William Cohen
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Masami Hiramatsu 2008-01-08 20:07:51 UTC
On ia64@RHEL5u1, some tests(alarm, forkwait, stat) in systemtap.syscall fails.

Here are the log messages of those tests.

============================
 1)    FAIL: alarm
============================
alarm: setitimer (ITIMER_REAL, [0.000000,1.000000], 0x60000fffffa734c0) = 0
alarm: rt_sigprocmask (SIG_BLOCK, [NULL], 0x60000fffffa73480, 8) = 0
alarm: rt_sigsuspend () = -4 (EINTR)
alarm: setitimer (ITIMER_REAL, [0.000000,0.000000], 0x60000fffffa734c0) = 0
alarm: rt_sigprocmask (SIG_BLOCK, [SIGCHLD], 0x60000fffffa733f0, 8) = 0
alarm: rt_sigaction (SIGCHLD, {NULL}, 0x60000fffffa73470, 8) = 0
alarm: rt_sigprocmask (SIG_SETMASK, [SIGUSR1], 0x0000000000000000, 8) = 0
alarm: nanosleep ([1.000000000], 0x60000fffffa73360) = 0
alarm: nanosleep ([0.001234000], 0x0000000000000000) = 0
alarm: nanosleep ([0.000000789], 0x60000fffffa73500) = 0
alarm: nanosleep ([0.000000789], 0x0000000000000000) = 0
alarm: exit_group (0) = 
  alarm: exit (0) = 
--------- EXPECTED and NOT MATCHED ----------
alarm: alarm \(1\) = 0
alarm: pause \(\) =
alarm: alarm \(0\) = 0
alarm: nanosleep \(\[1.000000000\], [x0-9a-fA-F]+\) = 0
alarm: nanosleep \(\[0.001234000\], 0x[0]+\) = 0
alarm: nanosleep \(\[0.000000789\], [x0-9a-fA-F]+\) = 0
alarm: nanosleep \(\[0.000000789\], 0x[0]+\) = 0
FAIL: 64-bit alarm
FAIL alarm
============================
 2)    FAIL: forkwait
============================
forkwait: fork_kernel_thread (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID) = 21905
forkwait: wait4 (21905, 0x60000fffff8a35a8, WNOHANG, 0x0000000000000000) = 0
forkwait: exit_group (0) = 
  forkwait: exit (0) = 
--------- EXPECTED and NOT MATCHED ----------
forkwait: clone \(CLONE_CHILD_CLEARTID\|CLONE_CHILD_SETTID\) = [\-0-9]+
forkwait: wait4 \([\-0-9]+, [x0-9a-fA-F]+, WNOHANG, [x0-9a-fA-F]+\) = [\-0-9]+
FAIL: 64-bit forkwait
FAIL forkwait
============================
 3)    FAIL: stat
============================
stat: utimes ("foobar", [1.000000][1135641600.000000]) = 
  stat: futimesat (AT_FDCWD, "foobar", [1.000000][1135641600.000000]) = 0
stat: utimes ("foobar", [1135690000.000000][1135700000.000000]) = 
  stat: futimesat (AT_FDCWD, "foobar", [1135690000.000000][1135700000.000000]) = 0
stat: exit_group (0) = 
  stat: exit (0) = 
--------- EXPECTED and NOT MATCHED ----------
stat: utime \("foobar", \[1970/01/01-00:00:01, 2005/12/27-00:00:00\]\) = 0
stat: utime \("foobar", \[2005/12/27-13:26:40, 2005/12/27-16:13:20\]\) = 0
FAIL: 64-bit stat
FAIL stat
===
Comment 1 Masami Hiramatsu 2008-01-08 21:48:36 UTC
I compared those results with strace's output.

============================
 1)    alarm
============================
setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={1, 0}}, {it_interval={0,
0}, it_value={0, 0}}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigsuspend([] <unfinished ...>
--- SIGALRM (Alarm clock) @ a000000000010621 (0) ---
<... rt_sigsuspend resumed> )           = -1 EINTR (Interrupted system call)
rt_sigreturn()                          = ? (mask now [])
setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 0}}, {it_interval={0,
0}, it_value={0, 0}}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, {1, 0})               = 0
nanosleep({0, 1234000}, NULL)           = 0
nanosleep({0, 789}, {6917546615532158977, 2305843009214016656}) = 0
nanosleep({0, 789}, NULL)               = 0
exit_group(0)                           = ?
=============================

From the output of strace, script's output is correct.
alarm() and pause() are implemented as a setitimer()
and a sigsuspend() respectively on ia64. Thus, this test have to check
setitimer() and sigsuspend() instead of alarm() and pause() on ia64.

============================
 2)    forkwait
============================
clone2(child_stack=0, stack_size=0,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x20000000002e0090) = 30908
wait4(30908, 0x60000ffffffd3748, WNOHANG, NULL) = 0
exit_group(0)       
=============================

Here, I found a bug; syscalls.stp failed to detect clone systemcall on ia64.
Currently, syscalls.stp(syscall.fork) checks start_stack==0, but on ia64, clone
systemcall is sometimes issued with start_stack=0. And I found that kernel_thread()
calls do_fork() with start_stack=-1 on x86-64.
Thus, we have to check another condition.

============================
 3)    stat
============================
stat("foobar", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
lstat("foobar", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
utimes("foobar", {{1, 0}, {1135641600, 0}}) = 0
utimes("foobar", {{1135690000, 0}, {1135700000, 0}}) = 0
exit_group(0)                           = ?
=============================

On ia64, since utime() is implemented by utimes(), this test have to
check utimes() on ia64.
Comment 2 Masami Hiramatsu 2008-01-09 21:13:14 UTC
Created attachment 2192 [details]
Fix alarm testcase on ia64

This patch fixes alarm syscall test.
Comment 3 Masami Hiramatsu 2008-01-09 21:13:59 UTC
Created attachment 2193 [details]
Fix stat testcase on ia64

This patch fixes stat syscall test on ia64.
Comment 4 Masami Hiramatsu 2008-01-09 21:21:06 UTC
Created attachment 2194 [details]
Fix syscall.fork to check kernel_thread/clone

This patch fixes syscall.fork check routine on x86-64/ia64.
To check whether do_fork is invoked from kernel_thread or clone syscall, this
patch uses user_mode() macro.
Comment 5 Masami Hiramatsu 2008-01-09 22:49:09 UTC
(In reply to comment #4)
> Created an attachment (id=2194)
> Fix syscall.fork to check kernel_thread/clone
> 
> This patch fixes syscall.fork check routine on x86-64/ia64.
> To check whether do_fork is invoked from kernel_thread or clone syscall, this
> patch uses user_mode() macro.

This must use kread() to access a member of pt_regs.
I'll rewrite it.
Comment 6 Masami Hiramatsu 2008-01-22 22:48:42 UTC
Created attachment 2209 [details]
Fix syscall.fork to check kernel_thread/clone take2

This patch uses kread() instead of using user_mode() directly.
I tested it on ia64, x86-64, i386.

Thanks,
Comment 7 Frank Ch. Eigler 2008-01-23 00:17:21 UTC
> This patch uses kread() instead of using user_mode() directly.
> I tested it on ia64, x86-64, i386.

It would win ugliness contests, but I can't think of a better way.
Comment 8 Masami Hiramatsu 2008-01-23 14:19:11 UTC
(In reply to comment #7)
> > This patch uses kread() instead of using user_mode() directly.
> > I tested it on ia64, x86-64, i386.
> 
> It would win ugliness contests, but I can't think of a better way.

Sure, I agreed.
Actually, I tried to find another way, but user_mode() implementation 
strongly depends on architecture. And pt_regs was too big to be copied
on some arch. I think this patch is *currently* the best way to do that.

---
If there are something like deref_area_begin/deref_area_end macro(the 
addresses between these macros are automatically registered to 
the exception table), we can use user_mode() directly. but it should 
be another enhancement.
Comment 9 Masami Hiramatsu 2008-01-24 17:02:41 UTC
I've committed this patch.
Comment 10 William Cohen 2008-01-25 15:32:24 UTC
The checked in patch for bz5554 causes the syscall tests to fail on RHEL4/5
kernel on i386 machines.

Trying to build the systemtap.syscall/sys.stp:

 ../../install/bin/stap -vv ../../src/testsuite/systemtap.syscall/sys.stp

Ends up producing the following error messages that SEGMENT_RPL_MASK and
USER_RPL undefined on  RHEL4 i386 2.6.9-67.0.1.ELsmp and RHEL5 i386
2.6.18-53.1.4.el5:

2dcdef1bb34572403776cda3605b_421823.o
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c: In function
`function___is_user_regs':
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c:33210: error:
`SEGMENT_RPL_MASK' undeclared (first use in this function)
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c:33210: error:
(Each undeclared identifier is reported only once
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c:33210: error: for
each function it appears in.)
/tmp/stapzirZcY/stap_d39a2dcdef1bb34572403776cda3605b_421823.c:33210: error:
`USER_RPL' undeclared (first use in this function)

See that linux-2.6.24/include/asm-x86/segment_32.h has definition for the
SEGMENT_RPL_MASK.

The x86_64 version has:

	THIS->__retvalue = (!!((cs & 3)));

For the x86_64 version is it going to return 1 for 1, 2, and 3 in the low bits
of cs. The i386 version is only going to return 1 if the value is 3. Why the
difference in test for x86_64 and i386? The include/asm-x86/ptrace.h has the
same logic. It seems like there could be some simplification there.

Comment 11 William Cohen 2008-01-25 15:33:49 UTC
Created attachment 2215 [details]
Avoid depending on linux-2.6.24 defines

The attached is a proposed patch to allow __is_user_regs() to work on older
i386 kernels.
Comment 12 Masami Hiramatsu 2008-01-25 15:44:01 UTC
(In reply to comment #11)
> Created an attachment (id=2215)
> Avoid depending on linux-2.6.24 defines
> 
> The attached is a proposed patch to allow __is_user_regs() to work on older
> i386 kernels.

Thank you for fixing.
It is good to me.
Comment 13 William Cohen 2008-01-28 21:52:19 UTC
The forkwait test is still failing on ia64 running both 2.6.24 and
2.6.18-53.1.4.el5 kernels. Did the tapset-fix-syscall-fork.patch work resolve
the problem on a particular ia64 kernel?
Comment 14 Masami Hiramatsu 2008-01-28 22:38:08 UTC
(In reply to comment #13)
> The forkwait test is still failing on ia64 running both 2.6.24 and
> 2.6.18-53.1.4.el5 kernels. Did the tapset-fix-syscall-fork.patch work resolve
> the problem on a particular ia64 kernel?

Yes, I checked it on the latest rhel5.
And I think you can check it by below command.

$ stap -e 'probe syscall.wait4, syscall.fork{ if (execname() == "forkwait")
printf("%s (%s)=",name,argstr)} probe syscall.wait4.return, syscall.fork.return
{if (execname() == "forkwait") printf("%s\n",retstr)}' -c ./forkwait

clone (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID)=13119
wait4 (13119, 0x60000fffff963728, WNOHANG, 0x0000000000000000)=0

The output seems good.
Comment 15 William Cohen 2008-01-29 16:18:44 UTC
Seems the runtest was running the installed /usr/bin/stap rather than the
locally built test. The current snapshot does have this fixed. For the latest
nightly run (Jan 29, 2008) that the the forkwait test passes and there are no
failures for systemtap.syscall/syscall.exp tests with a 2.6.24 kernel.
Comment 16 Frank Ch. Eigler 2008-01-29 16:36:06 UTC
(In reply to comment #15)
> Seems the runtest was running the installed /usr/bin/stap rather than the
> locally built test. [...]

Please note that installcheck is not supposed to use the freshly built stap
that may be sitting in the build tree.  It is supposed to use the $prefix/bin/*
copy of these programs.