Skip to content

Commit

Permalink
Add ALSA ioctls PVERSION and CARD_INFO to record_syscall
Browse files Browse the repository at this point in the history
VMware Workstation needs to query ALSA for information about
the system's audio devices to allow users to select which device
to direct VM audio output to. When running rr against Workstation,
I found rr asserting around ioctls SNDRV_CTL_IOCTL_PVERSION and
SNDRV_CTL_IOCTL_CARD_INFO.

This patch is my total wild guess on how to patch around this
problem. It's enough to launch Workstation and have it running
under rr, but I cannot attest to its correctness.
  • Loading branch information
Andrew Walton authored and rocallahan committed Nov 7, 2015
1 parent cc8b23c commit 89374ab
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ set(BASIC_TESTS
accept
alarm
alarm2
alsa_ioctl
arch_prctl
async_segv_ignored
async_signal_syscalls2
Expand Down
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Copyright (c) 2013 Mozilla Foundation
Copyright 2015 VMware, Inc

Contributors: Albert Noll <noll.albert@gmail.com>, Thomas Anderegg <thomas@tanderegg.com>, Nimrod Partush <nimrodpar@gmail.com>
Andrew Walton <awalton@vmware.com>

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
Expand Down
14 changes: 14 additions & 0 deletions src/kernel_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <sound/asound.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/quota.h>
Expand Down Expand Up @@ -1166,6 +1167,19 @@ struct BaseArch : public wordsize, public FcntlConstants {
ptr<robust_list> list_op_pending;
};
RR_VERIFY_TYPE(robust_list_head);

struct snd_ctl_card_info {
int card;
int pad;
unsigned char id[16];
unsigned char driver[16];
unsigned char name[32];
unsigned char longname[80];
unsigned char reserved_[16];
unsigned char mixername[80];
unsigned char components[128];
};
RR_VERIFY_TYPE(snd_ctl_card_info);
};

struct X86Arch : public BaseArch<SupportedArch::x86, WordSize32Defs> {
Expand Down
9 changes: 9 additions & 0 deletions src/record_syscall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/msdos_fs.h>
#include <poll.h>
#include <sched.h>
#include <sound/asound.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
Expand Down Expand Up @@ -1180,6 +1181,14 @@ static Switchable prepare_ioctl(Task* t, TaskSyscallState& syscall_state) {
case TIOCGWINSZ:
syscall_state.reg_parameter<typename Arch::winsize>(3);
return PREVENT_SWITCH;

case SNDRV_CTL_IOCTL_PVERSION:
syscall_state.reg_parameter<int>(3);
return PREVENT_SWITCH;

case SNDRV_CTL_IOCTL_CARD_INFO:
syscall_state.reg_parameter<typename Arch::snd_ctl_card_info>(3);
return PREVENT_SWITCH;
}

/* In ioctl language, "_IOC_READ" means "outparam". Both
Expand Down
32 changes: 32 additions & 0 deletions src/test/alsa_ioctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#include "rrutil.h"

#ifndef ALSA_DEVICE_DIRECTORY
#define ALSA_DEVICE_DIRECTORY "/dev/snd/"
#endif

int main(int argc, char* argv[]) {
int fd = open(ALSA_DEVICE_DIRECTORY "control0", O_NONBLOCK | O_RDONLY);
if (fd < 0) {
test_assert(errno == EACCES || errno == ENOENT);
} else {
int* pversion;
struct snd_ctl_card_info* info;

ALLOCATE_GUARD(pversion, 'x');
*pversion = -1;
test_assert(0 == ioctl(fd, SNDRV_CTL_IOCTL_PVERSION, pversion));
VERIFY_GUARD(pversion);
test_assert(pversion >= 0);

ALLOCATE_GUARD(info, 1);
test_assert(0 == ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, info));
VERIFY_GUARD(info);
test_assert(info->id[0] > 1);
test_assert(info->driver[0] > 1);
}

atomic_puts("EXIT-SUCCESS");
return 0;
}
1 change: 1 addition & 0 deletions src/test/rrutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <pty.h>
#include <sched.h>
#include <signal.h>
#include <sound/asound.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
Expand Down

0 comments on commit 89374ab

Please sign in to comment.