Weird pointer problem

Everything else that doesn't fall into one of the other PB categories.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Weird pointer problem

Post by KarLKoX »

Hi !
I am currently working on a module userlib using the famous libmodplug engine. After fighting like a beast with the vc++ compiler, i get it working (or at least compilable) with purebasic without errors.
I ll explain the design of this userlib and telling you when the problem occurs :

C++ code :
------------

- i have a class wich manage libmodplug, for each module loaded, i create an instance and putting this instance in a vector,
- i have a class wich manage directsound, for each module loaded, i create an instance of a directsound buffer object, each directsound buffer object is attached to a libmodplug object instance (to play multiple modules simultaneously)

C code :
-------
- i have a C source code related to the API (ModuleInit, ModulePlay and so on ...) use to be called from purebasic, it works like this :
* moduleinit : here, i init directsound and i create a THREAD wich will loop for each module object loaded, if the object at pos n is playing, i call the update member of the directsound buffer object for the module object (simple hey ^_^)
* load a module (or multiple module),
* play module at index n (wich is the index inside the vector of module),

Then, to test my app, i ve coded a simple C example using winapi, all is working great without bugs (perhaps deadlocks ...).
Now, i am going to the purebasic part : i do exactly the same thing than the C example but when the update member function is called, the buffer locked consist of ZEROS !
I tried a lot of trick :

- i switch to the C DirectSound interface (IDirectSound_xxx),
- i ve added a usercallback wich is called to write the data,
- i dynamically load directsound function (typedef to func pointers ans using GetProcAddress).

All these trick worked with the C example and never with the purebasic one, i always get a buffer with zeros, the writecursor and playcursos are updated correctly by the directsound mixing manager so for me, it can only be a pointer issue.
But how can it be resolved ? I am searching for 2 nigths and i am really sick of that :(
Help would be GREATLY appreciated !! :D
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Re: Weird pointer problem

Post by traumatic »

Glad to hear you're going on! :)

Well, it's hard to tell by your description, at least for me that is.
I can assure you however that all the different DSound approaches you've
tried won't be not necessary. I already coded some DSound libraries for PB,
all of them using the standard (C++) way - they work.

Did you try using consolemode and printf() your vars in order to see where
the data gets lost? (hi fred ;))
without bugs (perhaps deadlocks ...)
lmao


EDIT: I remember having loads of problems whenever I used msvcrt
in conjunction with PB's debugger.
I finally ended up with either replacing the needed functions or linking
only the needed objects (like chkstk.obj etc.). Maybe this is also the
problem on your side?
Good programmers don't comment their code. It was hard to write, should be hard to read.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Hi Traumatic :D

I allready succesfully used dsound with PB before but my code was in pure C, the difference is that i use C++ now.
I am writing the buffer locked by dsound to a raw file (44100/16/2) : from the C sample, the file write the buffer correctly and is played with players (winamp, foobar2000 ...), from PB, the buffers contains only zeroes so the file is played but i can't hear sound :roll:
I also write a second file wich tell me the address of the pointers, their size, the write and play cursor and all are ok, modplug return me a correct number of bytes read. (even from the C example AND the purebasic example)
I tried to put the code thread withing pb (i thought i could be a thread issue) but again, without success :(
The only solution i see : writing the dsound stuff in PB but for a userlibrary, it is not the easier way to use a lib for the user.
Btw, thanx for your reply :D

Edit : i staticly link MSVPCRT.LIB (the C++ lib) and i use the MSVCRT from purebasic to resolve some symbol. (in the desc file)
I removed dsound dependency from the purebasic one (i got issue using the dsound compiled from vc++ with the one with purebasic)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

A big "hmm........" ...


I can't believe this is a DSound-issue. That can't be the problem, really.
There must be something else wrong (yes, so easy to say ;))
KarLKoX wrote:Edit : i staticly link MSVPCRT.LIB (the C++ lib) and i use the MSVCRT from purebasic to resolve some symbol. (in the desc file)
I removed dsound dependency from the purebasic one (i got issue using the dsound compiled from vc++ with the one with purebasic)
You're linking both libs? That could be the problem (and the main difference
between the c- and the pb-code if I got you right). Is there no other way to
get rid of the dependencies? Does the code work if you're linking both libs
in VC++ ?

How are you passing the buffer data? Is this an internal process (global) or
are you using functions for that? Does the function that writes the buffer to
file receive the data at all (maybe a silly question) ?


BTW: putting dsound as required dll in the .desc works just fine.
Good programmers don't comment their code. It was hard to write, should be hard to read.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Hi again :)
i MUST link MSVPCRT.LIB inside my lib to resolve all the C++ symbol : remeber that the compiler/linker used is C only so compiling my lib staticly with the C++ standart lib resolve all the symbols.
Last nigth, i ve adapted the DSound code to pb and i got the same pb !!!
I tried a lot of things and after a night without sleeping, i entered to a debuggin session, here is a direct live instance :

