2013年8月16日 星期五

人善被人欺,行程善呢?

在嵌入式系統上,使用System-V init來開機,有些kernel module需要載入,而又不希望整個系統開機看起來反應很慢,這時候怎麼辦呢?

或許利用Linux的多工處理是種方法,也就是說跟顯示、操作無關的有些kernel module丟到背景去執行,這樣就可以幾乎同時跑出你主要程式,可是此時,有個問題,當你載入kernel module的行程與你主程式的行程優先權是一樣的時候,也不見得可以快到哪裡去。

所以怎麼辦呢?

請載入kernel module的行程友善一點,把系統資源讓出來,主要程式要快點端出來讓使用者看看。

換成命令就是:
$nice -n 19 /etc/rc.d/loadDriver.sh

很簡單吧~~所以這行程非常的友善,把資源都讓出來了,你主要的程式當然是可以用力的給他跑到畫面出來,這樣的效果在我手邊的機器上可以差到將近五秒鐘,只是加了nice而已。


nice的使用可以參考鳥哥的網站

事情難的都不是這命令怎麼用,而是你怎麼知道要改這個地方?

2013年8月15日 星期四

Core dump (核心轉儲)

核心檔案(core file),也稱核心轉儲(core dump),是作業系統在行程收到某些信號而終止執行時,將此時行程空間的內容以及有關行程狀態的其他訊息寫出到一個磁碟檔案。

核心檔案一詞源自於磁蕊記憶體 (core memory)

啟用core dump

大多數的Linux發行版通常會將core dump預設為關閉,此時要用ulimit命令可以查看目前的core dump功能是否有效。

$ulimit -c
0

-c 選項代表core dump文件的大小限制,上面例子限制為0,表示core dump是被關掉的。

開啟core dump

$ulimit -c unlimited

如此一來就設定為不限制core dump的大小,當發生問題的時候就會產生core file。

$./a.out
Segmentation fault (core dumped)

當下目錄會產生core file

$file core*
core.7561: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, format './a.out'

要用gdb除錯產生的core file

$gdb -c core.7561 ./a.out
GNU gdb Fedora (6.8-17.fc9)
...
Core was generated by './a.out'.
Program terminated with signal 11, Segmentation fault.
[New process 7577]
#0 0x000000000040048c in main () at segfault.c:6
6                     *a=0x1;



參考資料:
Book:Debug Hacks 深入除錯的技術和工具
Wiki :核心檔案


筆記Debug Hack 深入除錯的技術和工具

