2011年10月13日 星期四

海邊

圖片如果顛倒請見諒




ref: http://www.youtube.com/watch?v=Qx_EGe_yfME

2011年7月12日 星期二

C++ 繼承測試


#include
#include
#pragma hdrstop

using namespace std;
//---------------------------------------------------------------------------

class A
{
private:
// virtual void __fastcall virtual_private_pure()=0;
// void __fastcall private_pure()=0;
virtual void __fastcall virtual_private_A(){cout << "virtual_private_A" << endl;};
void __fastcall private_A(){cout << "private_A" << endl;};
protected:
virtual void __fastcall virtual_protected_pure()=0;
// void __fastcall protected_pure()=0;
virtual void __fastcall virtual_protected_A(){cout << "virtual_protected_A" << endl;};
void __fastcall protected_A(){cout << "protected_A" << endl;};
public:
virtual void __fastcall virtual_public_pure()=0;
// void __fastcall public_pure()=0;
virtual void __fastcall virtual_public_A(){cout << "virtual_public_A" << endl;};
void __fastcall public_A(){cout << "public_A" << endl;};


void A_get_private_A(){ private_A(); }
void A_get_virtual_private_A(){ virtual_private_A(); }
virtual void get_private_A(){ private_A(); }
virtual void get_virtual_private_A(){ virtual_private_A(); }
void get_private_A2(){ private_A(); }
void get_virtual_private_A2(){ virtual_private_A(); }
virtual void get_private_A3(){ private_A(); }
virtual void get_virtual_private_A3(){ virtual_private_A(); }
void void get_private_A4(){ private_A(); }
void void get_virtual_private_A4(){ virtual_private_A(); }
};

class B : public A
{
private:
// virtual void __fastcall virtual_private_pure()=0; //no supported
// void __fastcall private_pure()=0; //no supported

//以下2個要宣告,否則後面func呼叫會失敗,有宣告仍可以達到繼承
virtual void __fastcall virtual_private_A(){cout << "virtual_private_B" << endl;};
void __fastcall private_A(){cout << "private_B" << endl;};
protected:
virtual void __fastcall virtual_protected_pure(){cout << "virtual_protected_pure B" << endl;};
// void __fastcall protected_pure()=0; //no supported
virtual void __fastcall virtual_protected_A(){cout << "virtual_protected_B" << endl;};
void __fastcall protected_A(){cout << "protected_A" << endl;};
public:
virtual void __fastcall virtual_public_pure(){cout << "virtual_public_pure B" << endl;};
// void __fastcall public_pure()=0; //no supported
virtual void __fastcall virtual_public_A(){cout << "virtual_public_B" << endl;};
void __fastcall public_A(){cout << "public_B" << endl;};

void B_get_private_A(){ private_A(); }
void B_get_virtual_private_A(){ virtual_private_A(); }
virtual void get_private_A(){ private_A(); }
virtual void get_virtual_private_A(){ virtual_private_A(); }
void get_private_A2(){ private_A(); }
void get_virtual_private_A2(){ virtual_private_A(); }
void get_private_A3(){ private_A(); }
void get_virtual_private_A3(){ virtual_private_A(); }
virtual get_private_A4(){ private_A(); }
virtual get_virtual_private_A4(){ virtual_private_A(); }

};



#pragma argsused
int main(int argc, char* argv[])
{
B b;
A *pA = dynamic_cast(&b);


//private calling exported B-func , exported A-func , privated-func
b.B_get_private_A(); // B non-virt x non-virt
b.B_get_virtual_private_A(); // B non-virt x virt
b.get_private_A(); // B virt virt non-virt
b.get_virtual_private_A(); // B virt virt virt
b.get_private_A2(); // B non-virt non-virt non-virt
b.get_virtual_private_A2(); // B non-virt non-virt virt
b.get_private_A3(); // B non-virt virt non-virt
b.get_virtual_private_A3(); // B non-virt virt virt
b.get_private_A4(); // B virt non-virt non-virt
b.get_virtual_private_A4(); // B virt non-virt virt

pA->A_get_private_A(); // A x non-virt non-virt
pA->A_get_virtual_private_A(); // B x non-virt virt(h)
pA->get_private_A(); // B virt(x) virt(h) non-virt
pA->get_virtual_private_A(); // B virt(x) virt(h) virt
pA->get_private_A2(); // A non-virt(x) non-virt non-virt
pA->get_virtual_private_A2(); // B non-virt(x) non-virt virt(h)
pA->get_private_A3(); // B non-virt(x) virt(h) non-virt
pA->get_virtual_private_A3(); // B non-virt(x) virt(h) virt
pA->get_private_A4(); // A virt(x) non-virt non-virt
pA->get_virtual_private_A4(); // B virt(x) non-virt virt(h)
return 0;
}
//---------------------------------------------------------------------------

2011年6月8日 星期三

花博的花


畫花(6/2),剛開始真的沒什麼把握,連背景都拿不準
所以只好先鉤出大致的線條
至於背景就先不強求了(一步步來)


完成第1朵花的大致花形
有些感覺了,花感覺有浮起來
特別注意花瓣的走法,所以線條特別小心一條條來
避免看起來像一片的感覺
本來是想用一個"紅"色來表示深淺與陰影
不過看了後面第2朵後,發現應該要改一下


這一朵佔有先天的花形美觀
在光影上也比較豐富
不過如果只是用"紅色"來表示明暗深淺會大打折扣
所以加了一點其他顏色,發現更豐富了
這裡,有用了桔色,桔紅色跟藍色來豐富線條跟光影
這朵看來就活潑很多(可能跟原圖的表現也有關)
花蕊的部分,也是很重要的表現地方,整體畫龍點睛的意味
特別注意他的陰影,跟點上去的分佈狀況(花蕊摻了一點深紫色)


