Files
comun/docs/cercetare/handoff_watchdog_vfp.md
Marius Mutu 6de489950c sync SVN r18016: editare articole in factura de vanzare, precizie pret achizitie
ROAFACTURARE 2.11.15 (r18015): programe/ofacturare_editare.prg, programe/ofacturare_stoc.prg.
docs: conventia de encoding .sc2/.vc2 corectata la cp1250; cercetarile trans-proiect mutate
din ROAFACTURARE in docs/cercetare (r18014); actualizari reguli_lucru, oracle_export,
flux-editare-vfp-text, scripturi-migrare-db, flux-modificare-stergere-nota-jurnal, todos.
.gitignore: watchdog_out si PNG-urile din rularile headless (r18008).
Text FoxBin2Prg regenerat: clase/comun.vc2, ferestre/frm_import_note_facturi_clienti.sc2,
ferestre/frm_initializare_facturi_balanta.sc2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AV7dQbTLAqvrtQbH7zxXxw
2026-08-20 14:07:12 +03:00

8.2 KiB

Handoff — watchdog VFP + bisectie blocaj "View Parameter" gnAn

Predare la peste 310k context (Regula zero). Doar stare, fara analize noi. Raport analitic complet (dovezi, log-uri, discutie): docs\cercetare\rec_watchdog_vfp.md.

1. Inventar livrabile, cu fisier:linie

Utilitar: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_vfp.ps1. Linia de comanda completa:

powershell -ExecutionPolicy Bypass -File "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_vfp.ps1" -Script "<cale.prg>" -TimeoutSec 90 -AutoDismiss -MaxDialogs 10

Lanseaza vfp9.exe -A -T "<script>", detecteaza orice fereastra noua diferita de Process.MainWindowHandle, o captureaza (PNG + WM_GETTEXT pe titlu si controale copil) in <folderul scriptului>\watchdog_out\, si cu -AutoDismiss incearca s-o inchida STRICT prin mesaje Windows tintite pe handle (BM_CLICK pe buton Cancel/Anulare -> WM_COMMAND IDCANCEL -> WM_KEYDOWN/WM_KEYUP ca mesaj -> WM_CLOSE) - FARA input real (vezi sectiunea 3). Omoara procesul mereu la iesire (finally).

Fisiere de test noi:

  • COMUN\utile\Teste\watchdog_selftest.prg - caz banal de validare (MESSAGEBOX), folosit doar ca sa confirme ca watchdog-ul detecteaza/captureaza/dismite corect, inainte de cazul real.
  • COMUN\utile\Teste\editare_factura\test_repro_izolat_gnan.prg - experimentul B (izolat): DOAR test_init_env_auto + update_jtva_coloane("", "crsJtvaTemp", 6), fara nimic din S4. NU reproduce blocajul - dovada ca update_jtva_coloane/updateserver.prg sunt nevinovate.

Fisier de test modificat: COMUN\utile\Teste\editare_factura\test_page3_articole.prg:

  • linia 176: update_jtva_coloane("", "crsJtvaTemp", 6) (parametrul schimbat din 0 in 6 - necesar pentru indexul id_jtva cerut de Column63.ControlSource din omodificari.vc2:9199; independent de defectul principal, fix cunoscut deja din date_test_nnir.md);
  • PROCEDURE bisect_log_gnan (noua, la coada fisierului, ~linia 236) + apeluri DO bisect_log_gnan WITH <tag>, lcLog inserate: in programul principal intre fiecare apel de nivel superior, si ca PRIMA linie in interiorul fiecarei proceduri (verifica_vanzare_nota, verifica_coliziune_cod, verifica_pagecount_form) - infrastructura de bisectie, ramasa in cod ca dovada;
  • liniile 37, 39, 50 - remediul APLICAT DE TEAM-LEAD (nu de mine, sub pragul lui de editare directa): gnAn/gnLuna parantezate - (gnAn), (gnLuna) - in apelurile DO verifica_vanzare_nota WITH ... (x2) si DO verifica_pagecount_form WITH ... (primul), cu comentariu explicativ deasupra primei aparitii (liniile 34-36).

Log-uri si capturi: test_page3_articole_log.txt (log-ul aplicatiei, contine liniile [BISECT]), watchdog_out\*.png + watchdog_out\*_watchdog.log (capturi + jurnal watchdog, per fisier de test), toate in COMUN\utile\Teste\editare_factura\.

2. Ce e terminat, ce nu

Terminat:

  • Watchdog-ul: scris, testat pe caz banal, testat pe cazul real, corectat (heuristica de fereastra principala, bug de indexare PowerShell pe array cu 1 element, input real scos complet).
  • Bisectia: COMPLETA, cauza CONFIRMATA cu date brute (nu deductie) - vezi sectiunea 4.
  • Remediul: APLICAT de team-lead (liniile 37/39/50).

Neterminat: remediul NU a fost re-testat dupa aplicare. Ultima rulare a suitei (a mea) a fost INAINTE de remediul team-lead-ului. Team-lead ruleaza el insusi suita, separat - eu nu mai rulez nimic (interdictie explicita primita).

3. Stare fisiere - write-back

Toate fisierele atinse in aceasta sesiune sunt .prg/.ps1 (text simplu) - NU exista .vc2/.sc2/.vcx/.vct atinse, deci NU exista niciun write-back nefacut.

