系统环境:ubuntu 11.04 tiny6410: 2.6.38
软件环境:
arm-linux-gcc 4.5.1
问题描述:
为读入音频数据,自己实现了一个缓冲区代码,但包括此代码,当执行read函数时,就会报内存溢出:Segmentation fault,我测试只包含缓冲区代码,不调用任何函数也如此,只有不包括此代码才不会。
并且我写了一个简单的单独程序实现从audio读入数据存入文件中,如果我编译的时候,把缓存区代码的.o文件包括过来,同样到read的时候就会出现Segmentation fault
用GDB进行测试, bt显示以下信息:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1253]
0xfebd2222 in ?? ()
(gdb) bt
#0 0xfebd2222 in ?? ()
#1 0x0008900c in ?? ()
#2 0x0008900c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
小弟才疏学浅,还望各位高手相助。
以下为缓冲区实现的代码 audio_pool.c
同时我将audio_pool.o做附件上传(非rar文件,请直接mv audio_pool.o.rar audio_pool.o),大家可以尝试在自己的项目中链接时包括此文件,执行read会不会导致内存出错。
以下代码为单独的一个程序,从/dev/dsp读入音频数据
#arm-linux-gcc -o read main.c -lpthread //这样的命令编译出来的程序工作正常
#arm-linux-gcc -o read audio_pool.o sound.c -lpthread //这样的命令编译出来的程序就会报内存出错
复制代码- /*
- * * sound.c
- * */
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <linux/soundcard.h>
- #include <pthread.h>
- #define LENGTH 10 /* 存储秒数 */
- #define RATE 8000 /* 采样频率 */
- #define SIZE 16 /* 量化位数 */
- #define CHANNELS 1 /* 声道数目 */
- /* 用于保存数字音频数据的内存缓冲区 */
- extern void * read_audio(void* fd);
- const char * file = "./source.raw";
- unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/8];
- void * read_audio(void * fd)
- {
- int * xx=fd;
- int tt=read(*xx, buf, LENGTH*RATE*SIZE*CHANNELS/8); /* 录音 */
- return(void *) tt;
- }
- int main()
- {
- pthread_t pid;
- int fd; /* 声音设备的文件描述符 */
- int arg; /* 用于ioctl调用的参数 */
- int status; /* 系统调用的返回值 */
- FILE * fp;
- /* 打开声音设备 读写方式*/
- fd = open("/dev/dsp", O_RDWR);
- if (fd < 0)
- {
- perror("open of /dev/dsp failed");
- exit(1);
- }
- if((fp=fopen(file,"w"))==NULL)
- {
- perror("open dest error");
- exit(1);
- }
- /* 设置采样时的量化位数 */
- arg = SIZE;
- status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
- if (status == -1)
- perror("SOUND_PCM_WRITE_BITS ioctl failed");
- if (arg != SIZE)
- perror("unable to set sample size");
- int channels = 0; // 0=mono 1=stereo
- int result = ioctl(fd, SNDCTL_DSP_STEREO, &channels);
- if ( result == -1 ) {
- perror("ioctl channel number");
- return -1;
- }
- if (channels != 0) {
- perror("just double");
- // 只支持立体声
- }
- /* 设置采样时的采样频率 */
- arg = RATE;
- status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
- if (status == -1)
- perror("SOUND_PCM_WRITE_WRITE ioctl failed");
- printf("Say something:\n");
- void * test;
- pthread_create(&pid,NULL,read_audio,(void *)&fd); /* 录音 */
- pthread_join(pid,&test);
- if ((int)test != sizeof(buf))
- perror("read wrong number of bytes");
- fwrite(buf,sizeof(buf),1,fp);
- printf("done");
- fclose(fp);
- return 0;
- #if 0
- printf("You said:\n");
- status = write(fd, buf, sizeof(buf)); /* 回放 */
- if (status != sizeof(buf))
- perror("wrote wrong number of bytes");
- /* 在继续录音前等待回放结束 */
- status = ioctl(fd, SOUND_PCM_SYNC, 1);
- if (status == -1)
- perror("SOUND_PCM_SYNC ioctl failed");
- #endif
- }
|