Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]11613[/thread]

SpreadSheet::WriteExcel Bufferoverflow?

Leser: 1


<< >> 10 Einträge, 1 Seite
Tr0Nix
 2008-04-09 18:35
#108167 #108167
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen

Ich habe ein sehr spezielles Problem mit dem im Subjekt genannten Modul. Es äussert sich darin, dass wenn ich die Methode "write_number" verwende, Perl abstürzt und Windows eine Speicherschutzverletzung meldet. Die Speicherschutzverletzung bezieht sich dabei auf eine Memoryaddresse, die meinem Wert den ich ursprünglich schreiben wollte bezieht.

-> Ich will die Zahl 11 schreiben, Speicherschutzverletzung ist bei 0x0...11

Jetzt würde ich hier wahrscheinlich nicht schreiben, wenn ich nicht selbst das Gefühl hätte, selber noch etwas Dreck am Stecken zu haben :). Ich habe anfangs der Subfunktion etwas gebastelt. Und zwar möchte ich der Funktion ein Array und einen Hash übergeben. Da Perl dies zusammenmixt in einen Array, übergebe ich die Daten folgendermassen:
Code: (dl )
methode( ([@ARRAY], {%HASH}) );

-> Ich "stülpe" ein Array über den Array und den Hash. Der Sub-Array ist dabei in [0] und der Hash in [1].

In der Methode selbst - und hier ist das Gebastel - lade ich diese folgendermassen zurück:
Code: (dl )
1
2
3
4
5
6
my @tmp = @_;
shift;
@tmp = shift;
my @ARRAY = @{$tmp[0]};
@tmp = shift;
my %HASH = %{$tmp[0]};

(ich glaube nicht, dass das schön ist)

Ist es möglich, dass bei meinem zurückladen Perl etwas falsch interpretiert? Einen Wert als Pointer o.ä.? Das Problem ist mehrfach hintereinander nachvollziehbar, dann ist es wieder weg um irgendwann wieder aufzupoppen obwohl das Programm jedesmal das genau gleiche macht (gleiche Input Daten).
Tr0Nix
 2008-04-09 19:00
#108169 #108169
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
Ich habe eine V e r m u t u n g... möglicherweise hat der Garbage-Collector "versagt". Gemäss dem SpreadSheet::WriteExcel Readme:
Quote
In general your Excel file will be closed automatically when your program ends or when the Workbook object goes out of scope, however the close() method can be used to explicitly close an Excel file.


Da ich aus verschiedenen Methoden darauf zugreife, hab ich jetzt mal den ganzen Code der mit dem Excel arbeitet in eine Methode geworfen und siehe an, jetzt funktionierts... mehrmals restartet etc. und scheint jetzt stabil zu sein. Ursache ist mir dennoch nicht ganz klar und vielleicht hat jemand noch eine bessere Idee für die Array & Hash - Übergabe.
GwenDragon
 2008-04-09 19:48
#108172 #108172
User since
2005-01-17
14746 Artikel
Admin1
[Homepage]
user image
Was musst du denn übergeben?

Schau mal:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
my @ARRAY = qw( 1 2 3 );
my %HASH = ( 1 = 'TEST', 2 => 'OK');

methode (\@ARRAY, \@HASH);

sub methode {
my $arr_ref = shift;
my $hsh_ref= shift;

print '$arr_ref->[1] ist ', $arr_ref->[1];
print '$hsh_ref->{2} ist ', $hsh_ref->{2};
}
renee
 2008-04-10 10:31
#108200 #108200
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Es wäre auch gut gewesen, etwas mehr vom Code zu zeigen, der mit Spreadsheet::WriteExcel zu tun hat. Ich habe etliche Skripte mit dem Modul (bzw. Spreadsheet::SimpleExcel ;-) ) am laufen und da ist noch nie so etwas vorgekommen...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Tr0Nix
 2008-04-10 11:36
#108207 #108207
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
@Gwen: *thumbs up*, hat geklappt! Danke vielmals!

