Missing Sphinx debug package – building from source
Sphinx-lə əlaqədar olan ilk yazımızda Sphinx crash zamanı core dump-ı ala bilməməkdən danışmışdıq(bax. abrtd: Package ‘sphinx’ isn’t signed with proper key)
Core Dump aldıqdan sonra, GDB ilə debug etməyə çalışdıqda:
[root@xxxx ccpp-2014-12-10-21:53:04-8871]# gdb /usr/bin/searchd coredump GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6) This GDB was configured as "x86_64-redhat-linux-gnu". Reading symbols from /usr/bin/searchd...(no debugging symbols found)...done. [New Thread 8871] [New Thread 8874] [New Thread 8877] [New Thread 8878] [New Thread 8873] [New Thread 8875] [New Thread 8876] Core was generated by `/usr/bin/searchd --config /etc/sphinx/sphinx.conf'. Program terminated with signal 11, Segmentation fault. #0 0x00000000004c790d in CheckFlush() () Missing separate debuginfos, use: debuginfo-install sphinx-2.1.8-1.rhel6.x86_64 (gdb) bt #0 0x00000000004c790d in CheckFlush() () #1 0x000000000050c61f in TickHead(bool) () #2 0x000000000050ed16 in ServiceMain(int, char**) () #3 0x000000000050ffad in main () (gdb) bt full #0 0x00000000004c790d in CheckFlush() () No symbol table info available. #1 0x000000000050c61f in TickHead(bool) () No symbol table info available. #2 0x000000000050ed16 in ServiceMain(int, char**) () No symbol table info available. #3 0x000000000050ffad in main () No symbol table info available.
Bəzi debug paketləri yoxdur – Missing separate debuginfos, use: debuginfo-install sphinx-2.1.8-1.rhel6.x86_64.
Nəzərə alsaq ki, Sphinx 2.1.8 debug paketi repo-larda da yoxdur, o zaman bu paketi özümüz build etməli olacıq. Məqsədimiz coredump-ı daha düzgün şəkildə debug edə bilməmizdi.
Yeni yaratdığımız rpm-lərlə əvvəlkini əvəzləyəcik(replace) və eyni crash baş verdikdən sonra yeni coredump-la araşdırmamızı davam etdirəcik.
Source-dan özümüz debuginfo paketinin rpm-ini yaradaq və bunu install edək.
Bu məqsədlə lazımı paketləri yazaq:
[root@xxxx ~]# yum install rpm-build rpmdevtools
Sphinx builder user-ini tələb edir bu user-i yaradaq:
[root@xxxx ~]# adduser builder [root@xxxx builder]# su - builder
Source faylımızı download edək:
[builder@xxxx ~]$ wget http://sphinxsearch.com/files/sphinx-2.1.8-1.rhel6.src.rpm [builder@xxxx ~]$ ls sphinx-2.1.8-1.rhel6.src.rpm
Source faylı install edək:
[builder@xxxx ~]$ rpmdev-setuptree [builder@xxxx ~]$ ls rpmbuild sphinx-2.1.8-1.rhel6.src.rpm [builder@xxxx ~]$ rpm -ivh sphinx-2.1.8-1.rhel6.src.rpm 1:sphinx ########################################### [100%]
Əgər diqqət etsək .spec faylının yarandığını görərik:
[builder@xxxx rpmbuild]$ ls BUILD RPMS SOURCES SPECS SRPMS [builder@xxxx rpmbuild]$ ls SPECS/ sphinx_rel21.spec
Spec faylından istifadə etməklə rpm-lərimizi yaratmağa çalışaq:
[builder@xxxx rpmbuild]$ rpmbuild -ba SPECS/sphinx_rel21.spec error: Failed build dependencies: mysql-devel is needed by sphinx-2.1.8-1.el6.x86_64 postgresql-devel is needed by sphinx-2.1.8-1.el6.x86_64 expat-devel is needed by sphinx-2.1.8-1.el6.x86_64
Aydın olur ki, mysql-devel , postgresql-devel, expat-devel paketlərini yazmalıyıq.
Nəzərə alsaq ki, bizim Sphinx-imiz MySQL ilə çalışır və postgresql-devel paketi postgresql tələb edir. postgresql bizə lazım olmadığı üçün onu dependency requirement-dən çıxarmaq lazımdır. Bu məqsədlə sphinx_rel21.spec faylında postgresql-devel paketini comment-ləmək lazımdır:
#BuildRequires: postgresql-devel
Bir daha yuxarıdakı komandanı run etsək:
[builder@xxxx rpmbuild]$ rpmbuild -ba SPECS/sphinx_rel21.spec error: Failed build dependencies: mysql-devel is needed by sphinx-2.1.8-1.el6.x86_64 expat-devel is needed by sphinx-2.1.8-1.el6.x86_64
yum install mysql-devel expat-devel – bu dependency problemimiz həll edəcək.
Daha sonra bir daha eyni komandanı işlədək, lakin bir dəyişiklik etmək lazımdır.
Məntiqlə düşündükdə biz, PostgreSQL paketlərini dependency kimi çıxartdıq, lakin configure zamanı bunu göstərməliyik ki, source-dan compile etdikdə PostgreSQL paketlərinə müraciət etməsin.
Yenidən biz .spec faylımızı açırıq orada %build kataloqu altında %configure axtarırıq.
%configure –sysconfdir=/etc/sphinx –with-mysql –with-re2 –with-libstemmer –with-unixodbc –with-iconv –enable-id64 –with-pgsql –with-syslog
Gördüyümüz kimi, –with-pgsql opsiyasını –without-pgsql olaraq dəyişirik. Həmçinin, –enable-debug əlavə edirik.
%build kataloqundan yuxarıda isə %debug_package əlavə edirik.(bu debug paketinin yaradılması üçün lazımdır). .spec faylı save edirik.
Həmçinin bildiyiniz kimi, build və make əməliyyatları üçün aşağıdakı paketlərə də ehtiyac var:
yum install gcc gcc-g++ make cpp
Bütün addımları etdikdən sonra RPM paketlərimizi yaradaq:
[builder@xxxx rpmbuild]$ rpmbuild -ba SPECS/sphinx_rel21.spec . . . Wrote: /home/builder/rpmbuild/SRPMS/sphinx-2.1.8-1.el6.src.rpm Wrote: /home/builder/rpmbuild/RPMS/x86_64/sphinx-2.1.8-1.el6.x86_64.rpm Wrote: /home/builder/rpmbuild/RPMS/x86_64/sphinx-testing-2.1.8-1.el6.x86_64.rpm Wrote: /home/builder/rpmbuild/RPMS/x86_64/sphinx-debug-2.1.8-1.el6.x86_64.rpm
Əməliyyatlar uğurla nəticələnsə RPMS folderində aşağıdakı fayllar olacaq:
[builder@xxxx rpmbuild]$ ls -l RPMS/x86_64/ total 36924 -rw-rw-r-- 1 builder builder 7666291 Dec 11 13:35 sphinx-2.1.8-1.el6.x86_64.rpm -rw-rw-r-- 1 builder builder 28716729 Dec 11 13:35 sphinx-debug-2.1.8-1.el6.x86_64.rpm -rw-rw-r-- 1 builder builder 1422134 Dec 11 13:35 sphinx-testing-2.1.8-1.el6.x86_64.rpm
Gördüyümüz kimi hem sphinx həm də sphinx-debug paketlərini əldə etmiş olduq.
Mövcud Sphinx paketini yenisi ilə əvəz etdikdən və debug paketi install etdikdən sonra, yeni crash-dən sonra yazının əvvəlindəki kimi faydasız GDB analizi yox full analiz etmək mümkün olur:
[root@xxxx ccpp-2014-12-11-14:30:45-59208]# gdb /usr/bin/searchd coredump Reading symbols from /usr/bin/searchd...Reading symbols from /usr/lib/debug/usr/bin/searchd.debug...done. done. [New Thread 59208] [New Thread 59209] [New Thread 59211] [New Thread 59210] [New Thread 59213] [New Thread 59214] [New Thread 59212] Core was generated by `/usr/bin/searchd --config /etc/sphinx/sphinx.conf'. Program terminated with signal 11, Segmentation fault. #0 0x0000000000420c12 in CheckFlush () at searchd.cpp:18828 18828 if ( g_pFlush->m_bFlushing ) (gdb) bt #0 0x0000000000420c12 in CheckFlush () at searchd.cpp:18828 #1 0x000000000046731a in TickHead (bDontListen=false) at searchd.cpp:19825 #2 0x0000000000468cee in ServiceMain (argc=985764272, argv=<value optimized out>) at searchd.cpp:21072 #3 0x000000000046a621 in main (argc=3, argv=0x7fff3ac1a718) at searchd.cpp:21143 (gdb) bt full #0 0x0000000000420c12 in CheckFlush () at searchd.cpp:18828 bDirty = <value optimized out> #1 0x000000000046731a in TickHead (bDontListen=false) at searchd.cpp:19825 iClientSock = <value optimized out> sClientName = "85.132.89.226:35563\000\000" pListener = <value optimized out> #2 0x0000000000468cee in ServiceMain (argc=985764272, argv=<value optimized out>) at searchd.cpp:21072 iBacklog = 5 tQueryTLS = {m_tQuery = {m_pQuery = 0x0, m_iSize = 0, m_uCMD = 0, m_uVer = 0, m_bMySQL = false}, static m_tForkQuery = {m_pQuery = 0x7f75ff26ddc5 "", m_iSize = 202, m_uCMD = 0, m_uVer = 279, m_bMySQL = false}, static m_tLastQueryTLS = 6} bOptStatus = <value optimized out> iOptPort = <value optimized out> uReplayFlags = <value optimized out> hConf = @0x9b27a0 bOptStop = <value optimized out> bWatched = 176 tListener = {m_iSock = 985769744, m_eProto = PROTO_SPHINX} sArenaError = <value optimized out> pAcceptMutex = 0x0 bOptPort = <value optimized out> hIndexes = {<CSphOrderedHash<CSphIndex*, CSphString, CSphStrHashFunc, 256>> = {m_dHash = { 0x0 <repeats 33 times>, 0x2119ad0, 0x0 <repeats 31 times>, 0x2119cb0, 0x0, 0x0, 0x0, 0x0, 0x2119d70, 0x0 <repeats 17 times>, 0x2119b30, 0x0 <repeats 20 times>, 0x2119bf0, 0x0 <repeats 13 times>, 0x2119a10, 0x0 <repeats 46 times>, 0x2119a70, 0x0 <repeats 35 times>, 0x2119b90, 0x0, 0x2119dd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2119d10, 0x0 <repeats 35 times>, 0x2119c50, 0x0, 0x0, 0x0, 0x0}, m_pFirstByOrder = 0x2119a10, m_pLastByOrder = 0x2119dd0, m_iLength = 11, m_pIterator = 0x0}, <No data fields>} bOptStopWait = <value optimized out> i = <value optimized out> hSearchdpre = <value optimized out> bVisualLoad = false conf = {<CSphOrderedHash<SmallStringHash_T<CSphConfigSection>, CSphString, CSphStrHashFunc, 256>> = { m_dHash = {0x0 <repeats 256 times>}, m_pFirstByOrder = 0x0, m_pLastByOrder = 0x0, m_iLength = 0, m_pIterator = 0x0}, <No data fields>} ---Type <return> to continue, or q <return> to quit--- bOptPIDFile = 208 dOptIndexes = {m_iLength = 0, m_iLimit = 0, m_pData = 0x0} sOptListen = {_vptr.CSphString = 0x98b190, m_sValue = 0x0, static SAFETY_GAP = 4} bOptListen = <value optimized out> bTestMode = <value optimized out> iDevNull = 34607408 hSearchd = <value optimized out> #3 0x000000000046a621 in main (argc=3, argv=0x7fff3ac1a718) at searchd.cpp:21143 cTopOfMainStack = 0 '\000'
Artıq müəyyən elədik ki, crash səbəbi,
#0 0x0000000000420c12 in CheckFlush () at searchd.cpp:18828
18828 if ( g_pFlush->m_bFlushing )
searchd.cpp adlı faylın 18828 -ci sətrindəki if statement-dir.
Həmçinin görürük ki,
#0 0x0000000000420c12 in CheckFlush () at searchd.cpp:18828
bDirty =
bDirty – Dirty İndex-i təyin edən boolean dəyişəndir və.s şəkildə source kodu araşdırmaqla kod məntiqini başa düşmək lazımdır.
Daha sonra da, crash səbəbini müəyyən etmək olar, hətta bu əgər BUG-dırsa BUG report edə bilərsiniz.
Crash hər hansı üsulla həll edilsə, onun həlli haqqında da ayrıca danışacıq.
Təşəkkürlər.