Entwickler-Ecke

Sonstiges (Delphi) - Plötzlich auftretender Fehler in Anwendung


juppinger - Mi 29.10.08 17:29
Titel: Plötzlich auftretender Fehler in Anwendung
Hallo zusammen,

ich weiss langsam nicht mehr, was ich machen soll...
Ich habe eine Anwendung geschrieben, welche schon seit ca. 4 Jahren bei vielen Personen im Einsatz ist - auf unterschiedlichsten Systemen (geschrieben in Delphi 4).
Die Software wird auch ständig weiter entwickelt und aktualisiert.
In der Applikation ist es möglich verschiedene Reports zu drucken.
Seit einiger Zeit kommt bei einigen Personen bei bestimmten Druckreports (QuickReport) bevor der Report aufgeht (QuickRep1.Preview) eine Exception. Beispiel: Zugriffsverletzung bei Adresse 00000000.
Wenn ich mir das Programm komplett gepackt per E-Mail senden lassen und es auf meinem PC und allen anderen PCs, die ich finden kann, teste, funktioniert alles einwandfrei und keine Exception wird ausgelöst.

Ich weiss nicht mehr, was ich tun könnte.
>> Hat jemand einen Tipp?

Thx,
jupinger

P.S.: Kennt jemand eine Komponente für D4, welche optional aktiviert werden kann und in einer fertig compilierten EXE "mit läuft" und jegliche Aktion der Applikation debuggt und z.B. in eine TXT schreibt?


Delete - Mi 29.10.08 17:40

Die Meldung "Zugriffsverletzung bei Adresse 00000000" deutet daraufhin, dass auf nicht instanziierte Objekt zugegriffen wird. Und zum Auffinden der Fehlerursache könntest Du Dir mal madExcept [http://madshi.net] ansehen.


juppinger - Mi 29.10.08 18:12

Was genau bedeutet das und warum ist das nur auf wenigen PCs so der Fall?
Was kann ich nun tun?


Gausi - Mi 29.10.08 18:14

Sind irgendwo Threads im Einsatz?


Delete - Mi 29.10.08 18:14

Wie gesagt, madExcept oder etwas Ähnliches einsetzen, um die Fehlerstelle eingrenzen zu können. Die muss man sich dann halt einmal ansehen.


juppinger - Mi 29.10.08 18:20

Nein - keine Threads im Einsatz.


Xentar - Mi 29.10.08 20:17

Wenn du schon versuchst, den Fehelr bei dir nachzustellen, solltest du möglichst die gleichen Ausgangsbedingungen schaffen.
Soll heißen:
- Verwendest du in der Software irgendwelche Datenbanken, oder sonst irgendwelche Datenquellen? Wenn ja, lass dir diese auch zuschicken, damit du mit den gleichen Daten arbeitest
- Versuch es auf dem gleichen Betriebssystem

usw.


juppinger - Do 30.10.08 17:11

Hi,
genau das ist ja das interessante: Ich lasse mir das komplette Verzeichnis schicken (mit allen Datendateien usw). - Bei mir tritt der Fehler nicht auf - auch bei gleichen Betriebssystem.


hazard999 - Do 30.10.08 17:19

madexcept ist die Lösung.

Damit findest den Fehler innerhalb von 10 min.


juppinger - Do 30.10.08 18:46

okay... *PAUSE* an dieser Stelle. Werde mal madExcepten. Ggf. müsstet Ihr mir dann nochmal bei der Auswertung behilflich sein ;)
Bis hier erst einmal 1000-Dank für den schnellen Support. Ich melde mich die nächsten Tage mit dem Ergebnis.


BenBE - Do 30.10.08 22:16

Alternativ kann man auch EurekaLog oder das Omorphia Debugging Interface nutzen - letzteres bedarf aber etwas Einarbeitung, erlaubt dafür aber auch externe Auswertung von Pointern mit Hilfe von OmMAP (wenn zu der eingesetzten Programmversion ein detailliertes Mapfile verfügbar ist).

Für die Auswertung solltest Du einmal die geladenen Module (DLLs), sowie die vollständigen Stacktraces senden; solche Fehler sind nicht immer genau an derAufruf-Position). Näheres schauen wir aber, wenn Du soweit die Daten hast.


juppinger - Di 04.11.08 00:08

Hi zusammen. Hier mal ein Log... soweit bis die Exception Auftritt (von unten nach oben):


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
EXCEPTION:
=================

exception class   : EAccessViolation
exception message : Zugriffsverletzung bei Adresse 00000000. Schreiben von Adresse 00000000.
=================


