Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

probleme with memory management in threads and dll modules

14 réponses
Avatar
ouech
hi,

i've got a problem on a school project im working on. it's
a web server wich processes requests throught modules that
can hook at any stage of the request treatment.

these modules are classes that has the same base and do their
job in a member function. they are dlls loaded dynamically
throught configuration file or user command. modules store their
results in a class containing the request.

each client/request is managed in a thread and the data object
that store the request is created at the begining of the thread
proc function. it is passed throught each module and used to store
their result in public string members vars (most). those strings are
modified in the modules member functions with constant strings like :

data->result_string = "HTTP/1.1 200 OK\r\n";

so i come to my problem :) after that my server send the response,
when the thread proc is finished, the destructor of my data class
is called then destructors of the members strings. and at the
time the string destructor delete the _Ptr member of the string
class (in function deallocate), i've got a user breakpoint (the
programme stop) in debugging mode folowed (if i resume execution)
by a "debug assertion failed" error in dbgheap.c at expression
_CrtIsValidHeapPointer. the adress of _Ptr is the same that when
i initialized it in the modules functions.

I've tried some things like replacing the string member by a char*
initialized by strdup("mystr") but i can't free it in the destructor
and if i don't, it's the precedent member string in the data class
declaration that causes the same trouble.
i even thought that it was because the stack of the thread was freed
before the destructor of my class was called, so i tried allocating
the class with the new operator and deleting it at the end of the
thread. but it was strictly the same.

i don't really have anymore idea. i use dll like this for the first
time. it seems that the locals and allocated adresses are
not anymore valid after a module function was executed.
i really don't know how to produce data in a module if it's the case :)
does i have to allocate a big buffer before calling the modules
in order to put all the strings they produce in? it would suck a lot :)

thanks for your help,

--
Lucas
Montes

10 réponses

1 2
Avatar
adebaene
ouech wrote:
hi,



<snip>
This is a french-speaking newsgroup, thanks.

Arnaud
Avatar
Vincent Burel
- bon primo, dans la gestion d'une communication client / serveur, il faut
éviter de faire un thread par client. En général 2 thread suffisent, un
thread de management des requetes et un thread de service pour login/logout
des clients.

- deusio, un problem sur delete / free est TOUJOURS due à une mauvaise
gestion de la mémoire de votre part. ou bien que vous ne passez pas le bon
pointer, ou bien que vous avez corrompu la mémoire en dépassant des bornes,
ou bien que vous avez plus d 1 Mo de local dans votre thread... ou bien
etc....

- Dans un cas comme le votre, il y a des règles à suivre. D'abord ne pas
s'affoler, et éviter de parler en anglais :-) ensuite on se fait un petit
soda sur un bon canapé , pendant quelques jours... si la solution ne vous
tombe pas dessus comme par magie, c'est que vous ne comprenez rien à ce que
vous avez fait, votre cerveau ne l'a donc pas intégré, la solution ne peut
donc pas vous apparaitre, vous êtes obligé de chercher... là vous avez le
choix, ou vous perdez des semaines à trouver votre erreur, ou bien vous
recommencer tout... les deux méthodes prennent souvent autant de temps...
mais la seconde permet de s'améliorer et de faire qqc de beaucoup plus
solide, car mieux pensé...

pour moi l'occasion de rappeler la 23ieme loi de la programmation :
Tout nouveau type d'application nécessite d'être programmé deux ou trois
fois pour être totalement et rigoureusement cerné, maîtrisé, organisé.

:-)
VB

"ouech" wrote in message
news:

hi,

i've got a problem on a school project im working on. it's
a web server wich processes requests throught modules that
can hook at any stage of the request treatment.

these modules are classes that has the same base and do their
job in a member function. they are dlls loaded dynamically
throught configuration file or user command. modules store their
results in a class containing the request.

each client/request is managed in a thread and the data object
that store the request is created at the begining of the thread
proc function. it is passed throught each module and used to store
their result in public string members vars (most). those strings are
modified in the modules member functions with constant strings like :

data->result_string = "HTTP/1.1 200 OKrn";

so i come to my problem :) after that my server send the response,
when the thread proc is finished, the destructor of my data class
is called then destructors of the members strings. and at the
time the string destructor delete the _Ptr member of the string
class (in function deallocate), i've got a user breakpoint (the
programme stop) in debugging mode folowed (if i resume execution)
by a "debug assertion failed" error in dbgheap.c at expression
_CrtIsValidHeapPointer. the adress of _Ptr is the same that when
i initialized it in the modules functions.

I've tried some things like replacing the string member by a char*
initialized by strdup("mystr") but i can't free it in the destructor
and if i don't, it's the precedent member string in the data class
declaration that causes the same trouble.
i even thought that it was because the stack of the thread was freed
before the destructor of my class was called, so i tried allocating
the class with the new operator and deleting it at the end of the
thread. but it was strictly the same.

