Newsgroup: it.comp.lang.visual-basic
Titolo: [VB6] Intercettare *tutti* gli errori

Ciao a tutti,
mamma mia, come mi sento obsoleto a chiedere qualche cosa sul buon vecchio 
VB6, ma abbiamo un po' di roba da manutenere.
E' possibile intercettare *tutti* gli errori di runtime che vengono 
eventualmente generati?
Mi spiego meglio, dato che quanto scritto sopra vuol dire tutto e niente....
Ho un programma che sta girando, questo programma ha una form principale di 
partenza, e per qualche motivo viene generato un errore di runtime in un 
qualunque punto, questo errore non e' gestito (tramite On Error) da nessuna 
parte, ne nel metodo che lo ha generato, ne nei livelli superiori.
Chiaramente il risultato e' che l'errore viene mostrato a monitor e 
l'esecuzione si interrompe.
Esiste un "punto" dove posso intercettare un errore, ovunque sia stato 
generato, per poter, ad esempio, avvisare con una mail il supporto tecnico?
Ciao e grazie... Maurizio
 

 eventualmente generati?
 
No.
A meno di tools esterni, di cui non ho esperienza, devi ristrutturare il codice...

codice...
...
Immaginavo, purtroppo!
Grazie ancora 
 
 

 ha scritto nel messaggio 
news:5051ad74$0$13276$4faf...@reader2.news.tin.it...

detto da uno come me, completamente a digiuno di VB, ma che 20 anni fa si 
divertiva a giocare col turbo basic della borland...
notando che i miei programmini potevano essere soggetti a diversi errori, 
avevo forse cercato il modo di richiamare, in ogni punto critico, la routine 
generica di error trapping.
per cui, non si potrebbe mettere tutto il codice sotto il governo di una 
tale "routine" ?
� solo un'idea generica, nessuna pretesa 
 
 

 una tale "routine" ?
 
Tutto il codice, si, ma bisogna mettere on error e il resto in ciasucna 
routina.
Mentre la comodit� sarebbe stare mettere un solo On Error a livello di 
progetto
 
