标签:ubuntu

最流行的Linux发行版

ubuntu16.04 修改 pthread 库的 PTHREAD_KEYS_MAX 宏定义

编译说明

  • pthread 是 glibc 的子库,需要编译整个 glibc。
  • 需要安装编译套件 gcc, make 等工具。

编译 glibc

  • 查看 glibc 当前版本
$ /lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.23-0ubuntu9) stable release version 2.23, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 5.4.0 20160609.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
  • 下载 glibc-2.23
apt install axel
axel -n 10 http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.bz2
tar xjf glibc-2.23.tar.bz2
  • 修改 PTHREAD_KEYS_MAX 宏大小
    • 不能改太大,改成 10240 创建线程时会崩溃
    • 仅修改相关 PC 体系下的头文件,如下是修改完的
$ cd /home/share/glibc-2.23
$ ag "define PTHREAD_KEYS_MAX"
glibc-2.23/sysdeps/unix/sysv/linux/aarch64/bits/local_lim.h
65:#define PTHREAD_KEYS_MAX     2048

glibc-2.23/sysdeps/unix/sysv/linux/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     2048

glibc-2.23/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/unix/sysv/linux/mips/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/unix/sysv/linux/tile/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
64:#define PTHREAD_KEYS_MAX     1024

glibc-2.23/sysdeps/nacl/bits/local_lim.h
29:#define PTHREAD_KEYS_MAX        2048
  • 编译 glibc-2.23
apt install gawk
mkdir build
cd build
../configure CC=gcc --disable-sanity-checks

安装前的准备

  • 查看 pthread 所在目录
$ locate pthread.so
/lib/x86_64-linux-gnu/libpthread.so.0
/usr/lib/x86_64-linux-gnu/libpthread.so
/usr/lib/x86_64-linux-gnu/samba/vfs/aio_pthread.so
  • 查看运行库
$ cd /lib/x86_64-linux-gnu/
$ l *pthread*
-rwxr-xr-x 1 root root 136K Jun 17 04:57 libpthread-2.23.so
lrwxrwxrwx 1 root root   18 Jun 17 04:57 libpthread.so.0 -> libpthread-2.23.so
  • 查看链接库
$ cd /usr/lib/x86_64-linux-gnu
$ l *pthread*
-rw-r--r-- 1 root root 2.4M Jun 17 04:52 libpthread.a
-rw-r--r-- 1 root root 7.6K Jun 17 04:52 libpthread_nonshared.a
-rw-r--r-- 1 root root  252 Jun 17 04:52 libpthread.so
  • 查看头文件位置
$ locate local_lim.h
/usr/include/x86_64-linux-gnu/bits/local_lim.h

替换链接库

  • 备份链接库
cd /usr/lib/x86_64-linux-gnu
mv libpthread.so libpthread.so.bak
mv libpthread.a libpthread.a.bak
mv libpthread_nonshared.a libpthread_nonshared.a.bak
  • 替换链接库 编译完成后记得还原
cd /usr/lib/x86_64-linux-gnu
cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.so .
cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.a .
cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread_nonshared.a .

替换运行库

  • 备份运行库

    • 部分 shell 命令依赖 libpthread.so.0,如 cp,mv。
    cd /lib/x86_64-linux-gnu/
    cp libpthread.so.0 libpthread.so.0.bak
    
    • ln 仍然可用,可用于紧急情况下恢复。
    ln -s -f libpthread-2.23.so libpthread.so.0 
    
  • 替换运行库

    • 放到执行目录下
    export LD_LIBRARY_PATH=./
    cd /home/share/glibc-2.23/glibc-2.23/build/nptl
    cp *.so* /var/data/testprogram
    
    • 放到系统目录下 危险,尽量不要使用这种方法
    cd /lib/x86_64-linux-gnu/
    cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.so libpthread.spider.so
    ln -s -f libpthread.spider.so libpthread.so.0
    
  • 修改头文件 编译完成后记得还原
vim /usr/include/x86_64-linux-gnu/bits/local_lim.h
#define PTHREAD_KEYS_MAX 10240

GCC 多个 lib 同名函数链接冲突问题

问题描述

  • 用 gcc 编译两个动态库 lib1.so lib2.so, 程序 app 链接到这两个动态库
  • lib1.so 中定义了全局变量 var=1 , lib2.so 中定义全局变量 var=2 。即相同变量 var 在不同 lib 中定义值不同。
  • lib1.so 中定义了函数 fun1() { print(var); }
  • lib2.so 中定义了函数 fun2() { func1(); print(var); } , 即 lib2.so 依赖 lib1.so
  • 运行 app,调用 fun1fun2 ,输出 var 的值是相同的。