@renee: hätte ich sehr gerne gemacht, aber es ist ein relativ komplexes Konstrukt und ich wollte es auf das wirklich notwendigste runterbrechen. Hast du bei deinen Programmen mit dem gleichen Excel Objekt in mehreren Methoden gearbeitet? Ich finde die Aussage "..or when the Workbook object goes out of scope.." etwas verwirrend.
renee
 2008-04-10 12:28
#108209 #108209
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Ja, ich habe das Objekt in mehreren Methoden verwendet. "out of scope" heißt wohl eher "wenn der Referenzzähler auf 0 gesetzt wird".
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Tr0Nix
 2008-04-10 12:33
#108210 #108210
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
Ich hab das Problem etwas weiter Analysiert.. wenn ich in meiner komplexen, aus Referenzen bestehenden Datenstruktur etwas zuweise, erhalte ich jedesmal die Speicherschutzverletzung.

Muss mal zurückverfolgen, wie ich diese genau zusammensetze, ggf. hab ich irgendwo etwas gebastelt das Perl zwar akzeptiert, aber nicht wirklich korrekt ist :(
Tr0Nix
 2008-04-10 17:03
#108215 #108215
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
Ok, ich habe rausgefunden, wo das Problem liegt. Nur konnte ich es leider noch nicht lösen.

Alles fängt vom Hauptmodul aus an, indem ein "Record" erstellt wird, der an "check" übergeben wird:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
sub createRecord {
return {
'ID' => 'Record',
'FileName' => shift,
'LineNumber'=> shift,
'LineData' => shift,
'Treatment' => shift,
};
}

# $eins - $vier sind alles normale skalare
check(createRecord($File::Find::name, $eins, $zwei, $drei, $vier));


Innerhalb der Methode check wird der erstellte Record als Referenz gesichert, und hier liegt auch das Problem: Wenn ich hier Dummy-Daten einsetze, kriege ich später keine Schutzverletzung:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
sub check {
my $record = shift; # <--- Probleme
#my $record = { # <--- so würde alles funktionieren
# 'FileName' => 'c:\blah\fasel2.txt',
# 'ID' => 'Record',
# 'LineData' => 'some text comes here',
# 'LineNumber' => '222',
# 'Treatment' => undef,
#};

# ... etwas Logik dazwischen bis ...
createObject($record, $eins, $zwei, $drei, $vier); # <-- hier gebe ich den bereits erhaltenen Record weiter!
}

createObject funktioniert genau gleich wie auch createRecord weiter oben, also shiften in einen anonymen Hash-Array und return dessen.

Kann mir jemand sagen, was ich hier falsch mache? Perl akzeptiert meinen Code, der Debugger zeigt mir alles korrekt gesetzt an. Aber sobald ich später mit der in createObject erstellten Datenstruktur arbeite, kriege ich eine Speicherschutzverletzung.

Wie oben in den Kommentaren versehen -> wenn ich den $record manuell erstelle läuft alles durch!

Grüsse
renee
 2008-04-10 17:18
#108217 #108217
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Hast Du ein minimales (aber lauffähiges) Programm, das den Fehler reproduziert?

Hast Du das auch mal auf verschiedenen Umgebungen (OS, Perl-Versionen) getestet?
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Tr0Nix
 2008-04-10 17:28
#108219 #108219
User since
2006-11-21
44 Artikel
BenutzerIn
[default_avatar]
Renee, du hast dir echt ne Spende für das Forum verdient :-).

1. hast du absolut recht, wenn ich das Zeugs schon fürs Forum zusammenschneiden kann, kann ich auch gleich ein Debug-Programm schreiben.

2. scheinbar hat Komodos Debugger Einfluss auf das Laufzeitverhalten von Perl - mit Activestate Perl 5.8.0 über die Konsole aufgerufen habe ich das Problem nämlich nicht.

-> ich schneide bei Gelegenheit die Methoden zusammen und melde es Activestate! .. und wegen ner Spende schauen wir auch noch :)
<< >> 10 Einträge, 1 Seite



View all threads created 2008-04-09 18:35.