main thread ($83c):
???
TObject.Free
TQRPrinter.EndMetafileCanvas
TQRPrinter.EndDoc
TCustomQuickRep.CreateReport
@HandleFinally
RtlRaiseStatus
RtlUnwind
@HandleAnyException
RtlRaiseStatus
KiUserExceptionDispatcher
TStream.WriteBuffer
TMetafile.WriteEMFStream
TMetafile.SaveToStream
TQRPageList.AddPage
TQRPrinter.NewPage
TCustomQuickRep.NewPage
TCustomQuickRep.NewColumn
TQRCustomBand.Print
TCustomQuickRep.PrintBand
TQRController.PrintEmptyController
TQRController.Execute
TQuickRep.Execute
TCustomQuickRep.CreateReport
TCustomQuickRep.Preview
TForm2.BitBtn1Click


Moderiert von user profile iconGausi: Code-Tags hinzugefügt


BenBE - Di 04.11.08 12:34

hmmm, dem Stacktrace zu folge schein irgendetwas mit einer Grafik, die in dem Report verwendet wird, nicht hinzuhauen. Wenn Du mit TD32-Debug-Infos compilierst und Debug-DCUs einschaltest, dann sollten da sogar Zeilennummen mit vorhanden sein.

Schau also einmal, ob die von Dir im Report verwendeten Referenzen alle OK sind und da alles stimmt.


juppinger - Mi 05.11.08 22:44

Was sind "TD32-Debug-Infos"?^^
sry,
jup


BenBE - Do 06.11.08 00:30

TD32- ist ein Format, in dem in eine EXE die Informationen über Units, Zeilennummern, Quelldateien usw. eingebettet wird. Viele externe Debugger benötigen diese Informationen. Können in den Projekt-Optionen aktiviert werden.


juppinger - Do 06.11.08 13:13

Ah okay... Kannst Du mir sagen, wo genau dies Aktiviert wird?

Thx,
jup


Xentar - Do 06.11.08 13:17

Hast du die Projektoptionen schon durchgeguckt?
Das Häckchen heißt auch noch genau so!


juppinger - Do 06.11.08 15:02

OKay. Ich werde mir die Optionen heute Abend genauer anschauen. Wird dann in madExcept mehr Infos (Zeilennr. usw)? Das Problem ist wie bereits gesagt: bei mir klappt alles einwandfrei auf versch. PCs. Bei anderen Usern (habe keine Möglichkeit die zu besuchen), klappt es eben nicht.

Hier noch ein Report-Auszug:

============================
exception class : EFCreateError
exception message : Datei ðñ kann nicht erstellt werden.
============================


main thread ($388):
0045e4ee +072 Classes TFileStream.Create
00501d5a +066 <PROGRAMMNAME>.exe QRPrntr TQRStream.Write
0045e2cf +02f <PROGRAMMNAME>.exe Classes TStream.WriteBuffer
00469c68 +058 <PROGRAMMNAME>.exe Graphics TMetafile.WriteEMFStream
004698a4 +00c <PROGRAMMNAME>.exe Graphics TMetafile.SaveToStream
00502855 +10d <PROGRAMMNAME>.exe QRPrntr TQRPageList.AddPage
0050484a +042 <PROGRAMMNAME>.exe QRPrntr TQRPrinter.EndDoc
0051b8ca +4e2 <PROGRAMMNAME>.exe QuickRpt TCustomQuickRep.CreateReport
0051bd81 +091 <PROGRAMMNAME>.exe QuickRpt TCustomQuickRep.Preview
0053a73c +378 <PROGRAMMNAME>.exe Unit20 132 +67 TForm20.ReportDruckenKonten
0053af89 +1f1 <PROGRAMMNAME>.exe Unit20 259 +48 TForm20.BitBtn1Click
0047f326 +066 <PROGRAMMNAME>.exe Controls TControl.Click
00477120 +01c <PROGRAMMNAME>.exe StdCtrls TButton.Click
004afdb5 +065 <PROGRAMMNAME>.exe Buttons TBitBtn.Click
00477214 +00c <PROGRAMMNAME>.exe StdCtrls TButton.CNCommand
0047f191 +111 <PROGRAMMNAME>.exe Controls TControl.WndProc
00481942 +1ae <PROGRAMMNAME>.exe Controls TWinControl.WndProc
00477094 +06c <PROGRAMMNAME>.exe StdCtrls TButtonControl.WndProc
0047efc0 +024 <PROGRAMMNAME>.exe Controls TControl.Perform
00481a3f +023 <PROGRAMMNAME>.exe Controls DoControlMsg
00482097 +00b <PROGRAMMNAME>.exe Controls TWinControl.WMCommand
00496664 +02c <PROGRAMMNAME>.exe Forms TCustomForm.WMCommand
0047f191 +111 <PROGRAMMNAME>.exe Controls TControl.WndProc
00481942 +1ae <PROGRAMMNAME>.exe Controls TWinControl.WndProc
00494967 +567 <PROGRAMMNAME>.exe Forms TCustomForm.WndProc
004815f8 +02c <PROGRAMMNAME>.exe Controls TWinControl.MainWndProc
00491d90 +014 <PROGRAMMNAME>.exe Forms StdWndProc
7e36c644 +016 user32.dll CallWindowProcW
5d455fdf +041 comctl32.dll DefSubclassProc
7e36b8ee +044 user32.dll SendMessageW
7e36e8e0 +016 user32.dll CallWindowProcA
004819ec +09c <PROGRAMMNAME>.exe Controls TWinControl.DefaultHandler
0047f72c +010 <PROGRAMMNAME>.exe Controls TControl.WMLButtonUp
0047f191 +111 <PROGRAMMNAME>.exe Controls TControl.WndProc
00481942 +1ae <PROGRAMMNAME>.exe Controls TWinControl.WndProc
00477094 +06c <PROGRAMMNAME>.exe StdCtrls TButtonControl.WndProc
004815f8 +02c <PROGRAMMNAME>.exe Controls TWinControl.MainWndProc
00491d90 +014 <PROGRAMMNAME>.exe Forms StdWndProc
7e3696b2 +00a user32.dll DispatchMessageA
0049a613 +083 <PROGRAMMNAME>.exe Forms TApplication.ProcessMessage
0049a64a +00a <PROGRAMMNAME>.exe Forms TApplication.HandleMessage
0049a855 +081 <PROGRAMMNAME>.exe Forms TApplication.Run
00555e36 +34e <PROGRAMMNAME>.exe Project1 100 +46 initialization


hazard999 - Do 06.11.08 15:26

WTF!

Hast du dir den StackTrace überhaupt angesehen?

Das sind 2 verschiedene Probleme.

Beim letzten würd ich mal auf ein Berechtigungsproblem tippen.


hazard999 - Do 06.11.08 15:29

Und nichts für ungut.

Aber selbst in meinen Demos heißt keine Unit "Unit20"

nur mal so als Denkanstoss...


alzaimar - Do 06.11.08 16:35

user profile iconhazard999 hat folgendes geschrieben Zum zitierten Posting springen:
Aber selbst in meinen Demos heißt keine Unit "Unit20"
Wird nicht viel mit dem Fehler zu tun haben.


juppinger - Do 06.11.08 16:57

Joa - sorry 4 that. Das mit den Unit-Namen ist wirklich unschön.

Leider kann ich mit einem Stack-Trace nicht viel anfangen.

Meinst Du das hier?...

... Zur Info: Ich habe in das Projekt selbst eine kleine Debug-Fuktion eingebaut, welche einfach in eine TXT an bestimmten Stellen im Quellcode schreibt, wo sich das Programm gerade "befindet":
Unit1.TForm1.UPdebug('Unit 25 - bis line 240'); ==>> Schreibt in die TXT den String: 'Unit 25 - bis line 240'.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
cpu registers:
eax = 0268f6a8
ebx = 0269d66c
ecx = 00000000
edx = 0045e4f3
esi = 00c3a074
edi = ffffffff
eip = 0045e4f3
esp = 0012f20c
ebp = 0012f274

stack dump:
0012f20c  f3 e4 45 00 de fa ed 0e - 01 00 00 00 07 00 00 00  ..E.............
0012f21c  20 f2 12 00 f3 e4 45 00 - a8 f6 68 02 6c d6 69 02  ......E...h.l.i.
0012f22c  74 a0 c3 00 ff ff ff ff - 74 f2 12 00 3c f2 12 00  t.......t...<...
0012f23c  48 f2 12 00 18 39 40 00 - 74 f2 12 00 80 f2 12 00  H....9@.t.......
0012f24c  07 3a 40 00 74 f2 12 00 - 6c d6 69 02 00 87 01 00  .:@.t...l.i.....
0012f25c  00 87 01 00 ac f8 68 02 - 00 00 00 00 74 a0 c3 00  ......h.....t...
0012f26c  0b e2 45 00 00 87 01 01 - 9c f2 12 00 5f 1d 50 00  ..E........._.P.
0012f27c  ff ff 00 00 a4 f2 12 00 - 18 39 40 00 9c f2 12 00  .........9@.....
0012f28c  80 f5 12 00 10 13 50 00 - 00 87 01 00 00 00 00 00  ......P.........
0012f29c  c0 f2 12 00 d2 e2 45 00 - c8 f2 12 00 18 39 40 00  ......E......9@.
0012f2ac  c0 f2 12 00 ac f8 68 02 - 90 f7 68 02 00 00 00 00  ......h...h.....
0012f2bc  10 f0 69 02 e4 f2 12 00 - 6d 9c 46 00 f0 f2 12 00  ..i.....m.F.....
0012f2cc  18 39 40 00 e4 f2 12 00 - 90 f7 68 02 98 44 b6 00  .9@.......h..D..
0012f2dc  00 87 01 00 10 f0 69 02 - 20 f3 12 00 a9 98 46 00  ......i.......F.
0012f2ec  58 28 50 00 38 f3 12 00 - 18 39 40 00 20 f3 12 00  X(P.8....9@.....
0012f2fc  80 f5 12 00 68 f8 68 02 - 98 44 b6 00 21 91 46 00  ....h.h..D..!.F.
0012f30c  80 f5 12 00 68 f8 68 02 - 7c 00 00 00 cc 66 b6 00  ....h.h.|....f..
0012f31c  80 00 00 00 2c f3 12 00 - 4f 48 50 00 e0 cc c2 00  ....,...OHP.....
0012f32c  6c f3 12 00 cf b8 51 00 - f7 b8 51 00 80 f3 12 00  l.....Q...Q.....
0012f33c  18 39 40 00 6c f3 12 00 - 98 44 b6 00 c8 f9 c2 00  .9@.l....D......

disassembling:
[...]
0053a725       mov     edx, $53a890           ; 'Unit 20 - bis line 131'
0053a72a       call    +$100e1 ($54a810)      ; Unit1.TForm1.UPdebug
0053a72f 132   mov     eax, [$55c7ec]
0053a734       mov     eax, [eax]
0053a736       mov     eax, [eax+$2c4]
0053a73c     > call    -$1ea51 ($51bcf0)      ; QuickRpt.TCustomQuickRep.Preview
0053a741 133   mov     eax, [$55c9b8]
0053a746       mov     eax, [eax]
0053a748       mov     edx, $53a8b0           ; 'Unit 20 - bis line 133'
0053a74d       call    +$100be ($54a810)      ; Unit1.TForm1.UPdebug
0053a752       xor     eax, eax
[...]

========================ODER=========================


cpu registers:
eax = 0301f5b0
ebx = 0301e464
ecx = 0301f5ac
edx = 0012f301
esi = 00000000
edi = 00000000
eip = 00000000
esp = 0012e8dc
ebp = 0012e8f0

stack dump:
0012e8dc  3f 32 40 00 9f 44 50 00 - 64 e4 01 03 41 48 50 00  ?2@..DP.d...AHP.
0012e8ec  00 00 00 00 84 f3 12 00 - cf b8 51 00 14 39 40 00  ..........Q..9@.
0012e8fc  2c e9 12 00 00 00 00 00 - 00 00 00 00 00 00 00 00  ,...............
0012e90c  bf 37 91 7c 14 ee 12 00 - 44 f3 12 00 24 ea 12 00  .7.|....D...$...
0012e91c  18 ea 12 00 44 f3 12 00 - 04 38 91 7c 44 f3 12 00  ....D....8.|D...
0012e92c  f4 ec 12 00 8b 37 91 7c - 14 ee 12 00 44 f3 12 00  .....7.|....D...
0012e93c  24 ea 12 00 18 ea 12 00 - f0 b8 51 00 01 00 00 00  $.........Q.....
0012e94c  14 ee 12 00 44 f3 12 00 - 48 7b 94 7c 14 ee 12 00  ....D...H{.|....
0012e95c  44 f3 12 00 24 ea 12 00 - 18 ea 12 00 f0 b8 51 00  D...$.........Q.
0012e96c  40 ed 12 00 00 00 00 00 - 00 00 00 00 62 00 73 00  @...........b.s.
0012e97c  70 00 6c 00 61 00 6e 00 - 65 00 72 00 20 00 28 00  p.l.a.n.e.r...(.
0012e98c  77 00 77 00 77 00 2e 00 - 75 00 72 00 6c 00 61 00  w.w.w...u.r.l.a.
0012e99c  75 00 62 00 2d 00 66 00 - 65 00 72 00 69 00 65 00  u.b.-.f.e.r.i.e.
0012e9ac  6e 00 2d 00 70 00 6c 00 - 61 00 6e 00 75 00 6e 00  n.-.p.l.a.n.u.n.
0012e9bc  67 00 2e 00 64 00 65 00 - 29 00 00 00 01 00 00 00  g...d.e.).......
0012e9cc  30 ea 12 00 fc 84 36 7e - e0 cc f8 02 00 00 00 00  0.....6~........
0012e9dc  01 00 00 00 e4 04 00 00 - 00 00 00 00 01 00 00 00  ................
0012e9ec  00 00 00 00 10 0c 21 01 - f8 e9 12 00 30 00 6f 00  ......!.....0.o.
0012e9fc  67 00 65 00 6c 00 f6 00 - 66 00 65 00 72 00 00 00  g.e.l...f.e.r...
0012ea0c  09 00 00 00 80 84 f7 00 - 12 b4 38 7e cd ab ba dc  ..........8~....

disassembling:
[...]
00530d24 240   mov     eax, [$55c9b8]
00530d29       mov     eax, [eax]
00530d2b       mov     edx, $530db8           ; 'Unit 25 - bis line 240'
00530d30       call    +$19adb ($54a810)      ; Unit1.TForm1.UPdebug
00530d35 241   mov     eax, [ebx+$2c4]
00530d3b     > call    -$150d8 ($51bc68)      ; QuickRpt.TCustomQuickRep.Prepare
00530d40 242   mov     eax, [ebx+$2c4]
00530d46       mov     eax, [eax+$294]
00530d4c       mov     [$55f4f0], eax
00530d51 243   push    $530dd8                ; ' von '
00530d56       lea     edx, [ebp-8]
[...]


BenBE - Do 06.11.08 19:36

Das was Du mit den Sachen UPdebug gemacht hast, steht in ähnlicher Form auch im Stacktrace drin. Dort wird einfach die Stelle angegeben, zu der zurückgesprungen wird, wenn man mit einer Subroutine fertig ist. Damit kann man das für einzelnen Routinen recht genau beschreiben, wie man zu der Fehlerstelle hinkommt.

Wichtig ist hierbei aber, dass wie von mir gesagt, die Fehlerstelle nicht zwingend der letzte Eintrag im Call Stack sein muss. Hier hilft es oftmals, einige Variablen wie Referenzen auf Objekte oder Variablen-Inhalte, die als Parameter übergeben werden, auf gewisse Rahmenbedingungen hin überprüft.


juppinger - Fr 07.11.08 17:47

okay. und wie kann ich jetzt weiter vorgehen?


BenBE - Fr 07.11.08 20:25

An den im Stacktrace genannten Stellen Breakpoints setzen und im Einzelschritt durchdebuggen. Delphi bietet u.a. auch einen Remote-Debugger an, den Du für solche Dinge nutzen kannst.


juppinger - Sa 08.11.08 15:23

Bei mir läuft alles einwandfrei und keine Exception wird ausgelöst :-((( Alles Fehlerfrei.
Kann dies ggf. an einem Druckertreiber liegen?
Ich habe jetzt einmal QuickReport von 3.0.3 auf 3.0.5 geupdatet. Könnte das helfen?

Leider finde ich in dem Debug-Menü nur "TD32-Tasten" und kein "TD32-Debug-Infos".

In D4 Standard kann man Remote Debuggen? Gibts da ne HowTo?


juppinger - Sa 05.09.09 22:21

So... nun mal die Antowort für die Ursache und die Lösung zur Behebung des Fehlers:

Mit den nicht so einfach zu bekommenden Delphi-Updates
d4supd2 & d4supd3, ging es dann einwandfrei.

Also Delphi updaten, da wird der quickreport (qreport) auch direkt mit upgedatet.

Problem war:
-------------------------------
Der alte (auf der Delphi4 Original-CD mitgelieferte) QuickReport kommt von Hause aus mit den seit einer Windows-Version bestehenden überlangen Pfadangaben für Verzeichnisse/Ordner nicht klar. Startet dann ein Anwender eine mit der "alten" QReport-Version compilierte Applikation, so ist der Windows-Standard-Pfad für den Temporären-Ordner (Tmp/Temp) auf einen Pfad gesetzt, der mit unter extrem lang ist (siehe Systemeigenschaften -> Erweitert -> Umgebungsvariablen). Das Update fixt das Problem.