|
|
|
|
|
|
das
ultimative Installationsmanual |
Beim Installieren und benutzen von Midgard können diverse
Probleme auftauchen. Es gibt mehrere Möglichkeiten diesen
Problemen zu begegnen:
- Auswerten der Logfiles von Midgard
- Das Debuggen von Apache und mod_midgard
- Das Debuggen des PHP-Codes von Midgard
über Log-Files und gezieltem Setzen von Debug-Ausgaben
im Code
Logfiles werden nur ausgegeben wenn statt mod_midgard mod_preparse
installiert wird. Dieses lässt sich von midgard-project.org
downloaden und dann genau so wie mod_midgard installieren. Danach
kann man in der Datei /etc/httpd/conf/midgard-data.conf
folgende Zeilen hinzufügen:
(ausserhalb des VirtualHost)
MidgardLog Debug+ /var/log/midgard.log |
(innerhalb des VirtualHost)
Zusätzlich kann man die Debug-Ausgaben für PHP erhöhen
und in ein Log-File leiten indem man in /etc/php.ini die Zeilen
ändert:
error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /var/log/php_error.log |
Diese Einstellungen sollte man nach dem Debuggen auf Production-Servern
wieder ausstellen.
Um Apache zu debuggen habe ich lange im Internet gesucht und
folgende Alternativen gefunden:
- |
gdb |
|
Der Standard-Debugger unter Linux. Ein sehr schlecht
bedienbares aber relativ stabiles Console-Tool das als
Grundlage für viele Debuggeraufsätze dient.
Leider scheint es unter Linux KEINEN weiteren Console-Debugger
zu geben der vielleicht zudem ein bisschen bedienungsfreundlich
wäre. Zwar gibt es eine C/C++ Umgebung für die
Console (SetEdit),
die vielversprechend aussieht, aber die kann sich nicht
zu einem fertigen Programm attachen. |
|
|
- |
DDD (Data Display Debugger) |
|
Der Data
Display Debugger ist ein Aufsatz über den Linux-Standard-Debugger
gdb. Er ist unter den Linux-Anhängern wohl sehr verbreitet
und deutlich bedienbarer als der gdb. |
|
|
|
|
- |
TotalView 5 (kommerziell) |
|
TotalView
5 von Etnus ist ein kommerzieller Debugger. |
|
|
|
|
- |
Insight 5.2 |
|
Insight
5.2 ist kein Aufsatz auf gdb wie DDD sondern compiliert
die Sources des gdb in sich hinein. Dadurch ist Insight
spürbar schneller als DDD und benutzbarer wie ich
finde... Wer sich wundert wohin das Executable verschwindet
nachdem Insight compiliert wurde: Es nennt sich ebenfalls
'gdb' und lag bei mir in: /usr/local/bin/ |
|
|
Alle
Debugger sind entweder frei, oder es gibt eine kostenlose
Trial-Version im Internet.
Alle Debugger sind auch mal abgestürzt, haben Breakpoints
fehlinterpretiert und kamen mit der komplett DSO-Variante
des Apache überhaupt nicht zurecht. Also probiert es
bitte gleich mit der statisch kompilierten Variante.
Debug Code in Apache und seine Module zu bringen erweist sich
als schwerer als zunächst vermutet.
Zunächst muss der Apache als statisch konfiguriert werden:
./configure \
--enable-module=so \
--server-uid=apache \
--server-gid=apache \
--enable-rule=WANTHSREGEX \
--prefix=/etc/httpd \
--sysconfdir=/etc/httpd/conf \
--iconsdir=/var/www/icons \
--htdocsdir=/var/www/html \
--logfiledir=/var/log/httpd \
--cgidir=/var/www/cgi-bin \
--libexecdir=/usr/lib/apache/modules \
--bindir=/usr/bin \
--includedir=/usr/include/apache \
--mandir=/usr/share/doc \
--sbindir=/usr/sbin |
"configure" erzeugt nicht nur das Makefile, sondern
auch eine Datei src/Configuration.apaci .
In dieser muss folgende Zeile verändert werden:
EXTRA_CFLAGS= `$(SRCDIR)/apaci` -g |
Im
diesem Verzeichniss src
führen wir dann die Befehle aus:
wieder
zurück im Apache-Verzeichniss ändern wir die Makefile-Datei
und verhindern mit der Änderung der Zeile
IFLAGS_PROGRAM = -m 755 -s |
in
das die neu erzeugten Debug-Symbole wieder verschwinden. Ein
installiert nun Apache mit Debugsymbolen.
Wenn PHP und/oder mod_midgard oder mod_preparse statisch in
Apache eincompiliert werden müssen, dann muss zuerst
Apache mimimalistisch konfiguriert worden sein, z.B. mit:
./configure \
--enable-module=so \
--server-uid=apache \
--server-gid=apache \
--enable-rule=WANTHSREGEX \
--prefix=/etc/httpd \
--sysconfdir=/etc/httpd/conf \
--iconsdir=/var/www/icons \
--htdocsdir=/var/www/html \
--logfiledir=/var/log/httpd \
--cgidir=/var/www/cgi-bin \
--libexecdir=/usr/lib/apache/modules \
--bindir=/usr/bin \
--includedir=/usr/include/apache \
--mandir=/usr/share/doc \
--sbindir=/usr/sbin |
dann müssen die entsprechenden Module vorher jeweils
mit dem
--with-apache=<dein_Pfad_zum_Apache_Source> |
statt dem
--with-apxs=/usr/sbin/apxs |
Flag konfiguriert werden, danach ist Apache wie folgt zu konfigurieren:
./configure \
--enable-module=so \
--add-module=<Dein_Pfad_zum_mod_midgard_Source>/mod_midgard.c \
--enable-module=midgard \
--activate-module=<Dein_Pfad_zum_PHP4_source-lib-Verzeichiss>/libphp4.a \
--server-uid=apache \
--server-gid=apache \
--enable-rule=WANTHSREGEX \
--prefix=/etc/httpd \
--sysconfdir=/etc/httpd/conf \
--iconsdir=/var/www/icons \
--htdocsdir=/var/www/html \
--logfiledir=/var/log/httpd \
--cgidir=/var/www/cgi-bin \
--libexecdir=/usr/lib/apache/modules \
--bindir=/usr/bin \
--includedir=/usr/include/apache \
--mandir=/usr/share/doc \
--sbindir=/usr/sbin |
(Manchmal
ist es notwendig vorher noch in der Datei src/Configuration.tmpl
die Zeilen
EXTRA_LDFLAGS=-L/var/midgard/lib
EXTRA_INCLUDES=-I/var/midgard/include |
zu
ändern)
Ich würde jedoch zumindest mod_midgard weiterhin als DSO
nachladen, da ich es zwar so kompilieren konnte, aber Apache
sich nicht mehr starten liess...
mod_midgard_preparse ist ein 1:1 mod_midgard-pendant mit dem
Unterschied das Logging integriert ist. Man compiliert und
installiert es wie das Original.
Das Debuggen von Apache funktioniert mit allen Debuggern ähnlich,
deswegen demonstriere ich es hier nur mit dem gdb.Alles was
man wissen muss, ist der Umstand das Apache in form des httpd-Programmes
in /usr/sbin
liegt und mit dem Parameter -X im single-process mode läuft
damit wir einen gezielten Request debuggen können.
Zunächst können wir in der Funktion ap_process_request
einen Breakpoint setzen, da dies die Haupt-Request-Behandlungsfunktion
im apache ist, und danach (nachdem er alle Libs etc geladen
hat) einen Breakpoint auf midgard_translate_handler, das ist
die Hauptfunktion im mod_midgard. In gdb funktioniert das ungefähr
so
(grün sind die Benutzereingaben):
% gdb httpd
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License,
and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty"
for details.
This GDB was configured as "i386-mandrake-linux".
(gdb) b ap_process_request
Breakpoint 1 at 0x49fb4: file http_request.c, line 1164.
(gdb) run -X
Starting program: /usr/local/apache/src/httpd -X
[an diesem Punkt einen Request an Apache von einem anderen Fenster
aus machen]
Breakpoint 1, ap_process_request (r=0x95250) at http_request.c:1164
1164 if (ap_extended_status)
(gdb) s
1165 ap_time_process_request(r->connection->child_num,
START_PREQUEST);
(gdb) n
1167 process_request_internal(r);
(gdb) s
process_request_internal (r=0x95250) at http_request.c:1028
1028 if (!r->proxyreq && r->parsed_uri.path) {
(gdb) s
1029 access_status = ap_unescape_url(r->parsed_uri.path);
(gdb) n
1030 if (access_status) {
(gdb) s
1036 ap_getparents(r->uri); /* OK --- shrinking transformations...
*/
(gdb) n
1038 if ((access_status = location_walk(r))) {
(gdb) n
1043 if ((access_status = ap_translate_name(r))) {
(gdb) n
1048 if (!r->proxyreq) {
(gdb) n
1053 if (r->method_number == M_TRACE) {
(gdb) n
1062 if (r->proto_num > HTTP_VERSION(1,0) && ap_table_get(r->subprocess_env,
"downgrade-1.0")) {
(gdb) n
1071 if ((access_status = directory_walk(r))) {
(gdb) s
directory_walk (r=0x95250) at http_request.c:288
288 core_server_config *sconf = ap_get_module_config(r->server->module_config,
(gdb) b ap_send_error_response
Breakpoint 2 at 0x47dcc: file http_protocol.c, line 2090.
(gdb) c
Continuing.
Breakpoint 2, ap_send_error_response (r=0x95250, recursive_error=0)
at http_protocol.c:2090
2090 BUFF *fd = r->connection->client;
(gdb) where
#0 ap_send_error_response (r=0x95250, recursive_error=0) at
http_protocol.c:2090
#1 0x49b10 in ap_die (type=403, r=0x95250) at http_request.c:989
#2 0x49b60 in decl_die (status=403, phase=0x62db8 "check access",
r=0x95250) at http_request.c:1000
#3 0x49f68 in process_request_internal (r=0x95250) at http_request.c:1141
#4 0x49fe0 in ap_process_request (r=0x95250) at http_request.c:1167
#5 0x439d8 in child_main (child_num_arg=550608) at http_main.c:3826
#6 0x43b5c in make_child (s=0x7c3e8, slot=0, now=907958743)
at http_main.c:3898
#7 0x43ca8 in startup_children (number_to_start=6) at http_main.c:3972
#8 0x44260 in standalone_main (argc=392552, argv=0x75800) at
http_main.c:4250
#9 0x449fc in main (argc=4, argv=0xefffee8c) at http_main.c:4534
(gdb) s
2091 int status = r->status;
(gdb) p status
$1 = 403
(gdb)
Zu dem Thema habe ich hier
eine schöne Graphic gefunden, die es auch im PDF-Format
gibt:
Und nun Fröhliches Debuggen!
Es gibt zwar mittlerweile schöne
Lösungen die es ermöglichen mit übersichtlichen
Remote-Debuggern komfortabel durch den Code zu laufen, aber
da Midgard viel von nativem Code gebrauch macht (der seinerseits
wieder PHP aufruft) nützt uns das bei den gängigen
PHP-Debuggern nur etwas für die midgard-root.php, und
die stellt meistens nicht das Problem dar. Wir sind leider
gezwungen eine weit weniger komfortable Möglichkeit zu
nutzen - wir müssen den vermeindlich absturzgefährdeten
durch Debug-Ausgaben finden. Dazu könnt Ihr wie oben
beschrieben in /etc/php.ini
die Debug-Ausgaben von PHP in eine log-datei leiten, sie mit
tail -f <logdatei>
in einem Console-Fenster beobachten und den eigentlichen Code
(z.B. durch Nutzung des /admin/ - Interfaces) mit kleinen
error_log("<sinnvolle
Debugausgabe>" ,
0); - Befehlen spicken.
|
|