From: Gregor Jasny <jasny@vidsoft.de>
To: Hans de Goede <j.w.r.degoede@hhs.nl>
Cc: video4linux-list@redhat.com,
v4l2 library <v4l2-library@linuxtv.org>,
SPCA50x Linux Device Driver Development
<spca50x-devs@lists.sourceforge.net>
Subject: Messed up syscall return value
Date: Mon, 28 Jul 2008 23:49:27 +0200 [thread overview]
Message-ID: <20080728214927.GA21280@vidsoft.de> (raw)
In-Reply-To: <488721F2.5000509@hhs.nl>
[-- Attachment #1: Type: text/plain, Size: 5514 bytes --]
Hi,
I've observed strange behavior in the REQBUFS ioctl for the non-emulated
case. To reproduce:
* Use a amd64 system (Debian Sid if it matters)
* Linux 2.6.26
* load vivi driver to video0
* Compile attached program w/o libv4l2 and check that it runs fine.
* Compile attached program with libv4l2 and see it fail during REQBUFS
ioctl.
I've debugged the problem to the line:
result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, req);
Here the value 2 get stored into result, although the kernel driver
returned success (at least it does not complain loudly in the logs).
When stepping assembly instructions the rax value is zero, shortly after
it is set to two. Personally I suspect a messed up stack. Both
v4l2_ioctl and syscall are variable argument functions.
Thanks,
Gregor
Kernel log for pure V4L2;
Jul 28 23:20:09 Rincewind kernel: vivi: open called (minor=0)
Jul 28 23:20:09 Rincewind kernel: vivi: open minor=0 type=video-cap users=1
Jul 28 23:20:09 Rincewind kernel: vivi: vivi_start_thread
Jul 28 23:20:09 Rincewind kernel: vivi: returning from vivi_start_thread
Jul 28 23:20:09 Rincewind kernel: vivi: thread started
Jul 28 23:20:09 Rincewind kernel: vivi: vivi_sleep dma_q=0xffff81005c480640
Jul 28 23:20:09 Rincewind kernel: vivi: Thread tick
Jul 28 23:20:09 Rincewind kernel: vivi: No active queue to serve
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_S_FMT
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_REQBUFS
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_setup, count=2, size=202752
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_QUERYBUF
Jul 28 23:20:09 Rincewind kernel: vivi: mmap called, vma=0xffff810068086690
Jul 28 23:20:09 Rincewind kernel: vivi: vma start=0x7f8734c0a000, size=204800, ret=0
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_QUERYBUF
Jul 28 23:20:09 Rincewind kernel: vivi: mmap called, vma=0xffff8100680863f0
Jul 28 23:20:09 Rincewind kernel: vivi: vma start=0x7f8734bd8000, size=204800, ret=0
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_QBUF
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_prepare, field=4
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_QBUF
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_prepare, field=4
Jul 28 23:20:09 Rincewind kernel: vivi (0): VIDIOC_STREAMON
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_queue
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_queue
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_release
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer, state: 5
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_release
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer, state: 5
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:20:09 Rincewind kernel: vivi: vivi_stop_thread
Jul 28 23:20:09 Rincewind kernel: vivi: thread: exit
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_release
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer, state: 0
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:20:09 Rincewind kernel: vivi: buffer_release
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer, state: 0
Jul 28 23:20:09 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:20:09 Rincewind kernel: vivi: close called (minor=0, users=0)
Kernel Log for libv4l2 case:
Jul 28 23:21:03 Rincewind kernel: vivi: open called (minor=0)
Jul 28 23:21:03 Rincewind kernel: vivi: open minor=0 type=video-cap users=1
Jul 28 23:21:03 Rincewind kernel: vivi: vivi_start_thread
Jul 28 23:21:03 Rincewind kernel: vivi: returning from vivi_start_thread
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_QUERYCAP
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_G_FMT
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_ENUM_FMT
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_ENUM_FMT
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_TRY_FMT
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_S_FMT
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_REQBUFS
Jul 28 23:21:03 Rincewind kernel: vivi: thread started
Jul 28 23:21:03 Rincewind kernel: vivi: buffer_setup, count=2, size=202752
Jul 28 23:21:03 Rincewind kernel: vivi: vivi_sleep dma_q=0xffff81005c480640
Jul 28 23:21:03 Rincewind kernel: vivi: Thread tick
Jul 28 23:21:03 Rincewind kernel: vivi: No active queue to serve
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_QUERYBUF
Jul 28 23:21:03 Rincewind kernel: vivi: mmap called, vma=0xffff81007ab7ea80
Jul 28 23:21:03 Rincewind kernel: vivi: vma start=0x7f29aa02f000, size=204800, ret=0
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_QUERYBUF
Jul 28 23:21:03 Rincewind kernel: vivi: mmap called, vma=0xffff810070e260a8
Jul 28 23:21:03 Rincewind kernel: vivi: vma start=0x7f29a9ffd000, size=204800, ret=0
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_QBUF
Jul 28 23:21:03 Rincewind kernel: vivi: buffer_prepare, field=4
Jul 28 23:21:03 Rincewind kernel: vivi (0): VIDIOC_QBUF
Jul 28 23:21:03 Rincewind kernel: vivi: buffer_prepare, field=4
Jul 28 23:21:03 Rincewind kernel: vivi: vivi_stop_thread
Jul 28 23:21:03 Rincewind kernel: vivi: thread: exit
Jul 28 23:21:03 Rincewind kernel: vivi: buffer_release
Jul 28 23:21:03 Rincewind kernel: vivi: free_buffer, state: 1
Jul 28 23:21:03 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:21:03 Rincewind kernel: vivi: buffer_release
Jul 28 23:21:03 Rincewind kernel: vivi: free_buffer, state: 1
Jul 28 23:21:03 Rincewind kernel: vivi: free_buffer: freed
Jul 28 23:21:03 Rincewind kernel: vivi: close called (minor=0, users=0)
[-- Attachment #2: reqbufs.c --]
[-- Type: text/x-csrc, Size: 3765 bytes --]
// gcc -std=gnu99 -ggdb -L /home/gjasny/src/libv4l-0.3.7/libv4l2 -L /home/gjasny/src/libv4l-0.3.7/libv4lconvert -I/home/gjasny/src/libv4l-0.3.7/include -lv4l2 -lv4lconvert -o reqbufs reqbufs.c
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/ioctl.h>
#include <linux/videodev2.h>
#if 1
# include <libv4l2.h>
# define my_ioctl v4l2_ioctl
# define my_open v4l2_open
# define my_close v4l2_close
# define my_mmap v4l2_mmap
#else
# define my_ioctl ioctl
# define my_open open
# define my_close close
# define my_mmap mmap
#endif
#define NBUFFERS 2
#define WIDTH 352
#define HEIGHT 288
struct buffer {
void *start;
size_t length;
} g_buffers[NBUFFERS];
static int xioctl( int fd, unsigned long int request, void *arg )
{
int r;
do r = my_ioctl (fd, request, arg);
while (r == -1 && errno == EINTR);
return r;
}
int main(int argc, char *argv[])
{
const char *device = "/dev/video0";
int fd = my_open (device, O_RDWR);
if (!fd) {
perror ("open");
return -1;
}
struct v4l2_format format;
memset( &format, 0, sizeof(struct v4l2_format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = WIDTH;
format.fmt.pix.height = HEIGHT;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
format.fmt.pix.field = V4L2_FIELD_ANY;
if (xioctl (fd, VIDIOC_S_FMT, &format) == -1) {
perror("ioctl (VIDIOC_S_FMT)");
return -1;
}
// init mmap
struct v4l2_requestbuffers m_req;
memset( &m_req, 0, sizeof(struct v4l2_requestbuffers) );
m_req.count = NBUFFERS;
m_req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
m_req.memory = V4L2_MEMORY_MMAP;
if (xioctl (fd, VIDIOC_REQBUFS, &m_req) == -1) {
if (EINVAL == errno) {
fprintf (stderr, "device does not support memory mapping.\n");
} else {
perror ("ioctl (VIDIOC_REQBUFS)");
}
return -1;
}
if (m_req.count < NBUFFERS) {
fprintf (stderr, "Insufficient buffer memory.\n");
return -1;
}
for (unsigned i = 0; i < m_req.count; ++i) {
struct v4l2_buffer buf;
memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (xioctl (fd, VIDIOC_QUERYBUF, &buf) == -1) {
perror("ioctl (VIDIOC_QUERYBUF)");
return -1;
}
g_buffers[i].length = buf.length;
g_buffers[i].start = my_mmap (NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (g_buffers[i].start == MAP_FAILED) {
perror("mmap");
return -1;
}
}
for (unsigned i = 0; i < NBUFFERS; ++i) {
struct v4l2_buffer buf;
memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (xioctl (fd, VIDIOC_QBUF, &buf) == -1) {
perror ("ioctl (VIDIOC_QBUF)");
return -1;
}
}
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (xioctl (fd, VIDIOC_STREAMON, &type) == -1) {
perror("ioctl (VIDIOC_STREAMON)");
return -1;
}
my_close (fd);
return -1;
}
[-- Attachment #3: Type: text/plain, Size: 164 bytes --]
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list
next prev parent reply other threads:[~2008-07-28 21:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-23 12:20 Announcing libv4l 0.3.7 Hans de Goede
2008-07-28 21:49 ` Gregor Jasny [this message]
[not found] ` <488E4090.5020600@gmail.com>
2008-07-28 22:16 ` [V4l2-library] Messed up syscall return value Gregor Jasny
[not found] ` <488E46BC.10104@gmail.com>
2008-07-28 22:34 ` Gregor Jasny
2008-07-28 22:35 ` H. Willstrand
2008-07-29 10:00 ` Hans de Goede
2008-07-29 11:52 ` Gregor Jasny
2008-07-29 19:49 ` Hans de Goede
2008-07-29 16:00 ` Mauro Carvalho Chehab
2008-07-29 19:05 ` Laurent Pinchart
2008-07-29 20:51 ` Mauro Carvalho Chehab
2008-07-29 20:57 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080728214927.GA21280@vidsoft.de \
--to=jasny@vidsoft.de \
--cc=j.w.r.degoede@hhs.nl \
--cc=spca50x-devs@lists.sourceforge.net \
--cc=v4l2-library@linuxtv.org \
--cc=video4linux-list@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox