Debug di MariaDB con mysql-test-run
Controllare che MariaDB sia compilato con il debug
Si esegua:
mysqld --debug --help
Se si ottiene un errore 'unknown option '--debug', MariaDB non è compilato con il debug e il trace.
Compilare MariaDB per il debug
Per abilitare il tracing, che è di grande aiuto quando si effettua il debug di software complessi, occorre usare configure con l'opzione '--with-debug=full'
.
Se si desidera usare valgrind, un buono strumento per la memory instrumentation e per trovare i sovraccarichi di memoria, si usi:
configure --with-debug --with-valgrind.
Per le configurazioni più comuni esiste uno script nella directory BUILD.
Alcuni script raccomandati per Intel/AMD sono:
BUILD/compile-pentium64-debug-max BUILD/compile-pentium64-valgrind-max
Usare il framework mysql-test per il debug
Creare un test per mysql-test
Il framework mysql-test si trova nella directory mysql-test. In essa si trova un file README che spiega come aggiungere nuovi test.
I test principali sono nella directory 't' e i file dei risultati corrispondenti sono nella directory 'r'.
Segue una breve spiegazione su come aggiungere test e debuggare MariaDB con la test suite. La suite t/alias.test costituirà la base per i nuovi test. Attenzione: occorre compilare MariaDB, prima di poter eseguire i test.
cp t/alias.test t/new.test xemacs t/new.test # Modifica il test. Va bene anche usare 'vim' :) ./mysql-test-run --record t/new.test
L'ultima riga esegue il test e registra il risultato in 'r/new.result'. Per eseguire nuovi test è meglio usare l'opzione --record.
Nel caso in cui si debbano modifiche cambiamenti nel server MariaDB e il risultato dei test cambi, occorre esaminare l'output dei test per vedere se il nuovo risultato è corretto. Si può anche eseguire un diff tra i file originali e quelli nuovi in questo modo:
diff r/new.result r/new.reject
Quando si è certi che il nuovo codice sia corretto, si può sostituire il risultato in questo modo:
mv r/new.result r/new.reject or mv r/new.re*
Per ottenere una lista completa delle opzioni di mysql-test-run:
./mysql-test-run --help
Debuggare un test che fallisce o va in crash
La directory var/log contiene i log di mysqltest, mysqld e altre parti della test suite; essi possono aiutare a risolvere il problema.
Se non sono d'aiuto,uno dei seguenti metodi dovrebbe aiutare a capire dov'è l'errore:
Usare tracing di debug
Eseguire la test suite con l'opzione --debug genera un file di trace var/log/mysqld.1.trace o var/log/mysqld.2.trace. (Il secondo file è per lo slave se si vuole eseguire un test che usa una configurazione master/slave).
mysql-test-run --debug t/new.test
Un trace è molto utile per capire a che punto si è arrestato mysqld e cosa ha fatto prima di arrestarsi.
E' anche utile per scoprire che cosa è cambiato tra due diverse istanze di MariaDB (ad esempio dopo aver aggiunto nuove funzionalità che ne modificano il funzionamento).
In questo caso, si può generare un file di --debug con il vecchio server e uno con il nuovo, e compararli laddove si verifica un problema per scoprire in che modo si comportano diversamente.
Siccome i file di log contengono riferimenti di memoria, a volte è difficile compararli. Ecco un piccolo script in perl che modifica gli indirizzi di memoria in '#' per facilitare il confronto:
#!/usr/bin/perl -i while (<>) { s/^T@[0-9]+://g; s/0x[0-9a-f]+(\s|\n|\))/#$1/g; # s/[0-9a-f]{5,}/#/g; s/size: [0-9]+/size: #/g; print $_; }
Si può salvarlo come 'convert-debug-for-diff' ed eseguirlo sui file di trace prima di confrontarli. Lo script sopra è presente nelle recenti versioni di MariaDB nella directory scripts/convert-debug-for-diff.
Per rendere i file trace più piccoli, si può eseguire la test suite così:
mysql-test-run --mysqld=--debug=d,info,error,query,general,where:O,/tmp/mysqld.trace new.test
In questo modo essi non conterranno il tracing delle funzioni e verranno scritti soltanto i tag DBUG_PRINT selezionati. Il file di trace in questo caso verrà scritto in /tmp/mysqld.trace.
Un'altra strina di debug comune, che genera qualche informazione in più:
-mysqld=--debug=d:t:i:-f,mysql_select/,open_tables/,close_thread_tables/,\ log_general/,find_block/,make_lock_and_pin/,reg_requests/,unreg_request/,\ fix_paths/,translog_write_variable_record/:O,/tmp/mysqld.trace
L'opzione -f disabilita il logging delle funzioni indicate. I nomi di funzione che finiscono con / indicano anche tutte le funzioni che vengono chiamate da quella specificata.
Si veda il file dbug/dbug.t per la documentazione completa delle opzioni di debug. Si può trovare il sorgente in dbug/dbug.c
Eseguire un test case su un server in funzione
Se si vuole eseguire un test case su un server che è in esecuzione, per esempio esseguendo mysqld in un debugger, si può usare l'opzione --extern:
./mysql-test-run --extern socket=/tmp/mysql.sock t/new.test o mysql-test-run --extern "socket=/tmp/mysql.sock" --extern user=anna --extern password=guesswhat t/new.test
Eseguire i test con gdb / ddd
./mysql-test-run --gdb t/new.test ./mysql-test-run --ddd t/new.test