当你 Debug 一门过气语言生成的代码里面产生的 memory leak 时会发生什么 (a.k.a. 不要修改 vala 返回的 strv 的 length)

(会被写成 blog 发出来。)

直接上一段代码。

var array = elements.to_array ();
array.length = -1;
return "(" + string.joinv (" ", array) + ")";

提问,这段代码有什么问题?

它会生成这样的代码。

_tmp32_ = gee_collection_to_array ((GeeCollection*) _tmp30_, &_tmp31_);
array = _tmp32_;
array_length1 = _tmp31_;
_array_size_ = array_length1;
array_length1 = -1;
_tmp33_ = array_length1;
_tmp34_ = array;
_tmp34__length1 = array_length1;
_tmp35_ = _vala_g_strjoinv (" ", _tmp34_, _tmp34__length1);
_tmp36_ = _tmp35_;
_tmp37_ = g_strconcat ("(", _tmp36_, NULL);
_tmp38_ = _tmp37_;
_tmp39_ = g_strconcat (_tmp38_, ")", NULL);
_tmp40_ = _tmp39_;
_g_free0 (_tmp38_);
_g_free0 (_tmp36_);
result = _tmp40_;
array = (_vala_array_free (array, array_length1, (GDestroyNotify) g_free), NULL);
_g_object_unref0 (elements);
_g_free0 (_base);
_g_free0 (_tmp0_);
return result;

那么你再猜猜?给你点提示。

static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
    if ((array != NULL) && (destroy_func != NULL)) {
        int i;
        for (i = 0; i < array_length; i = i + 1) {
            if (((gpointer*) array)[i] != NULL) {
                destroy_func (((gpointer*) array)[i]);
            }
        }
    }
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
    _vala_array_destroy (array, array_length, destroy_func);
    g_free (array);
}

