1

I downloaded the ALSA sample source codes (https://gist.github.com/ghedo/963382) and test running under putty window, it works. However when put into the startup script (eg. rc.local) with or without "sudo", it crashed.

Note: The application only crashes after auto-run from power on; if run the script in putty (command line), no problem.

After added logging before each snd_xxx function calls, found the application stop after call snd_pcm_hw_params_any, meaning it crashes after snd_pcm_open and snd_pcm_hw_params_alloca. Following is code:

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_open"); /////logged 
    if ((pcm = snd_pcm_open(&pcm_handle, acDev, /////PCM_DEVICE, acDev="default:0"
                    SND_PCM_STREAM_PLAYBACK, 0)) < 0)
    {
        sprintf(acLog, "[audio]Can't open \"%s\" PCM device. %s\n", acDev, snd_strerror(pcm));
        g_pLog->LogInfo(LOG_SYS, acLog);
        return -1;
    }


    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_alloca");  /////logged
    /* Allocate parameters object and fill it with default values*/
    snd_pcm_hw_params_alloca(&params);

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_any");  /////logged and is the last line
    snd_pcm_hw_params_any(pcm_handle, params);

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_set_access");
    /* Set parameters */
    if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,
                    SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
...

After collect the core dump file and use gdb "bt full" to check, the result is:

root@linaro-ubuntu-desktop:/test# gdb ./AudioPlayer /opt/core.AudioPlayer.6277.1604311455.6
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabi".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /test/AudioPlayer...(no debugging symbols found)...done.
[New LWP 6277]
[Thread debugging using libthread_db enabled]
Core was generated by `/test/AudioPlayer'.
Program terminated with signal 6, Aborted.
#0  0x2ad8bed6 in ?? () from /lib/arm-linux-gnueabi/libc.so.6
(gdb) bt full
#0  0x2ad8bed6 in ?? () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#1  0x2ad9a0da in raise () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#2  0x2ad9c506 in abort () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#3  0x2ad951ec in __assert_fail () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#4  0x2ac6cb72 in snd_pcm_hw_refine () from /usr/lib/arm-linux-gnueabi/libasound.so.2
No symbol table info available.
#5  0x0000aca8 in main ()
No symbol table info available.

Note "snd_pcm_hw_refine" is not called directly from the application.

I am wondering what the difference is between running in putty and running from power-on startup script, and how to solve this failure. Appreciate if you can advise...

4

1 回答 1

0

调用snd_pcm_open()open 失败。然后错误代码检查失败,因为pcm未签名。snd_pcm_hw_params_any()然后崩溃,因为pcm_handle它是 NULL。

该代码中还有许多其他错误。忘掉它。使用这样的东西:

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

static void alsa_check(int result, const char *call)
{
    if (result < 0) {
        fprintf(stderr, "%s failed: %s\n", call, snd_strerror(result));
        exit(1);
    }
}
#define CHECK(f) alsa_check(f, #f)

static void play(snd_pcm_t *pcm, int frame_size)
{
#define FRAMES 50000
    void *buf, *data;
    int frames, rest;

    buf = malloc(FRAMES * frame_size);
    for (;;) {
        frames = fread(buf, frame_size, FRAMES, stdin);
        if (frames <= 0)
            break;
        rest = frames;
        data = buf;
        while (rest > 0) {
            frames = snd_pcm_writei(pcm, data, rest);
            if (frames < 0)
                CHECK(snd_pcm_recover(pcm, frames, 0));
            else {
                rest -= frames;
                data += frames * frame_size;
            }
        }
    }
    free(buf);
}

int main(int argc, char *argv[])
{
    const char *device = "default";
    snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
    snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED;
    unsigned int channels, rate;
    unsigned int latency = 500000; /* 0.5 s */
    snd_pcm_t *pcm;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s rate channels < inputfile\n", argv[0]);
        return 1;
    }
    rate = atoi(argv[1]);
    channels = atoi(argv[2]);

    CHECK(snd_pcm_open(&pcm, device, SND_PCM_STREAM_PLAYBACK, 0));

    CHECK(snd_pcm_set_params(pcm, format, access, channels, rate, 1, latency));

    play(pcm, channels * snd_pcm_format_physical_width(format));

    CHECK(snd_pcm_drain(pcm));
    snd_pcm_close(pcm);
    return 0;
}
于 2020-11-02T18:57:03.387 回答