Code: Select all

Global tmp1, tmp2, tmp3
Procedure Sound_Update(ID, *object.SoundObject)
Protected *curSoundBuffer.IDirectSoundBuffer8
Protected playPos,unusedWriteCursor
Protected writeLen
Protected *p1,*p2  
Protected l1,l2

  *curSoundBuffer = *object\lpDirectSoundBuffer
  Result = *curSoundBuffer\GetCurrentPosition(@playPos, @unusedWriteCursor)
  If Result <> #DS_OK
    playPos = 0
  EndIf
  
  If *object\writepos < playPos
    writeLen = playPos - *object\writepos
  Else
    writeLen = #DSOUND_BUFFERSIZE - (*object\writepos - playPos)
  EndIf
  
  While *curSoundBuffer\Lock(*object\writepos, writeLen, @*p1, @l1, @*p2, @l2, 0) <> #DS_OK
    *curSoundBuffer\Restore()
    *curSoundBuffer\Play(0, 0, #DSBPLAY_LOOPING)
  Wend
; debug session
;   Pointeur=?DEBUT_C
;   If Pointeur<>? FIN_C
;     SetClipboardText("")
;     Repeat
;       CettePosition=Pointeur
;       Pointeur=DisASMCommand(Pointeur)
;       Debug Hex(CettePosition)+" - " + GetDisASMString()
;       SetClipboardText(GetClipboardText()+GetDisASMString()+Chr(13)+Chr(10))
;     Until Pointeur >= ?FIN_C
;   EndIf
;   End
; 
; *p1 = [esp+24] = $18 in hex
; *p2 = [esp+28] = $1C in hex
; l1  = [esp+32] = $20 in hex
; l2  = [esp+36] = $24 in hex

; disasm
; 402948 - PUSH 0200019F
; 40294D - CALL 00403A99
; 402952 - MOV Ebx,[esp+18]       ; if p1
; 402956 - CMP Ebx,00             ; > 0
; 402959 - JLE 0040296B           ; continue
; 40295B - MOV Ebx,[esp+20]       ; if l1
; 40295F - CMP Ebx,00             ; > 0
; 402962 - JLE 0040296B           ; continue
; 402964 - MOV Eax,00000001       ; -----
; 402969 - JMP 0040296D           ;       \
; 40296B - XOR Eax,Eax            ;        - if these two conditions are true   
; 40296D - And Eax,Eax            ; _____/
; 40296F - JZ 0040298C            ; continue
; 402971 - PUSH 020001A5
; 402976 - CALL 00403A99          ; (surely a call to a internal or generated pb func)
; 40297B - PUSH dword [esp+20]  <-- ok    : [esp+20] = l1
; 40297F - PUSH dword [esp+1C]  <-- error ! [esp+1C] = p2 it MUST be p1 ( must output [esp+$18] )
; 402983 - PUSH dword [esp+08]  <-- error ! [esp+08] = *curSoundBuffer it MUST be ID ( must output [esp] )
; 402987 - CALL 004079F0
; 40298C - PUSH 020001A6
; 402991 - CALL 00403A99          ; (surely a call to a internal or generated pb func)
  
;  DEBUT_C:
;  If (*p1 > 0) And (l1 > 0) 
    ; save esp values to variable to check if they are the good one
    ; here, it is OK
    ;mov eax, [esp+$18]
    ;mov tmp1, eax
    ;mov eax, [esp+$20]
    ;mov tmp2, eax
    ;Debug "TMP1 = " + Str(tmp1) + " TMP2 = " + Str(tmp2)
;    ModplugRead(ID, *p1, l1)
    ;WriteData(*p1, l1)
;  EndIf
;  FIN_C:
;   If ((*p2) And (l2>0)) 
;      ModplugRead(ID, *p2, l2)   
;      WriteData(*p2, l2)
;   EndIf

  If (*p1 > 0) And (l1 > 0)
    ; save esp values from the disasm to check what they are
    ; and here, they are not the good one ! (see up)
    ;mov eax, [esp+$08]
    ;mov tmp1, eax
    ;mov eax, [esp+$1C]
    ;mov tmp2, eax
    ;mov eax, [esp+$20]
    ;mov tmp3, eax    
    ;Debug "TMP1 = " + Str(tmp1) + " TMP2 = " + Str(tmp2) + " TMP3 = " + Str(tmp3)
    
    ; should be this !
    ; save esp values from the offset wich are the good one
    ; and the debug print the good params values
    ; this show that the disasm is wrong (it should output these esp values)
    ;mov eax, [esp+$00]
    ;mov tmp1, eax
    ;mov eax, [esp+$18]
    ;mov tmp2, eax
    ;mov eax, [esp+$20]
    ;mov tmp3, eax    
    ;Debug "TMP1 = " + Str(tmp1) + " TMP2 = " + Str(tmp2) + " TMP3 = " + Str(tmp3)    
    
    ; here i force purebasic to call ModPlugRead with the good esp value
    ; i push all on the stack
    !Extrn _PB_ModplugRead@12
    !push dword [esp+$20]       ; l1
    !push dword [esp+$18]       ; *p1
    !push dword [esp+$00]       ; ID
    !call _PB_ModplugRead@12
    ; here, i normaly should have a pointer full of data ( [esp+$18] = p1 )
    !mov eax, [esp+$18]
    !mov [v_tmp1], eax
    ; leave this
    ;ModplugRead(ID, *p1, l1)
    ; writing the p1 pointer result of a buffer full of zeroes :'(
    WriteData(tmp1, l1)
  EndIf
  If (*p2 > 0) And (l 2 >0)
    !push dword [esp+$24]       ; l2
    !push dword [esp+$1C]       ; *p2
    !push dword [esp+$00]       ; ID
    !call _PB_ModplugRead@12
    ;ModplugRead(ID, *p2, l2)
    !mov eax, [esp+$1C]
    !mov [v_tmp2], eax
    WriteData(tmp2, l2)
  EndIf

  *curSoundBuffer\UnLock(*p1, l1, *p2, l2)
  *object\writepos + writeLen
  
  If *object\writePos >= #DSOUND_BUFFERSIZE
    *object\writePos - #DSOUND_BUFFERSIZE
  EndIf
  

EndProcedure
I ve very little skills in asm, i just can read it, if you read my code, i call ModplugRead(ID, *p1, l1) but when i disasm this, pb push on the stack *p2
I ve tested with dsound required in the desc file and without (i resolve the symbols by dymanicly call dsound.dll).
I really can't understand why all this happen :(
Last edited by KarLKoX on Wed May 18, 2005 9:50 pm, edited 4 times in total.
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

*double post*
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

I ve very little skills in asm, i just can read it, if you read my code, i call ModplugRead(ID, *p1, l1) but when i disasm this, pb push on the stack *p2
I really can't understand why all this happen
The stack pointer 'esp' is altered by each 'push' instruction, this means that the offset from the stack pointer is also changed. The PB asm output seems ok to me..

What does the function 'ModplugRead()' expect as input anyway?
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

ah, ok :)
The first argument is the ID of the module to play (just the index inside a vector class), a pointer to fill (*p1 and *p2 returned by the lock dsound func) and the len to write.
ModplugRead() call the internal libmodplug func ModPlug_Read.
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

KarLKoX wrote:ah, ok :)
The first argument is the ID of the module to play (just the index inside a vector class), a pointer to fill (*p1 and *p2 returned by the lock dsound func) and the len to write.
ModplugRead() call the internal libmodplug func ModPlug_Read.
Are you positively sure that you shouldn't call ModPlugRead() with something like this instead?

Code: Select all

ModPlugRead(ID, @*p1, l1)
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

No, it will crash (and it crach) if i put the address of the pointer
Btw, i don't think this is related to my code because when i used the C++ code wich manage the sound, all was working from the C sample, in PB i only called ModulePlay(index) wich only set the status of a module to begin playback, all the thing was internaly done in the lib (C++ code), there were no variables from PB to the lib needed to be passed. (like the native PB module lib)
This is why i thought it should be a pointer problem and not coding problem :)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

KarLKoX wrote:No, it will crash (and it crach) if i put the address of the pointer
Btw, i don't think this is related to my code because when i used the C++ code wich manage the sound, all was working from the C sample, in PB i only called ModulePlay(index) wich only set the status of a module to begin playback, all the thing was internaly done in the lib (C++ code), there were no variables from PB to the lib needed to be passed.
This is why i thought it should be a pointer problem and not coding problem :)
OK, and now i'm fresh out of ideas :) Ah one last try, you think it might have something to do with C calling convention versus std calling convention? Well for all i know it could be anything, really! ;)
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

Would you mind posting your VC++ project files?

...this is so "virtual" to debug via forums... ;)


Hmm... still my old question: When you say it works from C, are you using
exactly the same library (.obj/.lib) ?
Good programmers don't comment their code. It was hard to write, should be hard to read.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Here is the sourcecode. (this is my first serious c++ code ^_^)

Traumatic>yes i am using exactly the same lib.
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

KarLKoX, just to make sure:

You say sample.exe works for you?
It writes out*.raw and fills the correct values in?

I didn't spent much time on it yet but for me it does nothing as it is.
CSoundServer::PlaySound() seems to fail already (Init was ok).

ModPlugRead in PB however told me it read something...

Only asking because I don't know where to start looking. ;)
Good programmers don't comment their code. It was hard to write, should be hard to read.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Don't take attention to the dsound c++ code, it is now hardcoded in pb (directsound.pb).
The important part to look in is all the PB_ModplugXXX functions in the main.cpp file and the directsound.pb file (especially Sound_Update and ThreadOut), Thanx for look in it :D
Btw, i am currently rewriting the code to pure C to see what append. (there is no more MSVPCRT.LIB dependency)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Post Reply