XCB error: 148 - Qt application display issues

JLev picture JLev · Jul 17, 2017 · Viewed 9.9k times · Source

I'm trying to run my Qt application on a different computer (it works perfectly on mine, where I developed it). When I start this application through the terminal, I get this error -

QXcbConnection: XCB error: 148 (Unknown), sequence: 175, resource id: 0, major code: 140 (Unknown), minor code: 20

My program does launch and everything looks ok, but when I run it I see strange behavior when interacting with the display (some paint commands are not being executed, which is crucial for my app).

I've tried searching for this error and I can't find any solution so far. Do you have any suggestions?

Using ubuntu 16.04, with Nvidia 1050 GTX gpu

Answer

Uddhav Gautam picture Uddhav Gautam · Jul 27, 2017

You developed graphics related app. Your app is functionally dependent in your xorg.conf (X server configuration file). X server is your display windows, which is based on your display graphics hardware.

When you tried to run in the different computer the same app, it wants to read the same configuration that you had on your old computer. Since every computer has xorg.conf file located in /etc/x11/xorg.conf. There is on the new computer, the computer can read information from the xorg.conf, but it can't read all the information. That's why it is partially working.

Your graphics card enhances your X server. So, the configuration keeps adding on your xorg.conf based on you install the graphics driver. But, the computer without graphics card also has xorg.conf for its display.

There is FSM for X server connection (Finite State Machine) below. In your case, there is _xcb_out happening -- because it is displaying something. But, the proper _xcb_in (XCB Input) or _xcb_ext (XCB Extension) is not correct.

I can't exactly tell, which is causing this error. But, FSM is advanced machine, based on different context different ways it takes. They search the channels of configurations files to complete the XCB connection setup. In your case XCB connection has error, so XCB setup can't happen.

enter image description here

In every X server display, at the first, there need to complete X server connection and after that further processing occurs.

Look at the code below from the Wikipedia: https://en.wikipedia.org/wiki/XCB

#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  xcb_connection_t    *c; /* connection character */
  xcb_screen_t        *s;
  xcb_window_t         w;
  xcb_gcontext_t       g;
  xcb_generic_event_t *e;
  uint32_t             mask;
  uint32_t             values[2];
  int                  done = 0;
  xcb_rectangle_t      r = { 20, 20, 60, 60 };

                        /* open connection with the server */
  c = xcb_connect(NULL,NULL);
  if (xcb_connection_has_error(c)) {
    printf("Cannot open display\n");
    exit(1); /* you returned from here, no further processing */
  }
                        /* get the first screen */
  s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;

                       /* create black graphics context */
  g = xcb_generate_id(c);
  w = s->root;
  mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
  values[0] = s->black_pixel;
  values[1] = 0;
  xcb_create_gc(c, g, w, mask, values);

                       /* create window */
  w = xcb_generate_id(c);
  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  values[0] = s->white_pixel;
  values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
  xcb_create_window(c, s->root_depth, w, s->root,
                    10, 10, 100, 100, 1,
                    XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
                    mask, values);

                        /* map (show) the window */
  xcb_map_window(c, w);

  xcb_flush(c);

                        /* event loop */
  while (!done && (e = xcb_wait_for_event(c))) {
    switch (e->response_type & ~0x80) {
    case XCB_EXPOSE:    /* draw or redraw the window */
      xcb_poly_fill_rectangle(c, w, g,  1, &r);
      xcb_flush(c);
      break;
    case XCB_KEY_PRESS:  /* exit on key press */
      done = 1;
      break;
    }
    free(e);
  }
                        /* close connection to server */
  xcb_disconnect(c);

  return 0;
}

Here is the link that you can research more: https://xcb.freedesktop.org/tutorial/

So, what is the solution here? QT, by default, uses the dynamic linking while compiling. If you use static linking then, the executable package holds all libraries necessary to run, and thus, anywhere, you want to run you can run. So, in your old machine, compile using static linking. It produces something packages like tar. You have to install that tar into your different computer. It should run.

QT, by default, uses dynamic linking: Does Qt creator by default statically or dynamically link it's libraries?

How you can change QT to static linking: How to make Qt and Qtcreator link the libraries statically instead of dynamic?