Nikolaus Rath <[email protected]> writes: > Julian Seward <[email protected]> writes: >>> My guess would be that stat64 is not marked as a system call that can >>> block and that it needs the MayBlock flag adding. >> >> Yes, that could be it. I guess, normally, a stat64 (etc) call is >> completed eventually by the kernel, without the need for any other >> thread to run. But in this case a stat64 call might somehow require >> some other thread to progress. >> >> Nikolaus, try adding >> >> *flags |= SfMayBlock; >> >> to PRE(sys_stat64) in syswrap-x86-linux.c (I assume this is >> 32-bit x86). Does that help? > > > No, I'm afraid it's still blocking in the same call.
The devil's in the detail. I had to write a minimal example and observe it mysteriously working before I looked closely enough, but I finally noticed that the call is *l*stat, and not stat. After adding the flag to sys_lstat64 the problem is fixed. Is there any chance of getting the flag added in valgrind by default, or would that hurt performance too much? I'm attaching my minimal example anyway, maybe it's useful for someone at some point. Best, -Nikolaus -- »Time flies like an arrow, fruit flies like a Banana.« PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
/* FUSE: Filesystem in Userspace Copyright (C) 2001-2007 Miklos Szeredi <[email protected]> This program can be distributed under the terms of the GNU GPL. See the file COPYING. Modified by Nikolaus Rath to demonstrate deadlocking when running under Valgrind. gcc -Wall `pkg-config fuse --cflags --libs` fuse.c -o fuse */ #define FUSE_USE_VERSION 26 #include <fuse_lowlevel.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> #include <assert.h> static const char *hello_str = "Hello World!\n"; static const char *hello_name = "hello"; static char *mountpoint; static int hello_stat(fuse_ino_t ino, struct stat *stbuf) { stbuf->st_ino = ino; switch (ino) { case 1: stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; break; case 2: stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_size = strlen(hello_str); break; default: return -1; } return 0; } static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { struct stat stbuf; (void) fi; memset(&stbuf, 0, sizeof(stbuf)); if (hello_stat(ino, &stbuf) == -1) fuse_reply_err(req, ENOENT); else fuse_reply_attr(req, &stbuf, 1.0); } static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { struct fuse_entry_param e; if (parent != 1 || strcmp(name, hello_name) != 0) fuse_reply_err(req, ENOENT); else { memset(&e, 0, sizeof(e)); e.ino = 2; e.attr_timeout = 1.0; e.entry_timeout = 1.0; hello_stat(e.ino, &e.attr); fuse_reply_entry(req, &e); } } struct dirbuf { char *p; size_t size; }; static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name, fuse_ino_t ino) { struct stat stbuf; size_t oldsize = b->size; b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0); b->p = (char *) realloc(b->p, b->size); memset(&stbuf, 0, sizeof(stbuf)); stbuf.st_ino = ino; fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf, b->size); } #define min(x, y) ((x) < (y) ? (x) : (y)) static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize, off_t off, size_t maxsize) { if (off < bufsize) return fuse_reply_buf(req, buf + off, min(bufsize - off, maxsize)); else return fuse_reply_buf(req, NULL, 0); } static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { (void) fi; if (ino != 1) fuse_reply_err(req, ENOTDIR); else { struct dirbuf b; memset(&b, 0, sizeof(b)); dirbuf_add(req, &b, ".", 1); dirbuf_add(req, &b, "..", 1); dirbuf_add(req, &b, hello_name, 2); reply_buf_limited(req, b.p, b.size, off, size); free(b.p); } } void hello_ll_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { fuse_reply_err(req, ENOSYS); } static void hello_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { if (ino != 2) fuse_reply_err(req, EISDIR); else if ((fi->flags & 3) != O_RDONLY) fuse_reply_err(req, EACCES); else fuse_reply_open(req, fi); } static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { (void) fi; assert(ino == 2); reply_buf_limited(req, hello_str, strlen(hello_str), off, size); } static struct fuse_lowlevel_ops hello_ll_oper = { .lookup = hello_ll_lookup, .getattr = hello_ll_getattr, .readdir = hello_ll_readdir, .open = hello_ll_open, .read = hello_ll_read, .opendir = hello_ll_opendir, }; void *StatMountpoint(void *data) { struct stat buf; sleep(5); printf("Calling stat(%s)\n", mountpoint); if (lstat(mountpoint, &buf) != 0) { perror("stat failed"); } pthread_exit(NULL); } void *RunFUSE(void *data) { struct fuse_args *args; struct fuse_chan *ch; struct fuse_session *se; args = (struct fuse_args*) data; if ((ch = fuse_mount(mountpoint, args)) != NULL) { se = fuse_lowlevel_new(args, &hello_ll_oper, sizeof(hello_ll_oper), NULL); if (se != NULL) { if (fuse_set_signal_handlers(se) != -1) { fuse_session_add_chan(se, ch); fuse_session_loop_mt(se); fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); } fuse_session_destroy(se); } fuse_unmount(mountpoint, ch); } pthread_exit(NULL); } int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); int rc; pthread_t thread; if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != 0) { printf("fuse_parse_cmdline failed.\n"); return 1; } rc = pthread_create(&thread, NULL, RunFUSE, (void *)&args); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); return 1; } rc = pthread_create(&thread, NULL, StatMountpoint, NULL); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); return 1; } pthread_exit(NULL); }
------------------------------------------------------------------------------ Gaining the trust of online customers is vital for the success of any company that requires sensitive data to be transmitted over the Web. Learn how to best implement a security strategy that keeps consumers' information secure and instills the confidence they need to proceed with transactions. http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________ Valgrind-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/valgrind-users
