Neutron's Blog : OpenSource - Open my mind.

Friday, May 11, 2007

Wireshark(Ethereal), Segmentation fault!

จำเป็นต้องเร่งใช้.....

พอดีต้อง debug TCP/IP socket จากการที่ต้องทดสอบ Server ที่เขียนขึ้นด้วย C++ ซึ่ง Client ส่งชุดคำสั่งมายัง Server ปรากฏว่า Server ตอบสนองคำสั่ง แต่ไม่ตลอดรอดฝั่ง เกิดอาการลองลอยกลางอากาศ เลยพยายามที่จะตรวจสอบว่าเกิดอะไรขึ้นกับ socket (ตายแล้ว, หรือยังอยู่ดีมีสุข) เกริ่นมาซะยืดยาว สุดท้ายก็นึกถึง Wireshark/Ethereal เป็น Packet Sniffer ที่มีความสามารถยอดเยี่ยมเลยทีเดียว

จัดการ

# aptitude install wireshark wireshark-common
หลังจากนั้นก็สั่งคำสั่งด้วยใจจดจ่อ
$ wireshark
Segmentation fault 
เห็นแล้วเศร้า....

ทำยังไงต่อดี.....

ต้องใช้ความรู้ที่มีอยู่น้อยนิด หาสาเหตุการ crash ครั้งนี้

$ gdb wireshark
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
.
.
Using host libthread_db library "/lib/i686/cmov/libthread_db.so.1".

(gdb) run
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1242670896 (LWP 1542)]
0xb4e710e3 in sb_trie_root () from /usr/lib/libdatrie.so.0
อ้าว... libdatrie ชื่อคุ้น ๆ ครับผม ไล่ไปไล่มา จริงด้วย คนเขียน พี่เทพ เรานี่เอง เลยลองโทรถามพี่เทพก่อน แต่ได้ข่าวว่าเจ็บตา เลยถามเพื่อความชัวร์ว่า "พี่ดีขึ้นหรือยัง" คำตอบคือ "ดีขึ้น แต่ยังเจ็บอยู่" งั้นผมได้แต่เล่าบอกไว้ แต่ไม่รบกวนครับผม

ลองไล่ดูดีกว่า.....

จากข้อมูลที่ gdb รายงานมาก็ยังไม่เพียงพอที่จะชี้จุดที่มีปัญหา เลยตัดสินใจ re-compile เจ้า libdatrie ใหม่ เพื่อที่จะได้ใช้ gdb หาจุดปัญหาได้สะดวก และไล่ตามแก้ไปเรื่อย ๆ จนสุดท้ายได้เป็น patch ตามนี้

--- libdatrie-0.1.1.orig/datrie/sb-trie.c
+++ libdatrie-0.1.1/datrie/sb-trie.c
@@ -203,6 +203,9 @@
 {
     SBTrieState *sb_state;

+    if (!sb_trie)
+        return NULL;
+
     sb_state = (SBTrieState *) malloc (sizeof (SBTrieState));
     if (!sb_state)
         return NULL;
@@ -223,6 +226,9 @@
 {
     SBTrieState *new_state;

+    if (!s)
+        return NULL;
+
     new_state = (SBTrieState *) malloc (sizeof (SBTrieState));
     if (!new_state)
         return NULL;
@@ -249,6 +255,9 @@
 Bool
 sb_trie_state_walk (SBTrieState *s, SBChar c)
 {
+    if (!s)
+        return 0; 
+
     return trie_state_walk (s->trie_state,
                             alpha_map_char_to_alphabet (s->sb_trie->alpha_map,
                                                         (UniChar) c));
และก็ลอง wireshark ใหม่ ตอนนี้เข้าได้แล้วครับผม :)

ปล. ส่ง patch ไปให้พี่เทพแล้ว รอการตอบครับผม :P