Ma purtroppo VB7 non � mai uscito :(
 
 
-- 
Greg 
 
 

 ha scritto nel messaggio 
news:k2taoq$5t9$1...@tdi.cu.mi.it...

capisco, non saprei rispondere 
 
 

 non si potrebbe mettere tutto il codice sotto il governo di una
tale "routine" ?
� solo un'idea generica, nessuna pretesa
...
Come ti ha anche risposto Greg, cosi' sei obbligato ad usare un on error su 
ogni routine che vuoi proteggere, mentre lo scopo della mia richiesta era 
proprio di evitare tutto questo.
 

 proprio di evitare tutto questo.
 
Supponendo che il codice da manutenere non sia proprio così tanto fuori controllo da poter generare errori non previsti davvero *ovunque*, una passata preliminare, sui moduli/classi/form più delicati potresti provare a farla con sforzo modesto sfruttando il caro, vecchio MZTools (
http://www.mztools.com
)
 
Con quel plugin puoi creare un tuo template con le istruzioni di error trapping e, alla pressione di un tasto sulla sua toolbar, aggiungerlo alla routine attiva.
Se imposti l'editor di VB6 in visualizzazione NON modulo intero, aprendo un BAS per esempio riesci a fare la cosa in versione "scimmia ammaestrata" ripetendo 'PGDOWN+PGDOWN+Click, PGDOWN+PGDOWN+Click, ...'


Ragiona:
se il tuo programma chiede di aprire un file ....di fatto non lo fa 
"lui"....
ma si appoggia all'infrastruttura del S.O.
se quella "esplode" non c'è nessun trap che tenga! es. i Buffer underrun 
sono "carognissimi" da trappare!
 
Quello che "proviene" dal vb6 ...dal compilatore...dal "controllo" del 
programma è in qualche modo intercettabile
l'oggetto Error esiste anche in vb6
 
vado a ricordi
 
 
SUB AggiornaDB
on error goto TrapErrDB
 
 
 
exit sub
TrapErrDb:
if err.number = qualcosa (vedi 
http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=48434&lngWId=1
 
)  then
  faccio qualcos'altro
endif
 
end sub
 
 
Info supplmentari
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q168354&GSSNB=1
 
esempio di un po tutto da on error resume next a onerror goto (fregatene 
del provider oledb...sas non so che è!)
http://support.sas.com/documentation/tools/oledb/app_error_objects.htm
 
 
 
Aggiungo
anche NET non è immune! è molto più robusto se usi gli assembly standard 
perchè sei chiuso in una sandbox....
ma se si pianta la sandbox!!!
Per dire.....per quanto lo tengano nascosto....si piantano anche gli 
apple!!!...e pure linux....ed il trap definitivo a meno di non buttar 
via il S.O. e tenere il pc spento...che io sappia non esiste!

 via il S.O. e tenere il pc spento...che io sappia non esiste!
Per dire:
Linux Mint
l'accendo... sul notebook almeno 3 volte su 100 la scheda wifi non la 
sente!...mi tocca spegnere e riaccendere...e la sente!...eppure è 
aggiornato giornalmente!
...se avessi un programma...manca ci arriverebbe al trap!
 
Tablet mediacomm
ogni tanto smette di funzionare....si impalla! S.O. Android qualcosa
 
Win7
..il mio pc stand alone........10 minuti prima compila.....10 minuti 
dopo...."frulla frulla frulla"...cpu 100% . Eppure non c'è nulal di 
diverso da prima! almeno apparentemente...
 
Voglio dire che
 
Quando il progetto cresce a dismisura (un SO lo è) gran parte del tempo 
lo devi dedicare a pianificare test e debug "appropriati"...non puoi 
lanciare la compilazione ed aspettare eventuali errori....alcuni non li 
vedi subito ma solo con particolari combinazioni di "situazioni"!
 
... il nostro MVP Mauro te la saprà descrivere questa fase con dovizia 
di termini e riferimenti (io non sono purtroppo tecnico/competente come 
lui) ....il debug è un arte!...anzi no! proprio una branca 
dell'ingegneria informatica!

 l'oggetto Error esiste anche in vb6
[CUTTONE]
 
Vedi che tutto questo discorso penso lo avesse già ben presente... lui stava chiedendo un'altra cosa: visto che ormai il danno (mancanza di On Error messo con criterio) era fatto, se esisteva qualche scappatoia per non riscrivere mezzo mondo

riscrivere mezzo mondo
...
Tana!
E' proprio cosi', cioe', so bene come funziona l'on error di VB6, solo che 
per come e' stato scritto quel programmino, dato che non ho "voglia" di 
mettermi a fare una miriade di On Error su tutte le routine (o quanto meno 
su tutte le possibili chiamanti), speravo si potesse intercettare l'errore 
di runtime ad un livello superiore, tanto per fare "qualche cosa" prima di 
avere il blocco del software dato dal runtime error.
 
 


codesto l'avevo capito ma....
che se ne fa "a livello superiore"?
Reverse engigneering???
 
Non è che hai uno pseudocompilato come dotnet (e pure in dotnet mica 
vero) e puoi iniettare codice
....
abbi pazienza
SE NON HA CONTROLLATO NULLA
è cosa buona e giusta che segnali tutti gli errori dell'applicazione!
 
Senza ricordare chernobyl su allarmi disattivati....
più terra terra
 
 
Aggiorno il magazzino...per qualsiasi motivo...
i clienti 44 189 e 370 hanno dei records di articoli con campo quantità 
NULL (invece di zero)....non controllato ne trappato....
 
avvio l'aggiornamento di magazzino per l'inventario
 
non mi appare nulla o un innocuo: attenzione errori intervenuti
e mi stampa lo stesso la situazione di magazzino
 
è una situazione auspicabile???
Non controllar nulla per non controllar nulla....meglio il runtime error 
almeno si avviano le misure anche psicologiche per il debug(alias chi 
cazzo ha programmato sta ciofeca!....facciamo uscire la versione 2.0 
debuggata ....in puro stile microsoft!)
 
 
:)

