Autor Téma: predinstalovany HP minitower - problem s ukladanim html souboru  (Přečteno 11854 krát)

Offline Hdm

  • Nováček
  • *
  • Příspěvků: 34
  • Karma: 3
    • Verze Delphi: Tokyo
Ahoj,
mám program napsaný v Delphi a jednou funkcí je ukládání do souboru s koncovkou html.
Všude to funguje(rúzné verze windows včetně Win7profi), problém je pouze na sestavě:
HP minitower 8100 s předinstalovým Windows 7 profi 32bit i 64bit (přesnější popis stroje zákazník zatím nedodal)
Na stroji je prý nainstalovaný různý HP pomocný SW
Soubor to do umístění nevytvoří/neuloží a program žádnou chybu nehlásí, přestože je ukládání v chráněné části kódu. Toto by mohlo taky znamenat, že soubor vytvoří, ale hned ho něco smázne.
Soubory s koncovkami TXT, LOG, INI to vytvoří bez problémů.

Zkoušeli jsme:
  • přidat plná práva na složku
  • spustit jako administrator (zkoušeli jsme i doménového admina)
  • dokonce jsme PC odebrali z domény a spustit jak administrator s plným přístupem na složku
  • všechny predchozí pokusy i s programem v jiných složkách
  • Program na jiné sestavě(jiné PC) ve stejné doméně funguje správně
  • PC jsme přeinstalovali/obnovili systém z backup oblasti, takže žádný jiný SW tam není kromě HP pomocných SW

Nemáte někdo nějakou zkušenost s podobným problémem a jak to vyřešit?. Řešení ve smyslu nainstalovat tam čistý OS z CD a ne z HP backup oblast zákazník moc nevítá.i
Hdm

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3527
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #1 kdy: 22-04-2013, 08:54:30 »
Soubor to do umístění nevytvoří/neuloží a program žádnou chybu nehlásí, přestože je ukládání v chráněné části kódu. Toto by mohlo taky znamenat, že soubor vytvoří, ale hned ho něco smázne.
A FileMon na to rika co?

Offline Hdm

  • Nováček
  • *
  • Příspěvků: 34
  • Karma: 3
    • Verze Delphi: Tokyo
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #2 kdy: 15-05-2013, 13:38:15 »
Pokročil jsem ve zkoumání problému.
Jde o ukládání TstringList.SaveToFile z vedlejšího vlákna. Zkoušel jsem přesně toto ukládání obalit kritickou sekcí, ale nepomohlo.
Uložení z hlavního vlákna proběhne v pořádku, ale ten samý TstringList se uloží prázdný(to co naplnilo vedlejší vlákno tam není)

Kód: [Vybrat]
      ...
      EnterCriticalSection(tmpLock);
      try
        SL.SaveToFile(ExtractFilePath(ParamStr(0)) + SL_Name);
      except
        on E : Exception do
        begin
          WriteToLog(E.ClassName + ' - ' + E.Message);
        end;
      end;         
      LeaveCriticalSection(tmpLock);
      ...
Hdm

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3527
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #3 kdy: 15-05-2013, 14:13:57 »
Pokročil jsem ve zkoumání problému.
Jde o ukládání TstringList.SaveToFile z vedlejšího vlákna. Zkoušel jsem přesně toto ukládání obalit kritickou sekcí, ale nepomohlo.
Uložení z hlavního vlákna proběhne v pořádku, ale ten samý TstringList se uloží prázdný(to co naplnilo vedlejší vlákno tam není)
Takova kontrolni otazka: tu (jednu, spolecnou) kritickou sekci jsi dal ke kazdemu zapisu v aplikaci? Zadnou chybu to nikde nehlasi?

