NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/38891: ktruss shows wrong data for lstat()
>Number: 38891
>Category: bin
>Synopsis: ktruss shows wrong data for lstat()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jun 08 15:05:00 +0000 2008
>Originator: Michael van Elst
>Release: NetBSD 4.99.64
>Organization:
>Environment:
System: NetBSD volans 4.99.64 NetBSD 4.99.64 (VOLANS) #17: Sun Jun 8 09:19:11
CEST 2008 spz@volans:/home/netbsd/src/sys/arch/i386/compile/obj/VOLANS i386
Architecture: i386
Machine: i386
>Description:
When tracing the savecore program ktruss showed bad parameters
for the lstat() system call. Using ktrace/kdump is fine.
Here is an example program excercising the problem:
#include <dirent.h>
#include <errno.h>
#include <paths.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
char *
find_dev(dev_t dev, int type)
{
DIR *dfd;
struct dirent *dir;
struct stat sb;
char *dp, device[MAXPATHLEN + 1], *p;
size_t l;
if ((dfd = opendir(_PATH_DEV)) == NULL) {
syslog(LOG_ERR, "%s: %m", _PATH_DEV);
exit(1);
}
strlcpy(device, _PATH_DEV, sizeof(device));
p = &device[strlen(device)];
l = sizeof(device) - strlen(device);
while ((dir = readdir(dfd))) {
strlcpy(p, dir->d_name, l);
printf("%s %s\n",device,p);
fflush(stdout);
if (lstat(device, &sb)) {
syslog(LOG_ERR, "%s: %m", device);
continue;
}
printf("%s %s %o %d\n",device,p,sb.st_mode,sb.st_rdev);
fflush(stdout);
if ((sb.st_mode & S_IFMT) != type)
continue;
if (dev == sb.st_rdev) {
closedir(dfd);
if ((dp = strdup(device)) == NULL) {
syslog(LOG_ERR, "%m");
exit(1);
}
return (dp);
}
}
closedir(dfd);
syslog(LOG_ERR, "can't find device %d/%d", major(dev), minor(dev));
exit(1);
}
main()
{
find_dev(0, S_IFCHR);
}
This is what ktruss shows (stripped to relevant part):
17941 1 a.out write(0x1, 0xbb904000, 0x15) = 21
"/dev/console console\n"
17941 1 a.out __lstat30("/dev/..", 0xbfbfe80c) = 0
17941 1 a.out write(0x1, 0xbb904000, 0x1d) = 29
"/dev/console console 20622 0\n"
This is what kdump shows:
13619 1 a.out CALL write(1,0xbb904000,0x15)
13619 1 a.out GIO fd 1 wrote 21 bytes
"/dev/console console\n"
13619 1 a.out RET write 21/0x15
13619 1 a.out CALL __lstat30(0xbfbfe40b,0xbfbfe80c)
13619 1 a.out NAMI "/dev/console"
13619 1 a.out RET __lstat30 0
13619 1 a.out CALL write(1,0xbb904000,0x1d)
13619 1 a.out GIO fd 1 wrote 29 bytes
"/dev/console console 20622 0\n"
13619 1 a.out RET write 29/0x1d
13619 1 a.out CALL close(3)
13619 1 a.out RET close 0
13619 1 a.out CALL exit(0xbb901040)
The "/dev/.." is the path used by the previous __lstat30() call.
I can repeat this on -current/i386 and -current/amd64.
netbsd-4 is fine.
>How-To-Repeat:
Trace lstat() call.
>Fix:
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index