Debugging system hang by blacklist kernel module

有時在機器上會遇到 system hang 的狀況,特別是在 enable 新硬體時。遇到這種情況,可以試著 blacklist 可疑的 kernel module

以 mwifiex_sdio 為例

# Do not load the 'mwifiex_sdio' module on boot.
echo > /etc/modprobe.d/debug.conf <EOF
blacklist mwifiex_sdio
EOF

再重開機即可

如果這個 module 仍會被其它 module depends 而載入,可以再進一步的 blacklist

# Do not load the 'mwifiex_sdio' module on boot.
echo > /etc/modprobe.d/debug.conf <EOF
install mwifiex_sdio /bin/false
EOF

Using files in /etc/modprobe.d/

基於 upstream git-tree 產生 debian package patch

最近在工作上遇到一個 bug,在某些狀況下執行 lshw (02.16-2ubuntu1.2) 會 segmentation fault。找了 lshw 最新的 code 編譯執行後發現沒有這個問題。於是就開始了 git bisect。最後找到是 d048d300b5daeb44887a7fc06ddeb120119cac8a 這筆修改在 src/core/scsi.cc 上面的 commit 解決了這個問題

順著這筆 commit,找到了 lshw project 的 bug report lshw segfaults, with some 16GB USB-3 sticks from Patriot 。也了解是 USB3.0 stick plugged 時會出現問題。在手上的機器上試了一下,果然是這樣沒錯。原本沒有頭緒的 random segmentation fault,現在則是有了 root cause 的 issue。

既然找到了 Solution,就開始要加 patch 進 Ubuntu source 了。為了將 patch 加到 Ubuntu 14.04 (Trusty) 目前的 lshw (02.16-2ubuntu1.2) 裡,我們還必須加上 src/core/scsi.cc 的前一個 commit b79f299319f61bc80e8d38e61631cfee7521a729

# clone upstream

git clone https://github.com/lyonel/lshw lshw-lyonel
# clone ubuntu source

bzr branch lp:ubuntu/trusty-proposed/lshw

# make patch from upstream git tree

cd lshw-lyonel/
git format-patch b79f299^..b79f299
git format-patch d048d30^..d048d30
cd ..

# import patches to ubuntu source

cd lshw/
dquilt push -a # apply existing patches

dquilt import ../lshw-lyonel/0001-use-a-different-approach-for-scanning-SCSI-generic-d.patch
dquilt import ../lshw-lyonel/0001-presumably-fix-653.patch

# edit changelog

dch -v 02.16-2ubuntu1.3 -D trusty

# local commit

debcommit

這樣就完成了,最後這一包 source 就可以拿來做 debian package 的打包,並且開始跑 Ubuntu package propose 的流程。

Ref:

  1. how to add upstream git patches to an existing debian package
  2. Chapter 3. Modifying the source
  3. How To Survive With Many Patches or Introduction to Quilt

debugging fork child process in GDB

剛在 python 遇到 subprocess 的問題,處理一陣子後突然想到,如果是 C++ 的話要怎麼用 GDB 來 debug. 查了文件後發現有2個方式:

  1. 讓 child sleep 一段時間,手動取得 PID 後,再讓 GDB attach 上去

這個方式可以想的到,有點暴力解的感覺。看來處理 multi-process 真的沒什麼好方法。

  1. 設定 follow-fork-mode

GDB 預設只會 attach 在 parent process 上,而不會控制 child process。但如果將 follow-fork-mode 設為 child,那在 fork() 之後,parent process 將不受 GDB 控制,只有 child process 在 GDB 的控制中。換句話說,同一時間只有一個 process 會被 attached。

set follow-fork-mode parent
# The original process is debugged after a fork. The child process runs unimpeded. This is the default. 

set follow-fork-mode child
#The new process is debugged after a fork. The parent process runs unimpeded.

由 folow-fork-mode 還延伸出 detach-on-fork,預設值開啟代表沒被 attached 的 process 會獨立的運作。關閉代表沒被 attached 的 process 會被 suspend。

Ref: Forks - Debugging with GDB

python3 UnicodeDecodeError

遇到 python UnicodeDecodeError 其實有點頭大。

#!/usr/bin/python3

# -*- coding: utf-8 -*-


import subprocess
import os
import sys
import locale

if __name__ == "__main__":
    locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
    proc = subprocess.Popen(['date'], stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     stdin=subprocess.PIPE,
                                     env={'LANG': 'zh_TW.UTF8', 'LANGUAGE': 'zh_TW:zh'},
                                     universal_newlines=True, shell=True)
    (out, err) = proc.communicate()
    import codecs
    sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
    print(out)
    print(err)
$ ./date.py

再進一步查了一下,發現這跟環境變數有關。

$ env -i LANG='en_US.UTF8' /usr/bin/python3 -c 'import locale; print(locale.getpreferredencoding(False))'               
UTF-8
$ env -i  /usr/bin/python3 -c 'import locale; print(locale.getpreferredencoding(False))'
ANSI_X3.4-1968

看完這份 slides ,才比較知道 Unicode 在 Python 中較好的處理方法 Unicode In Python, Completely Demystified

Solution

  1. Decode early
  2. Unicode everywhere
  3. Encode late

或是類似 Ubiquity 的直接強制使用 C.UTF
http://bazaar.launchpad.net/~ubuntu-installer/ubiquity/trunk/view/head:/bin/ubiquity#L44

kindle 7 (2014)

幾天前拿到了 Kindle 7 (2014),基本款kindle。今年即使在最基本款也已經有 touch 功能了。這幾天用下來,確實覺得滿特別的。有一些優缺點跟大家分享

優點:

  1. 相較一般螢幕,透過電子紙閱讀,對眼睛確實舒服很多,也確實不容易受到其它網路資訊的干擾。
  2. Kindle 提供 Chrome Extension 來將網路文章 Send to Kindle,如此一來以後較長的文章都可以送到 Kindle 上來閱讀。

缺點:

  1. Send to Kindle 的同步功能做的不是很好。當文章被 Send to Kindle 後,實際上是存到 Amazon Cloud Drive,然後手上 Kindle 會自動下載一份在裝置上。但當閱讀完畢後,2邊的刪除不會同步,造成我想刪除文章必須去2個地方刪除。這點也很確實的寫在 Kindle 文件上,但這點應該是很重要需要改進的地方。 Kindle Personal Documents Service
  2. PDF 也可以 Send to Kindle,但提供的方式不夠好。最好的話能提供 Web 界面讓使用者上傳 PDF。另外要注意的是,Send to Kindle 會將文件轉檔為 Amazona 使用的 azw 格式,所以文件有可能格式會跑掉,如果想在Kindle 上閱讀手上PDF,可能要有心理準備會有一些小問題。(補充一下,PDF是可以直接透過 USB 傳輸線不轉檔直接存到 Kindle 上,不過一來Kindle資料夾管理看起來很麻煩,二來 Kindle 6吋大小顯示 A4 內容閱讀起來會滿辛苦的。透過 Send to kindle 轉檔雖然格式會掉,但至少是易閱讀的電子書格式。)

Docker Insight

這幾天弄懂了 cgroup, kernel capbability 的機制,再搭配這份投影片 Docker Insight,有種很多東西都串起來的感覺。

Docker 1.2 新增的 cap-add, cap-drop,再加上 Docker 本身附有的 Volume mount,讓 container 又有了更多方便的使用方式。

Docker Insight from Tiago Pires