Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Programma che funziona solo nel debugger
Forum - C/C++ - Programma che funziona solo nel debugger

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 23:43
Sabato, 11/11/2023
Mi sto scervellando per capire come mai un programma che sto realizzando (un semplicissimo gioco rompicapo in C, con supporto grafico tramite Gdi di win32) funziona perfettamente se "gira" nel debugger, ma va sistematicamente in crash in situazioni più o meno casuali se viene eseguito autonomamente. È la prima volta che mi succede una cosa del genere e, anche se ho provato un tot di metodi di indagine più o meno ortodossi, non riesco a capire come sia possibile. Qualcuno, qui, ha qualche consiglio generico da darmi, così che io possa tentare altre strade e magari riuscire a superare l'ostacolo?

AldoBaldo

Ultima modifica effettuata da AldoBaldo il 11/11/2023 alle 23:43


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1349
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 12:38
Domenica, 12/11/2023
Ipotesi.

Quando lavori nel debugger le librerie lincate vengono compilate ed usate, ma quando esegui l'.exe vengono usate le dll presenti nel sistema e raggiungibili attraverso l'impostazione dei path su: impostazioni sistema/avanzate/variabili d'ambiente (CMD >sysdm.cpl)


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 16:23
Domenica, 12/11/2023
Scusa, Carlo, ho imparato dai nostri contatti passati che sei una persona molto affabile e disponibile, per cui mi permetto di dirti che non ho capito come questo potrebbe influire sul mio caso particolare.

In effetti ho alcune librerie statiche precompilate (robetta di mio pugno) che ho incluso nel progetto di Code::Blocks. Per quel che ne so, in questo caso l'IDE prende di peso il codice delle librerie stesse e lo "incolla" pari pari nell'exe finale, tanto che sia una versione per il debug quanto una versione "release". Dunque non credo sia quello il problema, così come non credo che ci siano errori significativi nelle librerie stesse, perché in caso contrario manderebbero in crash anche eseguendole tramite il debugger (o, quanto meno, genererebbero segnalazioni di errore).

Le uniche librerie dinamiche che includo sono invece quelle del sistema, tipo gdi, user32... insomma, le solite cose di Win32 sin da Windows 98. "A naso" direi che neppure quelle dovrebbero dar luogo a problemi.

Una cosa che ho omesso nel mio messaggio precedente è che ottengo degli avvertimenti ("warning") dal compilatore che derivano dal file di intestazione 3d3types.h, che fa capo a DirectX. Gli avvertimenti sono tutti di questo tipo:

Codice sorgente - presumibilmente C/C++

  1. librerie/d3dtypes.h:26:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]
  2.  
  3. librerie/d3dtypes.h:2116:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]



Ora, le linee del file d3dtypes.h alle quali fanno riferimento gli avvertimenti sono queste, e non ho idea di cosa possano significare:

Codice sorgente - presumibilmente C/C++

  1. #pragma warning(disable:4201) // anonymous unions warning
  2.  
  3. #pragma warning(default:4201)



Da notare che uso DirectX solo per poter disporre di DirectSound nella sua versione 7, e che i comandi a detta libreria, al di là di quelli per l'inizializzazione e la dismissione (che avvengono senza problemi apparenti), li impartisco unicamente tramite IDirectSoundBuffer_Play() per brevissimi effetti sonori di pochi byte, per di più precaricati in fase di inizializzazione.

Scrivendo queste note mi sovviene che DirectX, in certe situazioni a sua completa discrezione, dealloca a tradimento i buffer che usa... potrebbe essere questo a creare i crash del programma? Tipo che io chiedo "esegui il buffer pinco pallino", ma quel buffer è stato deallocato, io non lo sottopongo a "refresh" e tutto va a rotoli? Mmm... Provo a vedere cosa riesco a capirci. Se hai suggerimenti, ti leggo senz'altro.

Per ora, grazie per il tempo che mi hai dedicato.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1349
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 17:28
Domenica, 12/11/2023
Se l'.exe lo lanci direttamente hai problemi, se lo fai lanciare al debugger no, che le dll usate siano diverse è tra le ipotesi da esplorare.

Per le Directx, disattiva i suoni e controlla se hai lo stesso problema.

Comunque ben risentito Aldo.


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 18:44
Domenica, 12/11/2023
Carlo, ora faccio una figura barbina, lo so... però ho scoperto l'errore (dopo aver penato lungo strade del tutto sbagliate per un tot di ore... va be', tanto è un passatempo).