在這本書中提到有關程式異常結束時的對應方法
  • 程式異常結束
    • Kernel Panic?
      • NO  : SIGSEGV導致的?
        • NO  :其他原因 (HACK #5 ~ #7)
        • YES:記憶體非法存取 (HACK #26 ~ #30)
      • YES: Core Dump
        • NO  :設定了嗎?
          • 設定 (HACK #19 ~ #20)
          • 分析核心訊息 (HACK #38)
        • YES:原因分類 (Oops 消息 HACK #15)
          • 使用BUG() (HACK #35)
          • 偵測到異常 WDT (HACK #36 ~ #40)
          • 記憶體非法存取 (HACK #33 ~ #35)
  • 其他現象
    • degradation (HACK #41 ~ #42)
    • 記憶體洩漏 memory overlap (HACK #45、#46、$54)
  • 程式不結束
    • 核心有問題?
      • NO  : 負載高?(用top等調查)
        • NO  :死鎖 dead lock (HACK #31)
        • YES:死循環 (HACK #32)
      • YES: 設定了WDT了嗎?
        • NO  :WDT的設定方法 (HACK #22 ~ #23)
        • YES:SysRq鍵和minicom的用法 (HACK #16, #18)

2013年8月14日 星期三

關閉ERP的程式

有時候ERP授權是有限制的,通常那些用ERP的人為了怕等待,所以就把視窗一直開著,這就是所謂的「佔著毛坑不拉屎」的行為,導致後來要用的人根本連不上去,底下就是本人為了解決這個問題而試著寫的程式,當然路不只有一條。


#!perl
    use strict;
 use Win32::API;
    use Win32::GuiTest qw(:ALL);
 use File::HomeDir;
 
 my $maxLimit = 30; #second
 my $cmdName = "notepad.exe";
 my $counterFile = File::HomeDir->my_home."/counterFile.tmp";
 if(! -e "$counterFile"){
  system "ECHO 0 > \"$counterFile\"";
 }
 system "start ".$cmdName; #run command for testing
 #sleep 1;
 
 while(1){
  my $counter = `CAT \"$counterFile\"`; #read counter from counterFile.tmp
  chomp $counter;
  print "Counter is $counter\n";
  #To get foreground window handle
  my $hlWindow = GetForegroundWindow();
  #=========================================================================
  #To get PID via windows API
  Win32::API::->Import("user32","DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId)") or die $^E;
  my $pidLPDWORDStruct = pack( "L", 0 );
  GetWindowThreadProcessId($hlWindow, $pidLPDWORDStruct);
  my ($fwPid) = unpack ("L", $pidLPDWORDStruct);
  print "Foreground window PID is $fwPid\n";
  #=========================================================================
  
  my @taskList = `tasklist.exe`;
  
  my $targetPid=0;
  my $i=0;
  foreach my $line (@taskList){
   chomp $line;
   if($i > 4){
    my ($imageName, $pid, $sessionName, $session, $memUsage) = split /\ +/, $line;
    if($imageName =~ $cmdName){
     $targetPid = $pid; #save target PID
     if($pid == $fwPid){
      print $imageName."[".$pid."] --- foreground\n";
      system "ECHO 0 > \"$counterFile\""; #clear counter
      last; #break loop
     }else{
      print $imageName."[".$pid."] --- background\n";
      $counter++;
      system "ECHO $counter > \"$counterFile\""; #write to counterFile.tmp
      last; #break loop
     }
    }
   }
   $i++;
  }
  sleep(1);
  if($targetPid != 0 && $counter >= $maxLimit){
   system "taskkill.exe /pid $targetPid"; #kill process
   system "ECHO 0 > \"$counterFile\"";
  }
 }
 exit 0;

本人PO的原文

2013年8月9日 星期五

寫程式容易除錯難 II

在這一個行業混那麼多年了,這個是真是感觸很深,最近有個客戶把CODE丟到我手上,要我除錯,我花了一天想要建立環境,還要混到晚上等他起床,隔天大概花了不到一天的時間就查到問題所在,又是個Memory overlap的問題。

這老兄阿,顯示年月日的空間只要了七個字元的空間,扣除掉最後的c-string的結尾,前面只有6個字元而已。

下完底下這一行
sprintf(buffer,"%02d%02d%02d", bYY,bMM,bDD);

整個程式就瘋了,bYY因為RTC時間不正常,數值是226,記憶體一下子就overlap了,當然是吐出segmentation fault啦!

這看似很簡單的錯誤,這老美卻是把問題丟出來,DEBUG這回事有時候答案是很蠢,很簡單的錯誤,可是要找到這蟲阿,卻可能是個很複雜的過程。

今天發現有一個還不錯的東西等待研究Valgrind,這單字好像是英靈殿的入口,英靈殿(瓦爾哈拉Valhalla)是北歐神化中的天堂,掌管戰爭、藝術與死者的主神奧丁命令女武神(瓦爾基里Valkyrja)將陣亡的英靈戰士(恩赫里亞 Einherjar)帶來此服侍,這堆在日本動畫中出現的北歐神話字眼,都不是重點~~ㄎㄎㄎ。

Valgrind是在Linux下GPL V2的模擬除錯工具的集合,目前是還沒試過,相信也是有機會用的上,這一次我是用core dump的資訊去追出錯的地方,用的是老方法。

改天研究一下這個東西怎麼用~ㄎㄎㄎ(會用就進去英靈殿了)

參考資料:
IBM的文件
某人的部落格
WIKI說明