不過畢竟還太淺了,表現不出他的真的特色
覺得應該還可以加強不同顏色來製造出他的豐富性
背景的部分,就先不在這裡著墨太多,日後慢慢加強


完成後2朵花畢竟還是會比較一下,就來個特寫

2011年5月31日 星期二

報稅-稅籍編號

桃園縣查詢稅籍編號:http://www.tytax.gov.tw/core/query/houseno.php?REGION=1&VILLID=110&LAST_REGION=1

在縣市政府網站上查到的稅籍編號通常只有11碼而已。報稅軟體所需的稅籍編號要12號,缺少的一碼是所謂的縣市代碼,譬如像台北市是A,台南市是D。
縣市代碼詳列如下:
A 台北市,
B 台中市,
C基隆市,
D 台南市,
E 高雄市,
F 台北縣,
G 宜蘭縣,
H 桃園縣,
I 嘉義市,
J 新竹縣,
K 苗栗縣,
L 台中縣,
M 南投縣,
N彰化縣,
O 新竹市,
P 雲林縣,
Q 嘉義縣,
R 台南縣,
S 高雄縣,
T 屏東縣,
U 花蓮縣,
V 台東縣,
W 金門縣,
X 澎湖縣,
Y 陽明山,
Z 連江縣。
所以假設你在台中市查到的編號是 01234567890 的話,就要輸入 B01234567890 .

2011年5月30日 星期一

水果盤


在親戚家裡,陪小朋友畫水果(2011/05/28)
也是第1次畫水果(以前好像都畫些543)
有人說,芒果看來蠻好吃的
我個人覺得橘子也不錯

畫得有點怪的貓


這次陪女兒畫家裡的貓,
這輩子第一次畫動物(2011,05月)
不好看也沒辦法了
自己認為比較強調在筆法

海棉寶寶系列





陪女兒畫的第1個系列(2011,4月)
好久沒畫圖了,很懷念
派大星最高票,其次是海棉寶寶

2011年5月15日 星期日

phplist匯入名單

假設剛裝好機器時,要匯入名單開始講起
匯入時,經常會遇到的2個問題
1.發現自己手動新增的的名字是正常的,但匯入名單是亂碼
原因是因為網頁必須要顯示UTF8的字,手動匯入名單的檔案來源是Big5
所以需要用轉碼程式來進行Big5轉UTF8,可以用ConvertZ這類程式先做轉換
2.發現自己手動新增的名字以及匯入名單都是亂碼,而從舊的資料庫備分檔還原後,是正常的
原因是曾經對資料庫進行重新初始化的作業,初始化的過程中,編碼不是用UTF8
所以原始儲存資料的編碼就有問題所導致
需要修改/etc/my.cnf的default-character-set=utf8,在[mysql] [mysqld]及[client]中
3.發現都其他原因的亂碼
應該是網頁顯示沒有設定成中文,或者網站已經故障
前項,切換成中文即可;後項,備份資料庫後重裝系統,再復原






依自己想要匯入名單的群組先加好電子報的名字(以下說明分"學術單位" 以及 "電子產業")



以下開始要準備在電子報裡,想要新增的欄位,這些欄位跟你的來源資料有關
一般除了email(預設已存在)是必要欄位外,其他建議不要鉤選"必要"
在設定欄位名字時,請注意,要跟資料來源的第1行一樣,
以下範例就是採用firstname,lastname,title,comp這4欄,都不是必要
而email不用新增,因為這是預設資料來源一定要有的必要欄位





以下是示範如何用ConvertZ來將來源資料轉成UTF8的中文編碼
如果如此才能確保網頁顯示正確中文


接下來再依以下步驟,即可完成匯入







2011年5月10日 星期二

Linux 上中文轉碼

在許多系統,預設要使用utf8的編碼資料
例如opensource的web系統(phplist phpMyAdmin)
而一般AP或WINDOW軟體多半是用Big5編碼,一旦轉出給opensource系統轉入,會有亂碼
Linux提供iconv的工具來進行資料轉換
accounts_phplist2.csv是原Big5編碼的資料
accounts_phplist2-utf8.csv則是經過編碼轉成utf8的資料
範例如下


iconv -f Big5 -t UTF-8 < accounts_phplist2.csv > accounts_phplist2-utf8.csv

Windows也有許多工具可以做到,以下舉一個範例
1.先下載ConvertZ並安裝
2.開啟後,指定來源檔,加入,目的路徑,轉碼方式

2011年5月6日 星期五

dump webpage

(1) telnet
[root@HTS099 burn]#telnet [target-ip] 80
[root@HTS099 burn]#telnet> GET [folder/page.htm] HTTP/1.1
[root@HTS099 burn]#telnet> Host:[source-ip or host name]
[root@HTS099 burn]#telnet> Authorization: Basic [ecrypted account and password]