codesto l'avevo capito ma....
che se ne fa "a livello superiore"?
[...]
No, la situazione e' leggermente differente da quella che prospetti.
Ho una applicazione che sta li per i fatti suoi, non e' "presidiata" (non 
sempre almeno).
Si fa tutte le sue operazioni e, *potrebbe* andare in runtime error (anche 
se con i vari debug che sono stati fatti, e' abbastanza raro).
Ammettiamo pero' che ci sia qualche cosa che ci e' sfuggito, ed in una 
particolare condizione, vada in errore. Il programma si ferma li, fino a che 
qualcuno non va a vedere come sta andando, si accorge che c'e' stato 
l'errore, ce lo segnala (per trovare il problema e possibilmente risolverlo) 
ecc.
Se riuscissi ad "intercettare" lo stato di errore, potrei quanto meno 
avvisare qualcuno, o entrare in una modalita' di emergenza (per altro, 
prevista) limitare i danni, e poi comunque andare a vedere chi e come ha 
causato il problema.
 
Ho provato anche a monitorare (tramite un programmino in .Net) lo stato del 
processo che voglio controllare, sono in grado di capire se l'applicazione 
non risponde (ho ad esempio inserito un loop infinito) ma non riesco a 
capire se il programma e' in stato di runtime error.
 

 causato il problema.
 
hai provato una cosa come questa?
 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680634(v=vs.85).aspx
 
 
.m
 
-- 
blog @ //
milestone.topics.it
 
 
 


Appunto....interessante.....
ma come è scritto ....roba per dev c e c++!
Niente di stra-drammatico...c'è persino una dll che aiuta il debug!
 
Però io torno sempre al punto.....sto giro di schiaffi ti merita farlo 
caro autore del post?
Ti merita metterti a studiare come funziona il core windows  e mettersi 
a spippolare?
Sei sicuro che poi il tuo sudato lavoro sia compatibile con Win7 8 e 
chissa cosa?
Casomai il tuo cliente ha un winxp o un vecchio win server e sta roba va 
alle ortiche e ne va studiata una ad hoc!
 
Sei proprio sicuro che la tua applicazione in stallo....non scriva ad 
esempio qualcosa nei log degli eventi/errori/menudelgiorno del windows 
del cliente? ...già sarebbe più semplice leggere e monitorare quel log!
 
 
Ma sopratutto....è davvero così fuori budget riprogettarla per emmettere 
log e strutturarla con un trap degli errori più efficiente?
fermo restando che la manutenzione continua è pressochè doverosa per 
ogni sw!!!(...se si pianta spesso è un brutto segnale....se si pianta 
ogni tanto...ci dovrebbe essere dei log di dump per tentare di capire....)
 
 
E poi....permettimi di dirtelo(o autore del post)....ok essere 
scrupolosi e professionali...ma paranoici no!
 
Se il cliente non vuole comprare un gruppo di continuita' e c'ha il cane 
che gioca fra le prese....o rovescia il caffe e la crema del bombolone 
sulla tastiera perchè non si vuol mettere a dieta!
o non ha speso per l'antivirus...o ha voluto le registrazioni contabili 
"sbloccate" perchè fa contabilità creativa...o ha una segretaria che fai 
bellissimi "soffoconi" al capo ma non sa nulla di pc e preme a caso per 
non rovinarsi lo smalto delle unghie.....
 
e ogni tanto va in tilt tutto......
 
 
e chi siamo noi....babbo Natale?????
:O)

 Niente di stra-drammatico...c'ï¿œ persino una dll che aiuta il debug!
 
ma ï¿œ un API del sistema operativo, non si puï¿œ da VB6 chiamarla e 
registrare una callbak?


 registrare una callbak?
 
Non sono sicurissimo che funzioni con VB6, perchè in realtà non esistono eccezioni non gestite, ma solo errori di runtime non gestiti... 
Nel senso che le eccezioni (in senso letterale) del tuo eseguibile vengono *tutte* intercettate dal runtime di VB6, che poi te le rimbalza indietro sotto forma di runtime error; temo che applicando la funzione al tuo codice VB non ci sia nessun effetto, perchè non viengolo sollevate in quel contesto.

