LINUX.ORG.RU

немогу запустить Xvfb через fork + execl

 , ,


0

2

сама ошибка от Xvfb

XKB: Failed to compile keymap
Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
(EE) 
Fatal server error:
(EE) Failed to activate virtual core keyboard: 2(EE) 

через консоль просто командой запускается нормально без ошибок

/usr/bin/Xvfb :99 -nolisten tcp -screen 0 1024x768x24

через код с ошибкой, вот код

/* g++ -Wall -otest test.cpp -std=c++14 */

#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <sys/wait.h>

#include <chrono>
#include <thread>
#include <atomic>
#include <cstdlib>
#include <iostream>

std::atomic<bool> running;

void signal_handler(int sig)
{
    syslog(LOG_DEBUG, "signal receive: %d", sig);
    
    if(sig == SIGTERM || sig == SIGINT)
        running = false;
}

int main(int argc, char** argv)
{
    openlog("test_case", LOG_PERROR, LOG_USER);

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGCHLD, SIG_IGN);
    signal(SIGHUP, SIG_IGN);

    int pid = fork();
    if(0 > pid)
    {
        syslog(LOG_ERR, "fork failed");
        return -1;
    }
    
    if(0 == pid)
    {
        syslog(LOG_DEBUG, "child zone");
        signal(SIGTERM, SIG_DFL);
        signal(SIGINT, SIG_IGN);
        signal(SIGHUP, SIG_IGN);
        signal(SIGCHLD, SIG_IGN);

        int res = execl("/usr/bin/Xvfb", "Xvfb", ":99", "-nolisten", "tcp", "-screen", "0", "1024x768x24", (char*) NULL);

        if(res < 0)
            syslog(LOG_ERR, "execl failed: %s", strerror(errno));

        _exit(0);
    }

    syslog(LOG_DEBUG, "main running");

    running = true;
    using namespace std::chrono_literals;

    while(running)
        std::this_thread::sleep_for(100ms);

    closelog();
    return 0;
}

selinux выключен, любые идеи... и кто и что там еще может какие лимиты срабатывать?

Запусти под ktrace (или как оно в линуксе называется, systrace, truss?) да посмотри что он пытается сделать. Навскидку, с execl у тебя разница в argv[0] относительно ручного запуска.

slovazap ★★★★★ ()

Возможно, отличаются переменные окружения при разных способах запуска. Особенно стоит обратить внимание на PATH - Xvfb может какую-то другую программу (xkbcomp, например) запускать, и ожидать наличие этой программы в $PATH.

Это легко проверить с помощью strace -f -e execve -v ./test.

kmeaw ★★★ ()
Ответ на: комментарий от kmeaw

не помогло, все переменные среды там копируются автоматом из сеанса. там все как то похитрее, через strace видно еще дополнительно стартует

/usr/bin/xkbcomp -w 1 -R/usr/share/X11/xkb -xkm -  -em1 "The XKEYBOARD keymap compiler (xkbcomp) reports:" -emp "> " -eml "Errors from xkbcomp are not fatal to the X server"  /tmp/server-99.xkm

потом он получает входной stdin

xkb_keymap "default" {
    xkb_keycodes             { include "evdev+aliases(qwerty)" };
    xkb_types                { include "complete" };
    xkb_compatibility        { include "complete" };
    xkb_symbols              { include "pc+us+inet(evdev)" };
    xkb_geometry             { include "pc(pc105)" };
};

и что то на этом этапе у меня ломается….

anonymous2 ★★★★★ ()
Последнее исправление: anonymous2 (всего исправлений: 3)
Ответ на: комментарий от anonymous2

argv[0] это не для «отображения в процессах», argv[0] это argv[0]. Если он относительно пути из argv[0] вызывает другие бинарники, то вот тебе вариант почему поведение разное.

slovazap ★★★★★ ()
Ответ на: комментарий от anonymous2

через strace видно

Попробуй «ltrace -S -n2 ...»

ABW ★★★★★ ()
Ответ на: комментарий от slovazap

это ничего не изменило, пути везде абсолютные, Xvfb запускает xkbcomp 100%, я даже менял его на скрипт.

С этими параметрами (argv и stdin), которые он получает от Xfvb, отдельно через консоль генерирует /tmp/server-99.xkm без ошибок (ну еще бы в продакшне оно не работало).

но через execl + Xfvb + xkbcomp он валится с ошибкой… только не говорите что у вас все работает, я на двух системах разных проверил

anonymous2 ★★★★★ ()
Последнее исправление: anonymous2 (всего исправлений: 1)
Ответ на: комментарий от anonymous2

Без SIGCHILD цепочки как бы не будет. Он используется для ожидания завершения процесса и если игнорируется, то тот же system() будет возвращать -1.

xaizek ★★★★★ ()
Ответ на: комментарий от anonymous2

Не знаю, может там у оболочки другое поведение или libc инициализирует процесс иначе.

xaizek ★★★★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.