´_>` strv 是一个不能改变大小的 array ……那么你改了它的大小……free 它的函数没法正常工作……然后就会造成 leak ……

Posted in Linux | Tagged , | 1 Comment

最近踩的一个关于 std::unique_ptr 的小坑。

简单来说就是这样一件事,std::unique_ptr 在析构途中调用了 .get() 会发生什么这样一个问题。

当然,你是不应该写出这样的代码的……但是有时候这样的行为可能并不是非常明显。所以就会导致问题…

一个 FreeBSD 上的人汇报了在 Linux 上没有的 crash。估计是 libc++ 和 libstdc++ 的行为差别。一个在析构途中就返回 null 了,一个还是返回原始的指针。

总之,小心避免写出这样的代码吧。

Posted in Linux | Tagged , | Leave a comment

Road to Fcitx 5: 4. Compatibility for different im modules.

I have been always care about the compatibility. Fcitx 5 will be able to type with either fcitx 4’s im module, or fcitx 5’s im module.

Fcitx 5’s im module will announce itself to accept both “fcitx5” and “fcitx”. Even if you did it wrong or forget to upgrade, application will still be able to pick up one of the fcitx im module. Even if it is the wrong one, the latest fcitx 4 im module is compatible with fcitx 5 server. There is no more excuse if you configure it wrong.

Even today, I just commit the code to even support ibus im module. So, when you start fcitx 5, it will automatically replace any existing ibus and initiate a shim dbus layer to provide ibus input context interface. So even your system is wrongly configured or forced by your desktop to use ibus im module, you should still be able to use fcitx anyway, as long as you didn’t forget to start it

.

Posted in fcitx development | Tagged , | Leave a comment

A case study: how to compile a Fcitx platforminputcontext plugin for a proprietary software that uses Qt 5

Due to the fact, that Qt 5 does not support XIM, the only way to type with fcitx under Qt is to use platforminputcontext plugin. The problem is that for some proprietary software like mathematica, it is impossible to use the system Qt plugin because the Qt version does not match (also the library path may not be correct).

If the proprietary software uses shared library version of Qt, it is still possible to get a special version of platforminputcontext plugin compiled. Though, they may have private modification on the Qt library, but it is highly likely the plugin interface is not changed so we can compile it with official Qt 5 source code but link to the private shared Qt library in the proprietary software. So here’s how I did it for mathematica.

First, you need to figure out which version of Qt that the software is using, this can be done easily by using some very hacky tool like strings / objdump since Qt encode it’s compilation info in Qt5Core library in string literals.

$ strings /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 | grep "Qt 5"
Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
This is the QtCore library version Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
If that is not possible, in Qt 5 you must at least reimplement

Now we know it’s Qt 5.6.2. Then we can go to Qt’s offical site to download a official version of Qt 5.6.2. http://download.qt.io/official_releases/qt/5.6/5.6.2/ You can just use the QtCreator bundled with in it so it’ll be much easier to get compilation argument right.

Then, use QtCreator and choose import project from Git, https://github.com/fcitx/fcitx-qt5/ , and select the Qt that comes with your installation, instead of your system Qt 5. I managed to make fcitx-qt5 plugin standalone recently, so it will be really easy to get it compiled.

But remember, we need to link it against the mathematica’s Qt, instead of the Qt binary that we just installed.  The problem is, Qt relies on qmake to find the library path, and it is hard to make it find the mathematica’s Qt. In order to solve this problem, we can directly hack the final link command line generated by cmake.

First, cd to the right path. fcitx-qt5’s plugin does not rely on fcitx-qt5’s library any more, so it is possible to only compile and copy the plugin library. If you already compiled it with QtCreator, you need to run make clean first. So here’s what it looks like:

# Locate the build-fcitx-qt5-Desktop_Qt_5_6_2_GCC_64bit-Default directory.
cd platforminputcontext/
make clean
make VERBOSE=1

Pay attention to the last command, it may looks like this:

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o -Wl,-rpath,/home/saber/Develop/build/Qt560/5.6/gcc_64/lib: /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Gui.so.5.6.2 /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5DBus.so.5.6.2 /usr/lib/libxkbcommon.so /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Core.so.5.6.2

You’ll need to replace the Qt library with the one comes with mathematica.

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5DBusWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5GuiWRI.so.5 /usr/lib/libxkbcommon.so

Also remember to remove the rpath option from it. If the command finishes successfully, now you’ll get an usable fcitx plugin for mathematica. Then just copy it to the right directory:

sudo cp libfcitxplatforminputcontextplugin.so /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/Qt-Plugins/platforminputcontexts/

Then you can enjoy typing with fcitx in mathematica.

The directory path above need to be adjusted based on your own system.

Posted in fcitx development | Tagged , , | 1 Comment

The Road to Fcitx 5: 3. You can (NOT) type on wayland (properly).

With a few recent changes on Fcitx 5, Fcitx can now be used to type on Wayland. (Even the window is rendered with EGL! .. ok this is not important)

And as of today, I’d say it is the first and only input method that can display UI correctly on a XWayland setup theoretically, although it’s still pretty useless (See my old post about wayland’s input method).

I used to have a branch on fcitx 4 to support this protocol, but, due to the architecture we can’t render UI on different display easily, so I gave it up and moved this work to Fcitx 5.

As described before, Xwayland client still uses XIM, while Wayland input method protocol need to use Wayland to display GUI. Now, Fcitx can render both X and Wayland input window in order to solve such problem. And to my own knowledge it is also the first one and the only one that can do this correctly.

Here’s a small video to demonstrate this feature. Though, it comes with some limitation, because only in classicui we render window ourselves. Also I have no idea about weston’s overlay input method window placement. I’d say the positioning issue is a bug in weston because fcitx can’t do any placement on wayland.

But, don’t get too excited, as described before, this is the only client app that uses this protocol and as you can see from video the application’s implementation has some problem with backspace (backspace should be send to input method first). Also when your application loses focus, the input context is destroyed which makes it impossible to keep track of the input state in the same application. (Also that silly wobbly animation is done by weston..)

Unfortunately, this is the best we can get for now.

Posted in fcitx development | Tagged , , , , , | Leave a comment