E poi....permettimi di dirtelo(o autore del post)....ok essere
scrupolosi e professionali...ma paranoici no!
...
E che c'entra?
Se l'applicazione va in runtime error, la "colpa" non e' dell'utonto, ma e' 
di chi ha sviluppato che non ha *previsto* quella condizione.
Specie se, come nel mio caso, l'applicazione gira "quasi" per i fatti suoi, 
senza nessuno li davanti.
Per fortuna non vedo un runtime error da un pezzo, ma dato che sto facendo 
un sistema di monitoring per segnalare eventuali errori, dato che c'ero... 
:)
 

 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680634(v=vs.85).aspx
 
...
Sembra interessante, ed, almeno in teoria, dovrebbe essere proprio quello
che stav cercando, il problema pero' e' che non riesco a farlo funzionare.
 
In un modulo, ho importato la dichiarazione della funzione API,
 
 
    Public Declare Function SetUnhandledExceptionFilter Lib "kernel32.dll"
(ByVal lpTopLevelExceptionFilter As Long) As Long
 
dopo di cio' nel Sub Main (ma ho provato anche nel Form_Load impostando la
form come oggetto di avvio),
 
    Dim hnt As Long
    hnt = SetUnhandledExceptionFilter(AddressOf ExceptionFilter)
 
dove ExceptionFilter e' una funzione, che, in base ad esempi che ho trovato
sul web, e' scritta:
 
    Public Function ExceptionFilter(ByRef ExcPtrs As SYSEXC_POINTERS) As
Long
       Dim I As Integer
       I = 0
  End Function
 
Naturalmente ho definito anche la struttura SYSEXC_POINTERS.
 
In questo momento, naturalmente, la funzione non fa nulla, semplicemente ho
messo un breakpoint sulla riga I=0 per vedere se, in caso di un errore di
runtime, effettivamente la funzione registrata come callback fosse stata
chiamata.
 
In una form, quindi, ho messo su un button, e nel codice di click,
semplicemente faccio una conversione non possibile ( Cint ("pippo") ) e
viene quindi sollevato un errore di runtime 13.
Da quanto avevo capito, e sperato, in questo caso l'errore non si sarebbe
dovuto "vedere", ma la mia funzione ExceptionFilter avrebbe dovuto essere
chiamata.
Ho capito male, oppure ho sbagliato qualche cosa?
 
 

 Ho capito male, oppure ho sbagliato qualche cosa?
 
Vedi sopra: per me non funziona perchè l'eccezione vera e propria viene sempre trappata dal runtime di VB; l'errore di runtime che viene restituito a noi è una cosa diversa e specifica di VB, quella funzione lì non sa cosa farsene...

sempre trappata dal runtime di VB
...
Ho sperato non avessi ragione :(
Pero' il tuo discorso sembra, sfortunatamente, buono.
 
 


Però la cosa ha incuriosito anche me....
se sei in grado di approfondire da solo o di parlare con un sistemista 
(dovrebbere esistere anche in casa Microsoft) sembra....
 
che l'applicazione in crash debba comunque poter scrivere nel log che è 
crashata...come ffa microsft a debuggare il SO altrimenti???!!!!
 
Se non lo fa da mie ricerche su San Google SEMBRA che lo sia perchè è 
DISATTIVATA l'intercettazione dell'errore...e sembra che su XP lo sia di 
default!
http://stackoverflow.com/questions/7290686/vb6-application-wont-run-in-some-computers-in-others-it-runs-fine
 
 
credo che tu debba attivarla ....ed allora il crash appare nel event log!
 
Sempre se ho capito bene come funziona!
 
Facce sapè!

Però la cosa ha incuriosito anche me....
[...]
 
Faccio qualche prova, grazie!
 

Facce sapè!
...
Lo so, lo so, sto rispondendo con un bel po' di ritardo, ma solo ieri ho 
avuto modo di mettere mano alla cosa.
Ho controllato le impostazioni come segnalato, ed il tracciamento degli 
errori di applicazione e' abilitato, ho mandato in runtime error il mio 
software, ma nel registro di sistema (WinXp 32 bit) 'un vi e' nulla!
Come avevo gia' scritto, mi sa che Luca ci ha preso!