NvRmStream: Illegal stream pointer (err=4); NvHost_NvRmHost1xSyncpointDetachChannel: ioctl failed

Hello Forum,

I am daemonizing (for being started/stopped via systemd) a recording program making use of Argus Library’s APIs with

void daemonize(bool runBackground = false) {
    if (!runBackground)
        return; // skip if running interactively

    pid_t sid, pid = fork();
    if (pid < 0)
        exit(EXIT_FAILURE);
    if (pid > 0)
        exit(EXIT_SUCCESS); // parent exits

    if (setsid() < 0)
        exit(EXIT_FAILURE);

    // Since the child process is a daemon, the umask needs to be set so files and logs can be written
    umask(0);

    // Open system logs for the child process
    openlog("cam_record", LOG_NOWAIT | LOG_PID, LOG_USER);
    syslog(LOG_NOTICE, "Successfully started cam_record");

    // Generate a session ID for the child process
    sid = setsid();
    // Ensure a valid SID for the child process
    if(sid < 0)
    {
       // Log failure and exit
       syslog(LOG_ERR, "Could not generate session ID for child process");

       // If a new session ID could not be generated, we must terminate the child process
       // or it will be orphaned
       exit(EXIT_FAILURE);
    }

    // Change working directory to root
    if (chdir("./") < 0) {
        // Log failure and exit
        syslog(LOG_ERR, "Could not change working directory to ./");

        // If our guaranteed directory does not exist, terminate the child process to ensure
        // the daemon has not been hijacked
        exit(EXIT_FAILURE);
    }

    // Redirect standard file descriptors
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
}

int main(int argc, char const * argv[]) {

    Config conf = parseOptions(argc, argv);                 ///< user's configuration

    // --- Optional: start as daemon if not running in interactive mode ---
    bool daemonized = conf.daemonized;
    daemonize(daemonized); // false → stay foreground, true → daemonized

    // --- Setup signal handling ---
    signal(SIGTERM, handleSignal);
    signal(SIGINT, handleSignal);

but I got following error :

NvRmStream: Illegal stream pointer (err=4)
NvHost_NvRmHost1xSyncpointDetachChannel: ioctl failed

In foreground console mode, the program works well however.

Do you know what could be the missing configuration/setting, please ?

Thanks and best regards,
Khang

hello khang.l4es,

did you meant it’s okay to do recording with gst pipeline?
for instance,
here’s sample pipeline to enable preview stream and also video recording.
$ gst-launch-1.0 nvarguscamerasrc num-buffers=300 ! 'video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1' ! tee name=streams streams. ! queue ! nvv4l2h265enc bitrate=8000000 ! h265parse ! qtmux ! filesink location=h265.mp4 streams. ! queue ! nvvidconv ! xvimagesink -e

Hi @JerryChang ,

We cannot use gstreamer pipeline. We use Argus APIs to capture frames inspiring the following example : GitHub - stereolabs/zedx-one-capture: Camera control API for ZED X One GMSL2 cameras from Stereolabs

By okay I meant it was okay for running the same code without daemonization (that I shared above). It looks like the issue happens with calling fork() / setsid().

hello khang.l4es,

Argus support multi-session mode to capture several cameras simultaneously,
please see-also 13_argus_multi_camera for reference.

Hi @JerryChang ,

Firstly, capturing several cameras within multi-session is NOT our intention. We are using single-session for multiple (dual) cameras as we want the software/ISP synchronization alongside with the hardware synchronization (external triggering).

Secondly, we have been able to capture multiple (dual) cameras in single session by running our application in foreground (command-line in an active console). However, there appeared the error messages as in the title of the topic when we turned the application into a daemon.

hello khang.l4es,

it’s Argus/public/samples/syncSensor to have single-session for dual cameras.
as you can see.. it’s creates two capture session instead of using fork().

Hi @JerryChang ,

it’s Argus/public/samples/syncSensor

I did the similar as syncStereo example for your information.

it’s creates two capture session instead of using fork().

There must be some misunderstanding about using fork() here: it does not for creating multiple capture sessions for multiple cameras, it is part of the daemonization for purpose of “forcing“ the program running in background (as a daemon, similar to argus-daemon) so that I can avoid opening a console terminal to execute it and I can start/stop it via systemd service.

hello khang.l4es,

it’s running at background by default, you may follow below to restart Argus daemon.
$ sudo pkill nvargus-daemon
$ sudo systemctl start nvargus-daemon

Hi @JerryChang ,

I know that nvargus-daemon already running in background. I meant for my own program having problem when being forced running in background.

hello khang.l4es,

err=4 means NvError_BadParameter, you may double check it’s correct stream handler
besides.. it looks NvRm internally called getpid() to set current PID as a stream marker.

you may also check the permission to access the camera hardware and other required resources.
or.. the environment variables for the process.

Hi @JerryChang ,

We just came up with idea to run the program in background within a tmux session to avoid the aforementioned issue.