问题分析

  • gcc 链接时,有个默认规则:当一个符号需要被加入全局符号表时,如果相同的符号名已经存在,则后加入的符号被忽略
  • 用 VC 编译链接这个程序, fun1fun2 会输出不同值: VC 在发现多个依赖库中有同名符号时, 会符号重定义, 而不是默认的选择一个

问题解决

  • 使用编译参数 -fvisibility=hidden ,使所有符号默认不导出
  • 将 fun1 和 fun2 声明为导出符号

    #define MY_API __attribute__((visibility("default")))
    void MY_API fun1();
    void MY_API fun2();
    
  • fun1fun2 可以输出各自 lib 中定义的值。

ubuntu 批量编码转换

  • 查询编码

    find . \( -name "*.cpp" -or -name "*.c" -or -name "*.h" \) -type f -exec file -i {} \; > /tmp/a
    
    
  • 转换

    find . -name "*" -type f -exec iconv -f GBK -t UTF-8 {} -o /home/share/jni/{} \;
    
    
  • 转换脚本

    #!/bin/sh
    FILES=$(find . -type f -name '*.*')
    for f in $FILES
    do
        if test -f $f; then
            CHARSET="$( file -bi "$f"|awk -F "=" '{print $2}')"
            echo $CHARSET
            if [ "$CHARSET" = iso-8859-1 ]; then
                echo "Converting $f from $CHARSET to utf-8"
                # iconv -f "$CHARSET" -t utf-8 "$f" -o "$f.temp"
                iconv -f GBK -t UTF-8 "$f" -o "$f.temp"
                mv -f "$f.temp" $f
            fi
        else
            echo "Skipping $f - it's a regular file";
        fi
    done
    
  • 参考链接

ubuntu server 上安装 xfce 并远程访问

  • 安装 xfce

    apt install xfce4
    
  • 安装 vncserver

    apt install vnc4server
    
  • 设置 vncserver 密码

    vncserver :1
    vncserver -kill :1
    
  • 修改 vncserver 启动文件

    vim ~/.vnc/xstartup
    
    #x-window-manager &
    sesion-manager & xfdesktop & xfce4-panel &
    xfce4-menu-plugin &
    xfsettingsd &
    xfconfd &
    xfwm4 & 
    scim -d &
    fcitx &
    
  • 启动 vncserver

    vncserver -geometry 1920x1080
    
  • 从 window vnc 连接连接名称为 IP:1
  • 创建 clion 菜单项

    vim ~/.local/share/applications/.desktop
    
    [Desktop Entry]
    Version=1.0
    Type=Application
    Name=clion
    Exec=/home/share/clion-2017.1.1/bin/clion.sh
    Icon=/home/share/clion-2017.1.1/bin/clion.svg
    Categories=Development
    
  • 隐藏 panel
    • Applications -> Settings -> Settings Manager -> Panel
    • panel1, panel2 都设置为自动隐藏
  • 安装字体
    • 安装思源黑体

      curl -O https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKsc-hinted.zip
      unzip NotoSansCJKsc-hinted.zip -d noto
      cd noto
      mkdir -p /usr/share/fonts/opentype/noto
      cp *otf /usr/share/fonts/opentype/noto
      fc-cache -f -v
      
    • 安装文泉驿字体

      apt install fonts-wqy-microhei fonts-wqy-zenhei
      
  • 终端 tab 不能补全问题

    vim ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
    
    <!-- <property name="&lt;Super&gt;Tab" type="string" value="switch_window_key"/> -->
    <property name="&lt;Super&gt;Tab" type="empty"/>
    
  • 安装 sublime-text3

    add-apt-repository ppa:webupd8team/sublime-text-3
    apt update
    apt install sublime-text-installer
    
    • 打开 Settings -> MIME Type Editor,修改文本文件的默认打开方式
  • 安装 7z, rar 解压

    apt install p7zip-full
    7z x archive.7z
    
  • 安装其它软件

    apt install firefox
    apt install gnome-commander
    apt install terminator
    
  • vnc4server 下使用中文输入法

    apt install fcitx fcitx-frontend-all fcitx-tools fcitx-config-gtk2 fcitx-table-wbpy im-switch scim
    e ~/.xprofile #append
    
    export XMODIFIERS=@im=fcitx
    export XIM=fcitx
    export XIM_PROGRAM=fcitx
    export GTK_IM_MODULE=fcitx
    export QT_IM_MODULE=fcitx
    
    e ~/.vnc/xstartup  #append
    
    scim -d &
    fcitx &
    
    • 修改切换输入法快捷键为 Ctrl-Alt-SPC
  • 快捷键冲突
    • Settings -> Windows Manager -> Clear 所有冲突快捷键
  • oh-my-zsh

    apt install zsh autojump thefuck silversearcher-ag
    chsh -s $(which zsh)
    sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
    
    vim ~/.zshrc #modify
    
    ZSH_THEME="ys"
    . /usr/share/autojump/autojump.sh