i don't really have anymore idea. i use dll like this for the first
time. it seems that the locals and allocated adresses are
not anymore valid after a module function was executed.
i really don't know how to produce data in a module if it's the case :)
does i have to allocate a big buffer before calling the modules
in order to put all the strings they produce in? it would suck a lot :)

thanks for your help,

--
Lucas
Montes


Avatar
ouech
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:

- bon primo, dans la gestion d'une communication client / serveur, il
faut
éviter de faire un thread par client. En général 2 thread suffisent, un
thread de management des requetes et un thread de service pour
login/logout
des clients.

- deusio, un problem sur delete / free est TOUJOURS due à une mauvaise
gestion de la mémoire de votre part. ou bien que vous ne passez pas le
bon
pointer, ou bien que vous avez corrompu la mémoire en dépassant des
bornes,
ou bien que vous avez plus d 1 Mo de local dans votre thread... ou bien
etc....




javais bien compris

- Dans un cas comme le votre, il y a des règles à suivre. D'abord ne pas
s'affoler, et éviter de parler en anglais :-)



c vrai desole c une erreur j'etais tres fatigue.

ensuite on se fait un petit
soda sur un bon canapé , pendant quelques jours... si la solution ne vous
tombe pas dessus comme par magie, c'est que vous ne comprenez rien à ce
que
vous avez fait, votre cerveau ne l'a donc pas intégré, la solution ne
peut
donc pas vous apparaitre, vous êtes obligé de chercher... là vous avez le
choix, ou vous perdez des semaines à trouver votre erreur, ou bien vous
recommencer tout... les deux méthodes prennent souvent autant de temps...
mais la seconde permet de s'améliorer et de faire qqc de beaucoup plus
solide, car mieux pensé...

pour moi l'occasion de rappeler la 23ieme loi de la programmation :
Tout nouveau type d'application nécessite d'être programmé deux ou trois
fois pour être totalement et rigoureusement cerné, maîtrisé, organisé.

:-)
VB




bah en fait le probleme vient surtout du faite que la memeoire allouer
par un module loader dynamiquement semble ne plus etre valide ailleur,
comme semble le montrer le poste plus haut (dll allocation memoire...)
il faut donc que je trouve un systeme pour ne rien allouer sur le tas
(par exemple avec un HeapCreate), ou alors liberer la memoire
allouer par un module dans une de ses propres fonctions. bref ca complique
mon boulot mais pour l'idee de tout recommencer, merci mais c un projet que
je rend demain. :)

merci quand meme et a+

--
Lucas
Montes
Avatar
ouech
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:

- bon primo, dans la gestion d'une communication client / serveur, il
faut
éviter de faire un thread par client. En général 2 thread suffisent, un
thread de management des requetes et un thread de service pour
login/logout
des clients.




apache lance plusieur process au demarrage avec plusieur threads en attente
dans chaque process. quand un nouveau client se connecte, il traite sa
requete
dans une thread (une thread par client) qui attendait dans un process.
alors c
sur que c bien plus rapide que de creer une thread a la connection du
client mais
pour gerer beaucoup de connexions (serveur web par exemple), le select ne
suffit
plus vraiment.

a+,

--
Lucas
Montes
Avatar
Vincent Burel
"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:

> - bon primo, dans la gestion d'une communication client / serveur, il
> faut
> éviter de faire un thread par client. En général 2 thread suffisent, un
> thread de management des requetes et un thread de service pour
> login/logout
> des clients.
>

apache lance plusieur process au demarrage avec plusieur threads en


attente
dans chaque process. quand un nouveau client se connecte, il traite sa
requete
dans une thread (une thread par client) qui attendait dans un process.
alors c
sur que c bien plus rapide que de creer une thread a la connection du
client mais
pour gerer beaucoup de connexions (serveur web par exemple), le select ne
suffit
plus vraiment.



C'est vous qui le dites, moi je dis qu'une thread par flux ca suffit et que
plusieurs thread sur le même flux, ca sert à rien ,sinon à créer des conflit
d'accès (et certainement ca facilite le travail du programmeur, m'enfin bon,
un bon programmeur se doit plutot de faciliter le travail de la machine, pas
le sien :-). Si vous avez deux flux, donc deux carte ethernet, alors oui,
dans ce cas un thread par carte ca a du sens...

VB
Avatar
Vincent Burel
"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:


bah en fait le probleme vient surtout du faite que la memeoire allouer
par un module loader dynamiquement semble ne plus etre valide ailleur,



impossible sans erreur de votre part.

comme semble le montrer le poste plus haut (dll allocation memoire...)
il faut donc que je trouve un systeme pour ne rien allouer sur le tas



pourquoi ? utiliser seulement malloc / free , ca suffit amplement.

merci mais c un projet que
je rend demain. :)



non, je ne crois pas :-)

VB
Avatar
ouech
Le Mon, 7 Feb 2005 11:03:46 +0100, Vincent Burel
a écrit:


"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:


bah en fait le probleme vient surtout du faite que la memeoire allouer
par un module loader dynamiquement semble ne plus etre valide ailleur,



impossible sans erreur de votre part.




bah vous semblez dire le contraire dans le post dll allocation de memoire.

je vais plus me renseigner mais si c'est juste pour m'embrouiller c pas
cool
:P

comme semble le montrer le poste plus haut (dll allocation memoire...)
il faut donc que je trouve un systeme pour ne rien allouer sur le tas



pourquoi ? utiliser seulement malloc / free , ca suffit amplement.

merci mais c un projet que
je rend demain. :)



non, je ne crois pas :-)

VB





dans mon module, la classe string qui doit recevoir les donnees alloue
de la memoire pour mettre la chaine. je retiens ladresse allouer au
debuggage,
et a la destruction de mon objet qui contient cette string, l'adresse est
toujours la meme mais l'erreur generee est dans _CrtIsValidHeapPointer.

donc c'est tres possible que cela vienne de segfault avant mais le post
plus
haut parle aussi d'impossibilite de delete de la memoire allouer par un
module
ailleur que dans ce module.je vais donc en lire plus dessus avant de
continuer
mais je pense quand meme avoir compris.



--
Lucas
Montes
Avatar
ouech
Le Mon, 7 Feb 2005 10:50:04 +0100, Vincent Burel
a écrit:


"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
a écrit:

> - bon primo, dans la gestion d'une communication client / serveur, il
> faut
> éviter de faire un thread par client. En général 2 thread suffisent,
un
> thread de management des requetes et un thread de service pour
> login/logout
> des clients.
>

apache lance plusieur process au demarrage avec plusieur threads en


attente
dans chaque process. quand un nouveau client se connecte, il traite sa
requete
dans une thread (une thread par client) qui attendait dans un process.
alors c
sur que c bien plus rapide que de creer une thread a la connection du
client mais
pour gerer beaucoup de connexions (serveur web par exemple), le select
ne
suffit
plus vraiment.



C'est vous qui le dites, moi je dis qu'une thread par flux ca suffit et
que
plusieurs thread sur le même flux, ca sert à rien ,sinon à créer des
conflit
d'accès (et certainement ca facilite le travail du programmeur, m'enfin
bon,
un bon programmeur se doit plutot de faciliter le travail de la machine,
pas
le sien :-).



humm maintenir des threads en attente dans plusieurs processus ne facilite
pas du tout l'implementation surtout comparer a un select. j'ai peu
d'experience
dans la prog systeme mais je pense pas que les programmeurs d'apache ai
voulut
se faciliter la tache :)

Si vous avez deux flux, donc deux carte ethernet, alors oui,
dans ce cas un thread par carte ca a du sens...




c possible je ne peut pas contredire :)

--
Lucas
Montes
Avatar
Vincent Burel
"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 11:03:46 +0100, Vincent Burel
a écrit:

>
> "ouech" wrote in message
> news:
>> Le Mon, 7 Feb 2005 09:54:22 +0100, Vincent Burel
>> a écrit:
>>
>>
>> bah en fait le probleme vient surtout du faite que la memeoire allouer
>> par un module loader dynamiquement semble ne plus etre valide ailleur,
>
> impossible sans erreur de votre part.
>

bah vous semblez dire le contraire dans le post dll allocation de memoire.



pas du tout, dans cet autre post je parle d'organisation, et je dis
grossomodo que si un objet alloue de la mémoire, il faudra que ce même objet
la libère... mais je ne dis pas que de la mémoire allouée dans la DLL A
n'est pas accessible à une DLL B du même processus.

D'ailleurs Process, Thread, et DLL sont dans le même espace d'adressage. Par
conséquent chacun peut accéder à toute mémoire statique ou dynamique créer
par l'un ou par l'autre.

En conséquence de quoi, vous ne pouvez pas avoir de problème de validiter de
mémoire dans une application Win32. Sauf erreur de votre part.

VB
Avatar
Vincent Burel
"ouech" wrote in message
news:
Le Mon, 7 Feb 2005 10:50:04 +0100, Vincent Burel
a écrit:

humm maintenir des threads en attente dans plusieurs processus ne facilite
pas du tout l'implementation surtout comparer a un select. j'ai peu
d'experience
dans la prog systeme mais je pense pas que les programmeurs d'apache ai
voulut
se faciliter la tache :)



Ben c'est pas sur ! :-) de même j'ai du mal a croire que de tel serveur
utilise une couche socket, pas vraiment concu pour gérer des gros débits de
connection.... d'un autre côté, l'expérience montre que tout est possible en
informatique, surtout du côté du pire :-)

VB
1 2