encrypted process:
[root@HTS099 burn]# python
Python 2.6.5 (r265:79063, Jul 14 2010, 11:36:05)
[GCC 4.4.4 20100630 (Red Hat 4.4.4-10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> print base64.b64encode(":") 帳號密碼為空白
Og==
>>> print base64.b64encode("acct:pass") .htaccess的帳號acct密碼pass
YWNjdDpwYXNz
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>>
[root@HTS099 burn]#

Example:
[root@PHPLIST ~]# telnet 192.168.1.254 80
Trying 192.168.1.254...
Connected to 192.168.1.254 (192.168.1.254).
Escape character is '^]'.
GET /status.htm HTTP/1.1
Host:192.168.1.100
Authorization: Basic Og==

HTTP/1.0 200 Okay
Connection: close
Server: IPShare6.0
MIME-version: 1.0
Pragma: no-cache
Content-Type: text/html
Content-Length: 5210

<html>
<head>
<title>Connection Status</title>
<script type="text/javascript" language="JavaScript">
:
:
:Connection closed by foreign host.

(2) wget
wget --http-user '' --http-password '' http://192.168.1.254/status.htm -O /root/status.htm
wget --http-user 'acct' --http-password 'pass' http://192.168.1.254/status.htm -O /root/status.htm

2011年4月29日 星期五

AIX core file trace

errpt -a

For example, to invoke the kdb command using a dump file named
/var/adm/ras/vmcore.0 and the kernel file named /unix, type:
  1. kdb /var/adm/ras/vmcore.0 /unix
-> find out which signal caused the core dump: file core_file

-> find out where the program was executing when the coredump occured (program's call stack):
dbx object_file core_file
where

dbx comes with bos.adt.debug and offers many more subcommands -> man dbx

应用进程 core dump 分析

上一章我们介绍了 core dump 产生的基本原理。本章我们将针对 AIX 操作系统,介绍 core dump 定位相关的背景知识。

环境变量设置

可以通过 /etc/security/limits 文件对各用户的基本配置参数包括 core 大小进行限制。或者通过 ulimit 更改当前环境下的 core 大小限制。

默认情况下,应用进程生成 core dump 时都使用文件名 core。为了避免同一工作目录下的进程 core 相互覆盖,可以定义环境变量 CORE_NAMING=true,然后启动进程,这样将生成名为 core.pid.ddhhmmss 的文件。可以使用 file core 命令查看 core 是哪个进程产生的。

默认情况下,应用进程 dump 时会包含所有的共享内存,如果 dump 时想排除共享内存内容,可以在启动进程之前设置环境变量 CORE_NOSHM=true.

系统有一个参数 fullcore 用于控制是否在程序 coredump 时生成完整的 core。为避免信息丢失,建议打开 fullcore。可以使用 lsattr –El sys0 查询是否将 fullcore 打开,使用 chdev -l sys0 -a fullcore=true 将 fullcore 状态更改为打开。也可以在程序内部调用 sigaction 例程设置 fullcore,参考如下测试程序:


fullcore 设置示例

                 //test.C #include  #include    int main(int argc, char* argv[]) {  char str[10];  struct sigaction s;  s.sa_handler = SIG_DFL;   s.sa_mask.losigs = 0;  s.sa_mask.hisigs = 0;  s.sa_flags = SA_FULLDUMP;  sigaction(SIGSEGV,&s,(struct sigaction *) NULL);    std::cout << " input str!\n" << std::endl;  std::cin >> str;  return 0; } 

寻找 core dump

应用进程的 core 产生在其当前工作目录下,可以在应用程序内部使用 chdir 函数切换当前工作目录。使用 procwdx 命令可以查看进程的当前工作目录。系统的 core 生成在 lg_dumplv 下,并在重启时转移到 /var/adm/ras/ 目录下(如果有足够空间的话,否则继续保留在 lg_dumplv,并随时有可能被覆盖)。

可以使用 errpt -a 查看标识 C0AA5338 SYSDUMP(系统 core)、B6048838 CORE_DUMP(进程 core)的详细错误信息,获取生成 core 的进程以及 core 文件位置。使用 snap –ac 收集系统的 dump 信息。

core dump 信息收集

如果可能 , 直接在发生 coredump 的机器上用 dbx 分析出结果 , 这样是最方便的分析方法 . 这种情况下注意不要直接以 root 用户登录然后用 dbx 分析 , 而必须在应用程序所属的用户下进行此操作 , 因为 core 可能需要依赖应用程序运行时对应环境下的某些库 , 这样就要借助应用程序的环境变量 .

如果需取回生产机上的 core 信息在实验室分析 , 则需要搜集一些相关信息 . 进程 core 分析一般至少需要依赖应用可执行程序,有时还需要包括一些运行时动态库信息。如果需要收集 core 相关的完整信息,可运行 snapcore < 可执行文件以及名称 >,例如 snapcore ./core ./a.out,然后在 /tmp/snapcore 下取下相应的 .pax.Z 文件。

正常的收集过程应该如下 :


snap core 收集过程

                 # snapcore ./core ./a.out Core file "./core" created by "a.out"  pass1() in progress ....   Calculating space required .   Total space required is 14130 kbytes ..   Checking for available space ...   Available space is 807572 kbytes  pass1 complete.  pass2() in progress ....   Collecting fileset information .   Collecting error report of CORE_DUMP errors ..   Creating readme file ..   Creating archive file ...   Compressing archive file ....  pass2 completed.  Snapcore completed successfully. Archive created in /tmp/snapcore.  # cd /tmp/snapcore # ls snapcore_352276.pax.Z # uncompress snapcore_352276.pax.Z # ls snapcore_352276.pax # pax -r -f snapcore_352276.pax # ls 注意需要保证有类似如下文件 ( 可执行文件,/core/errpt/lslpp/usr 目录等 ): README errpt.out usr a.out lslpp.out core snapcore_352276.pax # 

使用 dbx 分析 core dump 的例子

dbx 是 AIX 下基于命令行界面的源码级调试工具。本文档只提供一些基本的 dbx 分析指令,详细内容请参考“General Programming Concepts: Writing and Debugging Programs”关于 dbx 的描述。


初步分析

                 #dbx  core 

示例:

# dbx ./test core Type 'help' for help. warning: The core file is not a fullcore. Some info may not be available. [using memory image in core] reading symbolic information ...warning: no source compiled with -g  Segmentation fault in raise at 0xd022e1e4 0xd022e1e4 (raise+0x40) 80410014 lwz r2,0x14(r1) 

显示出 core 发生时,当前进程执行到的位置(-g 编译的情况下能够看到具体的行):

(dbx) where raise(??) at 0xd022e1e4 main(0x1, 0x2ff22d48) at 0x100019c4 

注意:

如果分析的是异地 core 文件,需要采用 snapcore 收集相关 core 信息。对于依赖链接库的情况,注意需要增加 -p oldpath=newpath:... 重新设置链接库路径(只有所有依赖的库都已经被链接,才能完整的复现 core dump 故障现场),参考 dbx 的帮助文档获取更多信息。

# cd /tmp/snapcore # dbx –p /=./ a.out core Type 'help' for help. [using memory image in core] reading symbolic information ...warning: no source compiled with -g   IOT/Abort trap in raise at 0xd01f4f60 0xd01f4f60 (raise+0x40) 80410014 lwz r2,0x14(r1)  

列举源码信息

列举程序源码(list,需要在运行 dbx 命令时使用 -I 指明源码搜索路径,并使用 -g 编译)或者汇编码(listi):

 (dbx) listi main 0x10001924 (main) 7c0802a6 mflr r0 0x10001928 (main+0x4) bfa1fff4 stmw r29,-12(r1) 0x1000192c (main+0x8) 90010008 stw r0,0x8(r1) 0x10001930 (main+0xc) 9421ffa0 stwu r1,-96(r1) 0x10001934 (main+0x10) 83e20064 lwz r31,0x64(r2) 0x10001938 (main+0x14) 90610078 stw r3,0x78(r1) 0x1000193c (main+0x18) 9081007c stw r4,0x7c(r1) 0x10001940 (main+0x1c) 83a20068 lwz r29,0x68(r2) 

列举变量内容

示例代码:

#include  #include  int g_test =0;  int testfunc(int &para) {  para++;  return 0; }  int main(int argc, char* argv[]) {  struct sigaction s;  s.sa_handler = SIG_DFL;  s.sa_mask.losigs = 0;  s.sa_mask.hisigs = 0;  s.sa_flags = SA_FULLDUMP;  sigaction(SIGSEGV,&s,(struct sigaction *) NULL);   char str[10];  g_test =0;   testfunc(g_test);  abort(); } # xlC test.C -g 

以全局变量 g_test 举例:

#print g_test 显示 g_test 的取值

#print sizeof(g_test) 显示 g_test 的大小

#whatis g_test 显示 g_test 的类型

#print &g_test 显示 g_test 的地址

#&g_test/16x 显示从 g_test 的地址开始处,连续 16 个 WORD(?byte)的取值

如果没有使用 -g 编译,则不能动态获取 g_test 的类型、大小等信息,但能够得到 g_test 的地址,并查询该地址所在区域存储空间的值。

例如:

# ./a.out IOT/Abort trap(coredump) # dbx ./a.out core Type 'help' for help. [using memory image in core] reading symbolic information ...  IOT/Abort trap in raise at 0xd03365bc 0xd03365bc (raise+0x40) 80410014 lwz r2,0x14(r1) (dbx) print g_test 1 (dbx) whatis g_test int g_test; (dbx) print sizeof(g_test) 4 (dbx) print &g_test 0x20000428 (dbx) &g_test/16x 0x20000428: 0000 0001 0000 0000 0000 0000 0000 0000 0x20000438: 0000 0000 0000 0000 0000 0000 0000 0000 

列举寄存器内容

列举寄存器内容:

(dbx) registers

如下模拟一个简单的 core dump,对 0 地址赋值引发 core dump 的问题:

# dbx ./a.out core Type 'help' for help. warning: The core file is not a fullcore. Some info may not be available. [using memory image in core] reading symbolic information ...warning: no source compiled with -g   Segmentation fault in main at 0x10000348 0x10000348 (main+0x18) 90640000 stw r3,0x0(r4) (dbx) where main(0x1, 0x2ff22ccc) at 0x10000348 (dbx) registers  $r0:0x00000000 $stkp:0x2ff22bf0 $toc:0x20000414 $r3:0x00000012  $r4:0x00000000 $r5:0x2ff22cd4 $r6:0xdeadbeef $r7:0x2ff22ff8  $r8:0x00000000 $r9:0x04030000 $r10:0xf0577538 $r11:0xdeadbeef  $r12:0xdeadbeef $r13:0xdeadbeef $r14:0x00000001 $r15:0x2ff22ccc  $r16:0x2ff22cd4 $r17:0x00000000 $r18:0xdeadbeef $r19:0xdeadbeef  $r20:0xdeadbeef $r21:0xdeadbeef $r22:0xdeadbeef $r23:0xdeadbeef  $r24:0xdeadbeef $r25:0xdeadbeef $r26:0xdeadbeef $r27:0xdeadbeef  $r28:0xdeadbeef $r29:0xdeadbeef $r30:0xdeadbeef $r31:0xdeadbeef  $iar:0x10000348 $msr:0x0000d0b2 $cr:0x22282489 $link:0x100001b4  $ctr:0xdeadbeef $xer:0x20000020  Condition status = 0:e 1:e 2:e 3:l 4:e 5:g 6:l 7:lo  [unset $noflregs to view floating point registers]  [unset $novregs to view vector registers] in main at 0x10000348 0x10000348 (main+0x18) 90640000 stw r3,0x0(r4) (dbx) print $r3 0x00000012 (dbx) print $r4 (nil) 

这个例子比较简单,从最后汇编指令“stw r3,0x0(r4)”就可以简单的看到程序 core dump 是因为向 0 地址(0+r4)存入 18(r3 寄存器值)造成。

查看多线程相关信息

如果以下环境变量采用默认的 OFF 值,则系统会完全禁止适当的调试列表,这意味着 dbx 命令将显示不出任何对象:

AIXTHREAD_MUTEX_DEBUG

AIXTHREAD_COND_DEBUG

AIXTHREAD_RWLOCK_DEBUG

可以使用

export AIXTHREAD_MUTEX_DEBUG=ON

打开 AIXTHREAD_MUTEX_DEBUG。

  • 查看线程信息

    (dbx) print $t1 // 打印 t1 线程的基本信息

    (dbx) attribute

    (dbx) condition

    (dbx) mutex

    (dbx) rwlock

    (dbx) thread

    例如:

    (thread_id = 1, state_u = 4, priority = 60, policy = other, attributes = 0x20001078)

  • 切换当前线程(默认当前线程为收到 core 触发信号所在线程)

    (dbx) thread current [tid]

    例如(> 表明 core dump 时的当前线程):

    (dbx)thread  thread state-k wchan state-u k-tid mode held scope function  $t1 wait 0x31bbb558 running 10321 k no pro _ptrgl   $t2 wait 0x311fb958 running 6275 k no pro _ptrgl  >$t3 run running 6985 k no pro _p_nsleep   $t4 wait 0x31bbbb18 running 6571 k no pro _ptrgl   $t5 wait 0x311fb9d8 running 7999 k no pro _ptrgl   $t6 wait 0x31bf8f98 running 8257 k no pro _ptrgl   $t7 wait 0x311fba18 running 8515 k no pro _ptrgl   $t8 wait 0x311fb7d8 running 8773 k no pro _ptrgl   $t9 wait 0x311fbb18 running 9031 k no pro _ptrgl   $t10 wait 0x311fb898 running 9547 k no pro _ptrgl   $t11 wait 0x311fb818 running 9805 k no pro _ptrgl   $t12 wait 0x311fba58 running 10063 k no pro _ptrgl   $t13 wait 0x311fb8d8 running 10579 k no pro _ptrgl  (dbx) thread current 3 (dbx) where _p_nsleep(??, ??) at 0xd005f740 raise.nsleep(??, ??) at 0xd022de3c sleep(??) at 0xd0260344 helper(??) at 0x100005ac (dbx) thread current 4 warning: Thread is in kernel mode, not all registers can be accessed. (dbx) where ptrgl._ptrgl() at 0xd020e470 raise.nsleep(??, ??) at 0xd022de3c raise.nsleep(??, ??) at 0xd022de3c sleep(??) at 0xd0260344 helper(??) at 0x100005ac (dbx)  

core dump 分析的局限性

不要期待能依赖 core dump 分析解决所有的问题,下面是一个简单的模拟缓冲区溢出的例子,在这个例子中由于缓冲区溢出覆盖了调用栈信息,从而完全丢失了定位依据:

root@/tmp#>xlC test.C -g -o test2 root@/tmp#> root@/tmp#>./test  input str!  012345678901234567890123456789 Segmentation fault(coredump) root@/tmp#>dbx ./test2 core Type 'help' for help. [using memory image in core] reading symbolic information ...  Segmentation fault in test2. at 0x34353634 0x34353634 (???) warning: Unable to access address 0x34353634 from core (dbx) where warning: Unable to access address 0x34353634 from core warning: Unable to access address 0x34353634 from core warning: Unable to access address 0x34353630 from core warning: Unable to access address 0x34353630 from core warning: Unable to access address 0x34353634 from core warning: Unable to access address 0x34353634 from core warning: Unable to access address 0x34353630 from core warning: Unable to access address 0x34353630 from core warning: Unable to access address 0x34353634 from core warning: Unable to access address 0x36373841 from core test2.() at 0x34353634 warning: Unable to access address 0x36373839 from core warning: Unable to access address 0x36373839 from core (dbx) 

系统 dump 分析

环境变量设置

可以通过“sysdumpdev –l”查看系统当前的 dump 配置信息:

root@/#>sysdumpdev -l primary /dev/hd6 secondary /dev/sysdumpnull copy directory /var/adm/ras forced copy flag TRUE always allow dump FALSE dump compression ON 

注意旧版本的 AIX “always allow dump”可能默认为关闭;为方便系统 crash 时问题定位,建议打开,可使用命令 sysdumpdev –K 或者使用 smitty -> System Environments-> Change / Show Characteristics of System Dump 菜单设置。

sysdumpdev –L 获得最近系统产生的 dump 的相关统计信息:

#>sysdumpdev -L 0453-039 Device name: /dev/hd6 Major device number: 10 Minor device number: 2 Size: 18885120 bytes Uncompressed Size: 113724523 bytes Date/Time: Sat Jul 21 14:20:22 BEIST 2007 Dump status: 0 dump completed successfully Dump copy filename: /var/adm/ras/vmcore.2.Z 

为保证系统出现 crash 时,dump device 能够保存下 dump 信息,需要合理的配置 dump device 的大小,可以使用 sysdumpdev –e 估计系统 dump 需要的空间。一般推荐的 dump device 值大小为 sysdumpdev –e 估计值的 1.5 倍。

环境变量设置

本文档只提供一些基本的 dump 分析指令,详细内容请参考“KDB kernel debugger and kdb command ”。

初步分析

kdb 对 dump 文件分析需要借助于产生 dump 的内核文件 /unix,一般 snap –ac 会对此文件进行收集。初步命令如下:

#kdb ./dump ./unix

示例:

#kdb ./dump ./unix The specified kernel file is a 64-bit kernel ./dump mapped from @ 700000000000000 to @ 70000007da53bd5 Preserving 1317350 bytes of symbol table First symbol __mulh Component Names:  1) minidump [2 entries]  2) dmp_minimal [9 entries]  3) proc [481 entries]  4) thrd [1539 entries]  5) rasct [1 entries]  6) ldr [2 entries]  7) errlg [3 entries]  8) mtrc [26 entries]  9) lfs [1 entries] 10) bos [2 entries] 11) ipc [7 entries] 12) vmm [13 entries] 13) alloc_kheap [256 entries] 14) alloc_other [26 entries] 15) rtastrc [8 entries] 16) efcdd [20 entries] 17) eidedd [1 entries] 18) sisraid [2 entries] 19) aixpcm [5 entries] 20) scdisk [11 entries] 21) lvm [2 entries] 22) jfs2 [1 entries] 23) tty [4 entries] 24) netstat [10 entries] 25) goent_dd [7 entries] 26) scsidisk [11 entries] 27) efscsi [5 entries] 28) dump_statistics [1 entries] Component Dump Table has 2456 entries  START END  0000000000001000 0000000003BBA050 start+000FD8 F00000002FF47600 F00000002FFDC920 __ublock+000000 000000002FF22FF4 000000002FF22FF8 environ+000000 000000002FF22FF8 000000002FF22FFC errno+000000 F100070F00000000 F100070F10000000 pvproc+000000 F100070F10000000 F100070F18000000 pvthread+000000 PFT: PVT: id....................0002 raddr.....0000000000686000 eaddr.....F200800030000000 size..............00040000 align.............00001000 valid..1 ros....0 fixlmb.1 seg....0 wimg...2 Dump analysis on CHRP_SMP_PCI POWER_PC POWER_5 machine with 8 available CPU(s)  (64-bit registers) Processing symbol table... .......................done 

分析命令示例

status 查看各个 CPU 在 dump 时正在运行的进程,如:

0)> status CPU TID TSLOT PID PSLOT PROC_NAME  0 2580F5 600 14C0F6 332 cron  1 12025 18 D01A 13 wait  2 1020BB 258 1580C6 344 expr  3 1502B 21 F01E 15 wait 

cpu 命令切换当前 CPU,默认的当前 CPU 为 cpu0:

(0)> cpu 1

(1)>

打印系统的基本状态和相关信息:

(0)> stat

打印系统 dump 时内核栈的情况:

(0)> f

lke 用来列出内核代码对应的相关系统文件信息:

(0)> lke 003DE9CC

显示系统 dump 时最后所在的指令:

(0)> dr iar

显示虚拟存储管理的日志信息;其中 Exception value 若为 0000001C 则表示 pagingspace 耗尽:

(0)> vmlog

显示进程表的信息:

(0)> proc

显示线程表的信息:

(0)> th

显示系统的 errpt 信息:

(0)> errpt

ERRORS NOT READ BY ERRDEMON (ORDERED CHRONOLOGICALLY):  Error Record: erec_flags .............. 1 erec_len ................ 54 erec_timestamp .......... 46DCDD9D erec_rec_len ............ 34 erec_dupcount ........... 0 erec_duptime1 ........... 0 erec_duptime2 ........... 0 erec_rec.error_id ....... DD11B4AF erec_rec.resource_name .. SYSPROC 00007FFF FFFFD000 00000000 003DE9CC .............=.. 00000000 00020000 80000000 000290B2 ................ 

总结

本文简单介绍了 core dump 相关的背景知识以及 AIX 上调试 core dump 的一些基本方法。通过阅读这篇文章,希望您能对 AIX 下 core dump 机制有所了解,并能够借助 core dump 定位基本的系统以及应用程序问题。

2011年4月22日 星期五

BCB在Link時連結.lib檔

(1)把 BCB 的專案關閉
(2)用文字編輯器(記事本 或 UltraEdit)修改專案檔案(例如: Project1.bpr)
(3)把 "xxx.lib" 分別加入 LIBRARIES 和 SPARELIBS 裡面,例如:


檢視純文字版複製到剪貼簿列印?


<xml version='1.0' encoding='utf-8' ?>
<-- C++Builder XML Project -->
<MACROS>
...............................................
<LIBRARIES value="xxx.lib yyy.lib" />
<SPARELIBS value="yyy.lib xxx.lib">
...............................................


(4)修改完後存檔
(5)用 BCB 開啟你的專案,重新 build 一次
注意:如果Project又在BCB的開發平台又存檔一次,那SPARELIBS的設定就會被蓋掉

利用dd備分及還原磁碟

利用dd指令遠端備份為ISO檔及還原成硬碟 (Linux, Unix, Solaris等適用)
遠端備份A(主機)的硬碟為ISO檔並儲存到B(File Server)的/backup目錄下

備份成ISO檔並丟到File Server:
Step1:SSH進入到欲備份的A主機下指令 (Linux)
Step2:dd if=/dev/hda | gzip -9 -c | ssh user@server_host dd of=/backup/hda.img.gz
Solaris 大概像以下的語法
/usr/local/bin/dd if=/dev/dsk/c1t0d0s2 | /usr/local/bin/gzip -9 -c | /usr/local/bin/ssh user@server_host /bin/dd of=/backup/c1t0d0s2.img.gz

從遠端File Server的ISO檔還原到本機硬碟
Step1:從一台裝上硬碟的Server, SSH進入到B(File Server)
Step2:ssh user@server_host zcat /backup/hda.img.gz | dd of=/dev/hda

如果該還原主機沒有作業系統,可採用 knoppix 之類的LiveCD來開機, 再綁上IP即可進行還原或備份

資料來源:
http://taiwanwolf.blogspot.com/2009/04/ddiso-linux-unix-solaris.html

2011年4月20日 星期三

mysql insert syntax


resolve: 1062 duplicate key
(1) import via ".sql" file
mysql -u root [dbname] --force < import.sql
(2)insert with IGNORE
insert IGNORE into symbdaily(symb,date,open,high,low,close,value) \
SELECT '001',cast(date as date)as date, \
cast(cast(open as decimal(8,2))*100 as unsigned) as open, \
cast(cast(high as decimal(8,2))*100 as unsigned)as high, \
cast(cast(low as decimal(8,2))*100 as unsigned) as low, \
cast(cast(close as decimal(8,2))*100 as unsigned) as close, \
cast(replace(replace(value,'↑',''),'↓','') as unsigned) as value \
FROM `tmp_idxdaily`
(3)Load data ... INFILE 'file' [IGNORE | REPLACE] ...

INSERT語法

INSERT [LOW_PRIORITY DELAYED HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ({expr DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]或:

INSERT [LOW_PRIORITY DELAYED HIGH_PRIORITY] [IGNORE] [INTO] tbl_name SET col_name={expr DEFAULT}, ... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]或:

INSERT [LOW_PRIORITY HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ] 一、DELAYED 的使用 使用延遲插入操作DELAYED調節符應用於INSERT和REPLACE語句。當DELAYED插入操作到達的時候,

服務器把數據行放入一個隊列中,並立即給客戶端返回一個狀態信息,這樣客戶
端就可以在數據表被真正地插入記錄之前繼續進行操作了。如果讀取者從該數據
表中讀取數據,隊列中的數據就會被保持著,直到沒有讀取者為止。接著服務器
開始插入延遲數據行(delayed-row)隊列中的數據行。在插入操作的同時,服務器
還要檢查是否有新的讀取請求到達和等待。如果有,延遲數據行隊列就被掛起,
允許讀取者繼續操作。當沒有讀取者的時候,服務器再次開始插入延遲的數據行。
這個過程一直進行,直到隊列空了為止。幾點要注意事項:
· INSERT DELAYED應該僅用於指定值清單的INSERT語句。服務器忽略用於INSERT DELAYED...SELECT語句的DELAYED。
· 服務器忽略用於INSERT DELAYED...ON DUPLICATE UPDATE語句的DELAYED。
· 因為在行被插入前,語句立刻返回,所以您不能使用LAST_INSERT_ID()來獲取AUTO_INCREMENT值。AUTO_INCREMENT值可能由語句生成。
· 對於SELECT語句,DELAYED行不可見,直到這些行確實被插入了為止。
· DELAYED在從屬複製服務器中被忽略了,因為DELAYED不會在從屬服務器中產生與主服務器不一樣的數據。注意,目前在隊列中的各行只保存在存儲器中,直到它們被插入到表中為止。這意味著,如果您強行中止了mysqld(例如,使用kill -9)
或者如果mysqld意外停止,則所有沒有被寫入磁盤的行都會丟失。二、IGNORE的使用IGNORE是MySQL相對於標準SQL的擴展。如果在新表中有重複關鍵字,
或者當STRICT模式啟動後出現警告,則使用IGNORE控制ALTER TABLE的運行。
如果沒有指定IGNORE,當重複關鍵字錯誤發生時,複製操作被放棄,返回前一步驟。
如果指定了IGNORE,則對於有重複關鍵字的行,只使用第一行,其它有衝突的行被刪除。
並且,對錯誤值進行修正,使之儘量接近正確值。insert ignore into tb(...) value(...)這樣不用校驗是否存在了,有則忽略,無則添加

三、ON DUPLICATE KEY UPDATE的使用如果您指定了ON DUPLICATE KEY UPDATE,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重複值,則執行舊行UPDATE。例如,如果列a被定義為UNIQUE,並且包含值1,則以下兩個語句具有相同的效果:

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=c+1; mysql> UPDATE table SET c=c+1 WHERE a=1; 如果行作為新記錄被插入,則受影響行的值為1;如果原有的記錄被更新,則受影響行的值為2。

註釋:如果列b也是唯一列,則INSERT與此UPDATE語句相當:

mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1; 如果a=1 OR b=2與多個行向匹配,則只有一個行被更新。通常,您應該儘量避免對帶有多個唯一關鍵字的表使用ON DUPLICATE KEY子句。

您可以在UPDATE子句中使用VALUES(col_name)函數從INSERT...UPDATE語句的INSERT部分引用列值。換句話說,如果沒有發生重複關鍵字衝突,則UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函數特別適用於多行插入。VALUES()函數只在INSERT...UPDATE語句中有意義,其它時候會返回NULL。

示例:

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); 本語句與以下兩個語句作用相同:

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=3; mysql> INSERT INTO table (a,b,c) VALUES (4,5,6) -> ON DUPLICATE KEY UPDATE c=9; 當您使用ON DUPLICATE KEY UPDATE時,DELAYED選項被忽略。


參考資料:
http://miggo.pixnet.net/blog/post/30932550

2011年4月19日 星期二

putty 中文輸入及顯示

1. Windows -> Appearance -> Font Setting(如. 新細明體)
2.Windows -> Translation -> Character set translation on received data(如. UTF-8)
3. 檢查連線主機的locale設定
# locale

2011年4月17日 星期日

phplist使用手冊

[1]建置後第一步
(1)剛開始時,因為資料庫都尚未建置完成,所以沒辦法提供使用,所以第一件事便是"初始化資料庫" 用
http://主機位置/cab/lists/admin
來登入管理員頁面 一進入後,系統便會要求你"初始化資料庫"(Initialise Database),直接點擊它
附註:在這個頁面,你可能是中文的版面,也可能是英文版面,如果你想切換語言,在任何一個網頁
右上角,都可以切換


(2)初始化完成後,接著便是要進行資料庫設定的過程,點擊右方的"首頁"(Main Page)
因為還沒登入過,所以會先跳出登入畫面(登入帳號密碼預設為admin/phplist),
然後就會跳出主選單,點擊主選單中的"設定"(Setup)來設定資料庫

[2]設定資料庫
初始化資料庫因為已經在剛開始的時候完成了,所以從修改密碼開始
承上一節,在右邊選單中點擊"主選單"(Setup),若未登入時,則會要求你以管理員登入
剛開始預設的管理員為admin, 預設密碼為phplist,進入後即可開始第2個設定
(1)修改管理者密碼 (Change Admin Password)


(2)一般設定(Configure General Values)
其他設定項目,請視狀況決定要設定什麼,以下為例,因為發出電子報預設會有電子報的附加功能
例如,可以取消訂閱,但如果只是內部管理,沒有外部IP,那EMAIL應避免寄出這類資訊


(3)設定欄位(Configure Attributes)
電子報系統預設只有簡單的EMAIL欄位,也以這個欄位做為關鍵值(不可重複),
如果想要讓增加會員的相關資料內容,就可以在系統設定欄位
step2-6

(4)建立電子報(Create Lists)
建議在建立電子報之前,先建立另一個管理員帳號(一般就設定組織的中文名,例:甲乙丙有限公司)
然後在接下來建立電子報時,可以讓所屬的管理員改為這個新增的管理員帳號
從首頁(Main Page)->設定(Setup)->建立電子報(Create Lists)
點擊新增電子報(add a list)後填入
電子報名稱:例如,最新產品報你知
請鉤選"啟用電子報"(Active)
擁有者:請選你想要的管理者,例如,甲乙丙有限公司


(5)建立訂閱頁面(Create Subscribe Page)

(6)建立新的管理員帳號(Add new Admin)
從首頁(Main Page)->管理者(Admin)->新增管理者(Add new Admin)
設定方法,請參考最開始"修改管理員密碼"

(7)建立電子報會員
從電子報主題(lists)-> 瀏覽會員(view members)->新增使用者:(Add a user:)填入新增帳號的EMAIL

另外會員新增的方法是讓會員自己來新增,例如你發出行鎖的EMAIL,
然後會員從超鏈結來自已加入(要有外部IP),會員從下面連結來登入
注意要提供會員自己訂閱,電子報系統必須有外部IP才能提供

http://主機位置/cab/lists?p=subscribe&email=xxx@gamil.com
如果想要寄發行銷EMAIL時,讓收信人少敲幾個字,就可以加上述紅字部分

會員自己訂閱後,還要回頭去回覆認證信才算完成訂閱
注意,如果會員訂閱不成功,發現是看不出什麼錯誤訊息,
可能原是剛建立系統時管理員的設定不當(例如EMAIL不對)


訂閱的頁面可以在電子報系統自訂,點選右邊選單的訂閱頁面(subscribe page)
進去後,可以依管理員的編排原則,來對每一個不同電子報進行排版

[3]寄發電子報
(1)第1則電子報
登出admin, 重新以新管理員帳號,甲乙丙有限公司登入
從首頁(Main Page)->撰寫電子報(Send a Message)
撰寫電子報內容
填入主旨
在寫訊息內容時,如果要撰入網頁內容時,可以先點"原始碼"(Source)
再填入訊息內容

注意:要發出測試電子報一般都是由管理員發給管理員,
不過如果管理員不在電子報會員清單時,會寄送失敗
要就管理員加入清單,要不就改寄給會員之1
(2)寄出電子報後,可以查詢目前寄送狀況,出狀況也可以查事件記錄(eventlog)



[4]取消訂閱電子報
(1)管理員的作業
從電子報主題(lists)-> 瀏覽會員(view members)->依下圖操作


















(2)會員自己的作業
這個功能必須在電子報系統有外部IP時才能做到
會員在收到電子報EMAIL時,如果下面有超連結可以取消訂閱,可以方便地取消

取消後,會在你的信箱收到回函

在信中也提及,一但取消後,如果想再回頭訂閱,也可以透過網頁來重新訂閱

[5]系統工具使用
(1)關機與重新開機
提供管理員可以遠端操作簡單的系統指令
點選後,隨即會發現系統無法連線了

(2)遠端備份與遠端還原
系統安裝時,如果有指定FTP的相關設定(StoreXXX=),則在安裝後,這個功能會開放使用
系統並會每天在0:0分時自動備分資料庫內容到FTP SERVER上
所以在系統出現異常無法時,可以重新安裝,把之前有備份的資料庫再復原回來
遠端備分在本機端並不會看到什麼資料,因為檔案已經在FTP SERVER上了
遠端還原執行後,可以看到Recovery Folder會出現檔案,執行遠端還原時
要填入一個數字,就是備份在FTP SERVER上的資料是星期幾的檔案
如果填如3,那就是要還原星期3的備份檔

(3)備份與還原
這個備份與還原是系統預設的功能,在系統上建立一個Backup Folder來存放本地端的備份檔
而要還原時,可以看備份檔的主檔名來還原
這個備分與還原功能,管理者可以隨時使用,多數可能原因為,可能要進行系統的測試
備份要執行時,管理者要填入主檔名,按下"Backup"鍵後,
在Backup Folder可以看到.sql及.tar.gz檔出現,這個就是備份檔
還原要執行時,管理者也只要填入主檔名就可以了,按下"Recovery"鍵,系統便完成還原
注意,還原時不需要填入.sql或.tar.gz





[Q&A]
1.寄發電子報時,怎麼不能選管理員來寄發電子報?
管理員要寄發電子報時,管理員要先登入,如果你發現不能寄發正確的電子報主題時
應該沒有登入正確的管理員

2.電子報撰寫時,可否直接上傳圖片?如果有圖片,建議作法為何
目前沒有發現可以直接上傳,有個方法是可以先把你要宣傳的網頁PO在網站上
然後用HTML的方法寄發出去給會員,而圖片部分要注意,網頁上的圖片連線網址要完整
例如:
<img src="/images/test.jpg" />
<img src="http://主機位置/images/test.jpg />
上面的第1行就無法被正確顯示,第2行才可以

3.信件寄發不完整時,怎麼知道
管理員可以在點選處理退信(process bounces)及瀏覽退信(view bounces)
裡頭可以看出寄發的一些退信狀況
一般在事件記錄(eventlog)也可以看到一些資訊

4.我在管理員頁面上看到亂碼
先看看你是不是切換語系統,看中文時,請選"Traditional Chinese"



5.我在drop database後,再create database,回到phplist重新初始化資料庫後
新增的中文都變亂碼
這個是因為這樣的重新初始化的資料庫會變成"latin1_swedish_ci",
而WEB PAGE要看到的應該是"utf8_general_ci"

還沒調整字元前show variables like "%character%"
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+


修改my.cnf如下
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
default-character-set=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

最後show variables like "%character%"
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

文章分類