Nel giochino c'è una funzione che gestisce una specie di "classifica" dei punteggi ottenuti nelle partite precedenti. Ebbene, la quantità dei punteggi elencati è fissa, per cui quando un nuovo punteggio deve essere inserito, tutti quelli dopo la posizione raggiunta nella partita corrente devono "scorrere" indietro di una posizione per far spazio al nuovo inserimento. Per spostare le strutture dati che contengono i punteggi uso memmove(). Peccato che abbia sbagliato il calcolo della quantità di memoria da spostare! Il che comportava che spostavo una manciata di byte in più andando a "contaminare" posizioni che volta per volta davano problemi oppure no (a seconda, probabilmente, di come vengono collocati altri byte essenziali o inessenziali in relazione all'andamento della partita). Ecco quindi che in alcune circostanze pseudocasuali il programma funzionava come niente fosse perché i byte molesti finivano in posizioni inutilizzate o irrilevanti, mentre in rare altre quei pochi byte molesti finivano in qualche "ingranaggio" essenziale e... BUM! "Esplodeva" il meccanismo.

Ovviamente, in qualche angolo del mio cervello sta un neurone che preferisce accollare la responsabilità ad altri piuttosto che a se stessi.

Ah, ho scoperto l'errore quasi per caso, vedendo che un flag di tipo BOOL assumeva all'improvviso un valore stellare che niente poteva avere a che fare con TRUE e con FALSE. Dunque, mi son chiesto: "cosa può essere ad assegnare dei valori così elevati laddove dovrebbe esserci giusto 1 o 0?". Dai e dai, son risalito alla funzione incriminata.

Tutt'ora non mi spiego, però, perché passando per il debugger non avvenissero i crash. Probabilmente per puro caso.

Scusa se ti ho rubato del tempo per niente.
Per farmi perdonare, ti regalerò la mia versione di "Greed" (te lo farò avere con un messaggio privato appena l'avrò completata). Come se valesse qualcosa! :rotfl:



ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6405
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 10:19
Lunedì, 13/11/2023
Testo quotato

Postato originariamente da AldoBaldo:

Tutt'ora non mi spiego, però, perché passando per il debugger non avvenissero i crash. Probabilmente per puro caso.




Quando si esegue il codice in modalità debug, vengono usate altre librerie e un runtime diverso. L'ambiente di memoria in cui lavora il codice è del tutto diverso da quello di release. In particolare, vengono aggiunte dal debugger delle zone di memoria appositamente  riempite e che delimitano le aree allocate. Queste zone servono al debugger per individuare gli overflow di memoria.
La presenza di queste aree però non permette al processore di individuare letture/scritture in aree non allocate dal processo ed evita dei crash che, invece, in release avvengono puntualmente.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1349
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 10:38
Lunedì, 13/11/2023
Testo quotato

Postato originariamente da AldoBaldo:
Ovviamente, in qualche angolo del mio cervello sta un neurone che preferisce accollare la responsabilità ad altri piuttosto che a se stessi.



Mi è successo un sacco di volte, ho sempre avuto torto. :asd::asd:
Sono contento che tu abbia risolto e come ti ha evidenziato nessuno anche più puntualmente, la differenza tra debugger e non, c'è.

Grazie per il giochino, veramente divertente, lo pubblicherai?
Ora sono impegnato in altri progetti ma non è escluso che un domani non ne faccia una versione C#


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 16:43
Lunedì, 13/11/2023
Testo quotato

Postato originariamente da nessuno:
Quando si esegue il codice in modalità debug (...) invece, in release (...)



Non ne avevo idea, grazie per avermelo fatto notare. Anche se si tratta di un'informazione generica, almeno ora sono sull'avviso e magari in futuro saprò essere un po' più "mirato" nella mia caccia agli insetti molesti (bug).


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 16:47
Lunedì, 13/11/2023
Testo quotato

Postato originariamente da Carlo:
Grazie per il giochino, veramente divertente, lo pubblicherai?
Ora sono impegnato in altri progetti ma non è escluso che un domani non ne faccia una versione C#



Non so se valga la pena di renderlo pubblico, perché è un'idea non mia e perché il codice, proprio perché invece interamente di mio pugno, è spiccatamente amatoriale. Per la versione in C# intendi partire da zero o preferisci che ti passi il codice in C? Ti avviso: è piuttosto "spaghettoso".

Nota: mentre ne ho ignorato completamente la parte in cui si riporta il codice, ho tratto le regole del gioco (adattandole leggermente al mio gusto) da questo filmato su youtube

https://www.youtube.com/watch?v=XQHq6tdxylk

Ultima modifica effettuata da AldoBaldo il 13/11/2023 alle 16:57


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo