Page 1 sur 1

bug sur boucle for-next dans une proc ?

Publié : lun. 18/avr./2005 0:32
par filperj
C'est un code de delta69 (qui se demande pourquoi ça marche pas), et ya un truc qui me perturbe:

Regardez la ligne 109 "For x=1 To 2", et le "Next" correspondant ligne 130, et regardez le code assembleur généré.

Code : Tout sélectionner

CallDebugger



Procedure.l ansi2bstr(ansi.s)
  size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0)
  Dim unicode.w(size)
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), size)
  ProcedureReturn SysAllocString_(@unicode())
EndProcedure

Procedure.s unicode2ansi(mem)
  ansi.s=""
  Repeat
    a=PeekW(mem)
    ansi=ansi+Chr(a)
    mem+2
  Until a=0
  ProcedureReturn ansi
EndProcedure


; ------------------------------------------------------------
; OS_info
; ------------------------------------------------------------



;_______________ données_________________________

DataSection
CLSID_WbemLocator:
    ;4590f811-1d3a-11d0-891f-00aa004b2e24
Data.l $4590F811
Data.w $1D3A, $11D0
Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24
IID_IWbemLocator:
    ;dc12a687-737f-11cf-884d-00aa004b2e24
Data.l $DC12A687
Data.w $737F, $11CF
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
IID_IUnknown:
    ;00000000-0000-0000-C000-000000000046
Data.l $00000000
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IWbemRefresher:
;49353c99-516b-11d1-aea6-00c04fb68820
Data.l $49353C99
Data.w $516B, $11D1
Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
CLSID_WbemRefresher:
;c71566f2-561E-11D1-AD87-00C04FD8FDFF
Data.l $C71566F2
Data.w $561E, $11D1
Data.b $AD,$87,$00,$C0,$4F,$D8,$FD,$FF
IID_IWbemConfigureRefresher:
;49353c92-516b-11d1-aea6-00c04fb68820
Data.l $49353C92
Data.w $516B, $11D1
Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
IID_IWbemObjectAccess:
;49353c9a-516b-11d1-aea6-00c04fb68820
Data.l $49353C9A
Data.w $516B, $11D1
Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
EndDataSection


#COINIT_MULTITHREAD=0
#RPC_C_AUTHN_LEVEL_CONNECT=2
#RPC_C_IMP_LEVEL_IDENTIFY=2
#EOAC_NONE=0
#RPC_C_AUTHN_WINNT=10
#RPC_C_AUTHZ_NONE=0
#RPC_C_AUTHN_LEVEL_CALL=3
#RPC_C_IMP_LEVEL_IMPERSONATE=3
#CLSCTX_INPROC_SERVER=1
#WBEM_S_NO_ERROR = 0


Structure d
  l.l
  h.l
EndStructure

Procedure OS_info()



; ___________________ Initialisations __________________________

; partout, hres doit être nul si pas d'erreur

CoInitializeEx_(0,#COINIT_MULTITHREAD)
hres=CoInitializeSecurity_(0, -1,0,0,#RPC_C_AUTHN_LEVEL_CONNECT,#RPC_C_IMP_LEVEL_IDENTIFY,0,#EOAC_NONE,0)
hres=CoCreateInstance_(?CLSID_WbemLocator,0,#CLSCTX_INPROC_SERVER,?IID_IWbemLocator,@loc.IWbemLocator)
hres=loc\ConnectServer(ansi2bstr("root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices)
hres=svc\queryinterface(?IID_IUnknown,@pUnk.IUnknown)
hres=CoSetProxyBlanket_(svc,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE)
hres=CoSetProxyBlanket_(pUnk,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE)
pUnk\release()
hres=CoCreateInstance_(?CLSID_WbemRefresher,0,#CLSCTX_INPROC_SERVER,?IID_IWbemRefresher,@pRefresher.IWbemRefresher)
hres=pRefresher\queryinterface(?IID_IWbemConfigureRefresher,@pConfig.IWbemConfigureRefresher)
hres=pConfig\AddEnum(svc,ansi2bstr("Win32_OperatingSystem"),0,0,@penum.IWbemHiPerfEnum,@id)
pConfig\release()
Dim tab.IWbemObjectAccess(100)

For x=1 To 2 ; ici x est [esp+36]
  Debug x
  pRefresher\refresh(0)
  hres=penum\GetObjects(0,100*SizeOf(IWbemObjectAccess),@tab(),@retour.l)
  If x=1
    hres=tab(0)\GetPropertyHandle(ansi2bstr("Name"),0,@info)
  EndIf

  If x>1
    *MemoryID = AllocateMemory(500)
   For i=0 To retour-1
     tab(i)\Readpropertyvalue(info,500,@len,*MemoryID)
     result$=(unicode2ansi(*MemoryID))
     ZeroMemory_(*MemoryID,500)
     tab(i)\release()
   Next i
   FreeMemory(*MemoryID)
  EndIf

  Delay(500)

  Next x ; ici x devient [esp+48]
 
penum\release()
pRefresher\release();
svc\release()
loc\release()
CoUninitialize_()

MessageRequester("OS", result$, #MB_OK)

EndProcedure

;OS_info()

Publié : lun. 18/avr./2005 9:19
par Le Soldat Inconnu
Vois rien ...
Arf forcément, tu ne lances même pas la procedure dans ton code :lol:

bon, les lignes qui cause l'erreur sont celles-ci :

Code : Tout sélectionner

hres=tab(0)\GetPropertyHandle(ansi2bstr("Name"),0,@info)
tab(i)\Readpropertyvalue(info, 500, @len, MemoryID)
tab(i)\release()
après, c'est soit un débordement mémoire, soit une erreur avec les object

Publié : lun. 18/avr./2005 10:19
par delta69
Bonjour,

J'ai à l'origine posté mon problème dans une autre catégorie (http://purebasic.hmt-forum.com/viewtopic.php?t=2725).
Le code fonctionne bien hors d'une procédure, mais ne marche plus dans la proc...

Il y a peut être bien un débordement mémoire, mais le fait que ce soit bloquant dans un cas et pas dans l'autre me dépasse...

Merci pour vos réponses et votre aide !

Nicolas

Publié : lun. 18/avr./2005 10:46
par Le Soldat Inconnu
ben, avec les débordements mémoire, tout dépend de la variable qui est écrasée ou modifiée accidentellement

et entre la procedure et sans, l'organisation des variables n'est pas forcément la même

tu devrais vérifier la structure de PB avec la MSDN, j'ai déjà ce genre de prob et l'erreur venait de la

Publié : lun. 18/avr./2005 12:40
par filperj
Même s'il y a une erreur sur les structures, ça n'explique pas pourquoi la variable x change d'adresse :roll:

Publié : lun. 18/avr./2005 17:11
par Anonyme2
Ca marche en dehors d'une procédure car x et i deviennent des variables globales et non plus locale, d'ou pas de problème d'adresse.

Sur l'adressage de x avec esp + quelque chose, ça peut varier et être correct, tout dépend des mouvements de la pile; avec les interfaces, il y a au moins 2 push pour l'appel de chaque méthode et je pense qu'il doit y avoir un problème de restauration de la pile (au niveau de l'incrément du compteur que le compilateur utilise). Je n'ai pas tracé le code, j'ai juste regardé avec le debugger.

Je pense que filperj a raison, c'est un bug

Allez Fred, au boulot :D