Confirmare explicita: COMUN\clase\omodificari.vc2/.vcx/.vct si COMUN\programe\updateserver.prg sunt NEATINSE in aceasta sesiune (nici de mine, nici - din cate stiu - de altcineva). Fara commit git/svn facut sau initiat.

4. Ce s-a stabilit deja - NU relua

  • Cauza CONFIRMATA, nu ipoteza: test_page3_articole.prg (inainte de remediu) trecea gnAn/gnLuna NEPARANTEZAT in DO...WITH (liniile 34, 36, 47 - numerotare dinainte de remediu). DO proc WITH var paseaza variabile de memorie BY REFERENCE implicit in VFP; LPARAMETERS primitor devine alias direct pe storage-ul original, iar numele original (gnAn) devine inaccesibil (TYPE()='U') STRICT pe durata acelui apel, revenind valid imediat dupa RETURN. Confirmat simetric pe 3 apeluri afectate vs 2 neafectate (vezi tabelul din rec_watchdog_vfp.md sectiunea 5).
  • updateserver.prg/update_jtva_coloane sunt nevinovate - experimentul B (izolat, fara nimic din S4) NU reproduce; functia merge perfect cand gnAn e vizibil normal.
  • gnAn NU e eliberata niciodata - ramane valida (TYPE()='N', 2026) la FIECARE checkpoint din scope-ul PRINCIPAL, fara exceptie. Nu exista CLEAR ALL/CLEAR MEMORY/RELEASE ALL EXTENDED pe lantul executat.
  • Nu e coliziune de nume in corpul procedurii: verifica_pagecount_form NU are gnAn in LOCAL (linia ei 148/159), si NU exista PRIVATE gnAn/LOCAL gnAn nicaieri in COMUN\programe. Umbrirea vine din SINTAXA APELULUI (DO...WITH neparantezat), nu din declaratiile callee-ului.
  • Handler-ul de eroare (test_error_handler/ON ERROR) doar logheaza (STRTOFILE) si continua
    • nu ascunde nimic, util pentru diagnostic.
  • Incidentul de focus: ESC-ul trimis de o versiune veche a watchdog-ului (cu SetForegroundWindow
    • keybd_event, SCOASA complet acum) a aterizat de fapt in PROPRIUL nostru proces de test, NU in sesiunea utilizatorului - dar mecanismul tot nu are tinta si regula "fara input real" ramane obligatorie indiferent (documentat in rec_watchdog_vfp.md sectiunea 1, corectat acolo dupa o formulare initiala gresita).

5. Ce e interzis

  • Input real de tastatura/mouse in watchdog (keybd_event, SetForegroundWindow, SendInput, mouse_event) - masina e PARTAJATA. Deja scos din cod, verificat cu grep (zero hit-uri de cod, doar comentarii care explica interdictia).
  • Atingerea COMUN\clase\omodificari.vc2/.vcx/.vct si COMUN\programe\updateserver.prg.
  • Commit git/svn.
  • Eu nu mai rulez suita - team-lead o ruleaza separat dupa remediul lui.

6. Capcane de mediu platite in aceasta sesiune

  • Heuristica "prima fereastra vazuta = principala" e o cursa pierduta: un dialog poate aparea in aceeasi fractiune de secunda cu fereastra principala. Solutia corecta: Process.MainWindowHandle (.NET), NU ordinea de aparitie si NU numele clasei (VFP foloseste clase vfp9... si pentru shell, si pentru dialogurile proprii - vfp99400000 vs vfp994000002).
  • Dialogurile proprii VFP (ex. "View Parameter") sunt owner-drawn - EnumChildWindows intoarce ZERO controale copil (butoanele sunt desenate, nu HWND-uri reale). BM_CLICK e imposibil pentru ele; chiar si WM_CLOSE poate "reusi" aparent (IsWindow -> fals) FARA sa deblocheze de fapt motorul VFP din spate (SQLEXEC ramas agatat, fara linie noua in log, pana la timeout) - un fals "succes" de retinut daca cineva reia mecanismul de dismiss.
  • Bug PowerShell subtil: un List[string] cu UN SINGUR element e "descompus" de PowerShell la scalar string simplu la return din functie (fara , unar) - indexarea ulterioara $x[0] citeste atunci primul CARACTER, nu primul element. Prins la dump-ul de text al dialogului "View Parameter" (fara controale copil = un singur element in listă). Fix: return , $lista.ToArray().
  • .fxp vechi blocat: sterge intotdeauna .fxp-ul inainte de fiecare rulare (watchdog-ul o face singur) - altfel VFP ruleaza tacut codul vechi compilat.
  • Bisectia: TRANSFORM(gnAn) pe o variabila TYPE()='U' ARUNCA eroare catchabila ("Variable 'GNAN' is not found") - helper-ul bisect_log_gnan verifica TYPE()<>'U' INAINTE de a apela TRANSFORM(), ca sa nu produca o eroare noua care ar fi intrerupt bisectia la primul checkpoint "gol".

Confirmare finala

PID 16548 nu mai exista (verificat cu Get-Process -Id 16548 - inexistent la momentul acestui handoff) si niciun vfp9.exe nu ruleaza (verificat cu Get-Process vfp9 - lista goala). Nimic in stare periculoasa: fara editare pe jumatate, fara cursor/tranzactie Oracle deschisa (doar citiri), fara fisier binar atins. Sesiunea se opreste aici.