Lepsi reseni je otevrit se ten soubor jako stream v exclusive modu a misto SaveToFile pouzit SaveToStream. A po kazde I/O operaci zkontrolovat vysledek, a pro ACCESS_DENNIED pres nejaky retry mechanismus po nejake dobe operaci zopakovat.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 577
  • Karma: 25
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #4 kdy: 15-05-2013, 20:11:08 »
Jestli to chápu dobře, tak jeden StringList plníš z více vláken? Je StringList thread-safe (mělo by to být napsané v dokumentaci, podle diskuzí typu http://objectmix.com/delphi/633638-do-tstringlist-add-tstringlist-delete-methods-threadsafe.html není), případně přístup k němu synchronizován?

Offline Hdm

  • Nováček
  • *
  • Příspěvků: 34
  • Karma: 3
    • Verze Delphi: Tokyo
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #5 kdy: 16-05-2013, 08:19:37 »
TStringList je property objektu, který se vytvoří v hlavním vlákně hned při startu programu.
Po té je plněn, ale pouze z toho vedlejšího vlákna.
Nakonec informace z objektu zobrazuje hlavní vlákno.

Žádnou chybu program nehází a hlavní vlákno vidí TStringList prázdný.

Nyní se snažím dokrokovat kam až program doběhne(, ale jde to pomalu - když krokuju z Delphi více vláken tak se po několika krocích sekne celé Delphi a musím ho restartnout :-(   )

Teď mě napadlo, že zkusím ve vedlejším vláknu vytvořit nějaký dočasný SL a ten na ThreadEnd pak předhodit SL v objektu.

Doplním další informace co jsem obdržel od tech. podpory a co jsem sám vyzkoumal:

Problém je pouze na Win7 aWin8. Nezáleží na home, profi... 32/64bit

Další anomálie jsem zjistil i v jiných částech kódu, které se vláken netýkají, takže tady už fakt začínám být dost tápající.
Poměr u zákazníků nefunkčních Win7/8 proti funkčním je momentálně asi 1:15.

Jeden příklad z mého zoufalství:
Mám sadu HW identických notebooků, kde:
  • Win7 64bit předinstalované > program nechodí správně
  • Win7 64 bit "ručně" instalované > program běží bez problémů
  • Win8 Enterprise evolution 64 bit "ručně" instalované  > program nechodí správně

Takže zatím jsem vyloučil problém na HW.

Dále zkoumám zda na to nemůžou mít vliv nějaké drivery či nastavení OS.
« Poslední změna: 16-05-2013, 10:21:26 od Hdm »
Hdm

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 577
  • Karma: 25
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #6 kdy: 16-05-2013, 10:54:29 »
TStringList je property objektu, který se vytvoří v hlavním vlákně hned při startu programu.
Po té je plněn, ale pouze z toho vedlejšího vlákna.
Nakonec informace z objektu zobrazuje hlavní vlákno.

Žádnou chybu program nehází a hlavní vlákno vidí TStringList prázdný.

No a to je blbě, prostě stringlist není (předpokládám) thread safe, takže k němu nemůžeš přistupovat z víc vláken, aniž bys to synchronizoval. Při přidávání nových záznamů se reorganizuje pole, které to interně používá, takže klidně ti může vracet nevalidní hodnoty nebo prázdný seznam, záleží jenom na tom, kdy se to sejde. Tohle jsou věci, které je potřeba dobře napsat v kódu, pokud to máš blbě, tak to může někdy fungovat a někdy ne. Což je nejspíš to, co se ti děje. Třeba dictionary v .Net se chová tak, že vrací klíče s null hodnotou, které do ní ale dát nejdou. Nebo při konkurentním přístupu dojde k zamrznutí těch dvou zúčastněných threadů, takže ti celá aplikace vytuhne.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3527
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #7 kdy: 16-05-2013, 10:58:31 »
Nyní se snažím dokrokovat kam až program doběhne(, ale jde to pomalu - když krokuju z Delphi více vláken tak se po několika krocích sekne celé Delphi a musím ho restartnout :-(   )

Nekrokuj to, ale zuzuj si postupne prostor pomoci breakpointu. A jestli se jedna o nejaky race condition bug, tak ho stejne s velkou pravdepodobnosti v debuggeru nechytis a budes muset pouzit logovani.

Citace
Teď mě napadlo, že zkusím ve vedlejším vláknu vytvořit nějaký dočasný SL a ten na ThreadEnd pak předhodit SL v objektu.

Jedna z prvnich veci, ke ktere by ses mel dobrat, zda je to problem obsahu nebo I/O operace: takze si v miste, kde to zapisujes do souboru, vytvor lokalni pomocny SL, napln ho nejakym Lorem Ipsum generatorem, zapis ho do souboru a zase SL zrus. Tim bys mel vyloucit interakci s ostatnimi thready a pri trochu systematickem pristupu by nemel byt zadny problem zjistit, proc ti ev. Save selhava.


Citace
  • Win7 64bit předinstalované > program nechodí správně

Kdyz vidim tohle, tak si vzpomenu na zakernou, ale mnohokrat ruzne zminovanou zalezitost, ze se predinstalovana wokna (ja mam zkusenost s Win7) tvari jako spravne cesky nainstalovana, ale nekde maji uvnitr neco spatne nastaveno kolem NLS, takze zejmena aplikace, ktere nejsou vyvinute v unicode ale ANSI, mivaji problemy. Takze prvni co bych udelal na kazdych ceskych preidinstalovanych windows: nastavil bych EN, restartoval, nastavil CZ a restartoval.
« Poslední změna: 16-05-2013, 11:11:21 od pf1957 »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3527
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #8 kdy: 16-05-2013, 11:06:56 »
No a to je blbě, prostě stringlist není (předpokládám) thread safe, takže k němu nemůžeš přistupovat z víc vláken, aniž bys to synchronizoval.
TStringList neni thread safe. Ale jestli (?) je to jak pise, ze po tom stringu saha vzdycky jenom z jednoho mista a nikdy ne soucasne z vice, tak by mu to nemelo vadit.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 577
  • Karma: 25
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #9 kdy: 16-05-2013, 11:31:19 »
TStringList neni thread safe. Ale jestli (?) je to jak pise, ze po tom stringu saha vzdycky jenom z jednoho mista a nikdy ne soucasne z vice, tak by mu to nemelo vadit.

píše, že vlákno plní v jednom vlákně a v UI threadu se mu tváří prázdný, to je přístup z dvou threadů. Jinak nějakou sychronizaci asi má, viz to EnterCriticalSection(tmpLock);. Otázka ale je, jestli to má všude, kde s tím stringlistem pracuje (čtení i zápis).

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3527
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #10 kdy: 16-05-2013, 11:41:43 »
píše, že vlákno plní v jednom vlákně a v UI threadu se mu tváří prázdný, to je přístup z dvou threadů. Jinak nějakou sychronizaci asi má, viz to EnterCriticalSection(tmpLock);. Otázka ale je, jestli to má všude, kde s tím stringlistem pracuje (čtení i zápis).
Ne ze bych se chtel prit o necem, o cem vim kulovy, ale ja textu:
Citace
TStringList je property objektu, který se vytvoří v hlavním vlákně hned při startu programu.
Po té je plněn, ale pouze z toho vedlejšího vlákna.
Nakonec informace z objektu zobrazuje hlavní vlákno.
rozumim tak, ze ty operace probihaji po sobe: v main threadu vytvori instanci SL, pak spusti thread, ten do te instance pise (a asi dela i to SaveToFile?) a kdyz thread skonci (o par radku niz pise neco o ThreadEnd), tak obsah SL zobrazi v hlavnim threadu. Takze me z toho zadna paralelni operace se SL nevyplyva (i kdyz sam bych to udelal poradne a thread safe).

Offline Hdm

  • Nováček
  • *
  • Příspěvků: 34
  • Karma: 3
    • Verze Delphi: Tokyo
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #11 kdy: 16-05-2013, 13:13:35 »
je to jak píše pf1957. Je to samozřejmě bezpečně odděleno přes kritické sekce a dost jsem nad tím strávil, takže tam problém nevidím. K SL se přistupuje postupně, nikdy najednou ve více vláknech.

Každopádně jsem pokročil díky informaci o přepnutí lokálního nastavení CZ>EN>CZ co mi radí pf1957. Už jsem na to v minulosti narazil a dělal jsem kód s ochranou, že toto může nastat, ale ouha je to ještě zákeřnější než jsem si myslel.

Pokud celý nastavení locale přepnu na EN(spojené státy) tak program jede OK.
Pokud to přepnu zpět na CZ (CZ>EN>CZ) tak to nejede.

Zkusil jsem dát EN formát datumu v českém prostředí a zjistil problém ve standartních Delphi funkcích Now a StrToDateTime

Kód: [Vybrat]
var
tmpDT : TDateTime;
tmpString : String;


tmpString := DateTimeToStr(Now);
// vrací např. 16. 5. 2013 12:50:01   (povšimněte si mezer za tečkami v datu)

tmpDT :=  StrToDateTime(tmpString);
// spadne do výjimky, že není validní datum ve stringu

tmpDT :=  StrToDateTime('16.5.2013 12:50:01');
// po odstranění mezer za tečkami je situace stejná, také chyba

tmpDT :=  StrToDateTime('16/5/2013 12:50:01');
// proběhne v pořádku
Celkově z toho vyplývá, že funkce Now pracuje v českém tvaru, ale funkce StrToDateTime očekává tvar EN.

Nyní se pokouším zjistit jak OS donutit, aby se celý nastavil na CZ. Pokouším se manipulovat hodnotami v registrech:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Language]
"InstallLanguage"="0409"
"Default"="0405"
Ale zatím se zdá, že OS na změnu nereaguje.


Takže celá záležitost s vlákny a SL je mimo hru, protože ve vláknu je i převod datumu na kterém to spadlo do ošetřené výjimky, nehlásilo na venek chybu a vracelo default hodnotu. Dále to pak nemělo podle datumových podmínek žádná data k naplnění SL proto byl SL nakonec prázdný. Toto mě zmátlo a špatně navedlo na problém ve vláknech.


EDIT:Oprava drobnosti v kodu
« Poslední změna: 16-05-2013, 14:54:31 od Hdm »
Hdm

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 577
  • Karma: 25
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #12 kdy: 16-05-2013, 15:04:29 »
Now nepracuje v žádném tvaru, to vrací číslo odpovídající aktuálnímu datu a času, při zobrazování se naformátuje.

Nemůžeš prostě specifikovat formát data? Pokud na něm tak moc záleží a potřebuješ konkrétní formát, tak ho prostě specifikuj v těch konverzních funkcích jako parametr (alespoň doufám, že to šlo). Měnit kvůli tomu nastavení systému mi přijde jako lamerský přístup někoho, kdo ten formát neumí specifikovat nebo neví o tom, že to jde. Na nastavení systému bych se nespoléhal.

Offline Hdm

  • Nováček
  • *
  • Příspěvků: 34
  • Karma: 3
    • Verze Delphi: Tokyo
Re:predinstalovany HP minitower - problem s ukladanim html souboru
« Odpověď #13 kdy: 20-05-2013, 08:11:53 »
Mě nezáleží na formátu data, jak jsem psal  to i v EN tvaru. Na čem mě záleží je to, aby všechny funkce pracovaly se stejným tvarem. Pokud Now je číslo, pak je problém v StrToDateTime a DateTimeToStr, protože jedna funkce vrací jiný formát než druhá požaduje.

Řešit to budu, jak jsi také navrhl, úplným oddělením formátu od OS a celé to budu řešit na své straně.

Každopádně díky oběma za rady.
Hdm