Calling exported string functions - PB 4.2 beta 2

Just starting out? Need help? Post your questions and find answers here.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Calling exported string functions - PB 4.2 beta 2

Post by srod »

Hi,

this quite serious problem is shown in the generated ASM file, but first, if you wish to reproduce this bug, tailbite the following to create a simple userlib (or even create a dll instead) :

Userlib :

Code: Select all

ProcedureDLL.s HeyHo(a)
  Protected a$
  a$=Str(a)
  ProcedureReturn a$
EndProcedure
Now a client program :

Code: Select all

Procedure TEST_PROC() 
  tarea.s = HeyHo(100) 
  MessageRequester("Bloody hell's bells!", tarea) 
EndProcedure 

If OpenWindow(0,0,0,640,300,"Tally bally ho!",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Maximize|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  CreateMenu(0,WindowID(0)) 
  MenuTitle("test") 
  MenuItem(1, "testing") 
  Repeat 
    EventID = WaitWindowEvent() 
    If EventID=#PB_Event_Menu And  EventMenu()=1 
      TEST_PROC() 
    EndIf 
  Until EventID = #PB_Event_CloseWindow 
EndIf 
Run the client (after creating the userlib) and select the menu option. CRASH!

The problem is generated by the HeyHo(100) call in the TEST_PROC() procedure and would appear to be one of stack corruption.

The problem is quite easily seen in the ASM corresponding to the TEST_PROC() procedure; see the two instances of

Code: Select all

PUSH   dword [_PB_StringBasePosition]
ASM for the TEST_PROC() procedure.

Code: Select all

; :
; Procedure TEST_PROC() 
macro MP0{
_Procedure0:
  PS0=8
  XOR    eax,eax
  PUSH   eax                                                                                                                                                                                                                             
; tarea.s = HeyHo(100) 
  PUSH   dword [_PB_StringBasePosition]
  PUSH   dword [_PB_StringBasePosition]
  PUSH   dword 100
  CALL   PB_HeyHo
  LEA    ecx,[esp+4]
  POP    edx
  CALL   SYS_AllocateString
; MessageRequester("Bloody hell's bells!", tarea) 
  PUSH   dword [esp]
  PUSH   dword _S1
  CALL  _PB_MessageRequester@8
; EndProcedure 
  XOR    eax,eax
_EndProcedure1:
  PUSH   dword [esp]
  CALL  _SYS_FreeString@4
  ADD    esp,4
  RET
}
;
All of this runs fine with PB 4.1 and indeed the generated ASM file only has one instance of the PUSH dword [_PB_StringBasePosition] instruction in this case!
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Don't know if it's related, but it seems to also happen on a gosub:

Code: Select all

Gosub FindFileLocations
End

FindFileLocations:
	DeskTop$=GetSpecialFolderLocation(#CSIDL_DESKTOP)
Return
The GetSpecialFolderLocation command is from Droopy's library.

The crash happens on th return. :(
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I would guess that it is exactly the same problem.

Have a look at the ASM to see if the PUSH dword [_PB_StringBasePosition] instruction is duplicated?
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Is there an easy way in the PB IDE to generate the ASM file? I do this a lot and don't want to have to bother going to DOS and start typing, etc ...
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Guess you could create a tool for it.

I just use a simple batch file.
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Code: Select all

; Gosub FindFileLocations 
  CALL   l_findfilelocations
; End 
  JMP   _PB_EOP_NoValue
; 
; FindFileLocations: 
l_findfilelocations:
; DeskTop$=GetSpecialFolderLocation(#CSIDL_DESKTOP) 
  PUSH   dword [_PB_StringBasePosition]
  PUSH   dword [_PB_StringBasePosition]
  PUSH   dword 0
  CALL   PB_GetSpecialFolderLocation
  LEA    ecx,[v_DeskTop$]
  POP    edx
  CALL   SYS_AllocateString
; Return
  RET
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  CALL  _PB_FreeFiles@0
  CALL  _PB_FreeFonts@0
  CALL  _PB_FreeWindows@0
  CALL  _PB_FreeImages@0
  CALL  _PB_FreeLibraries@0
  CALL  _PB_FreeMemorys@0
  CALL  _PB_FreeNetworks@0
  CALL  _PB_FreeSimpleLists@0
  RET
Looks like it's the same problem!

I hope this one gets fixed fast, it could cause lots of unexpected problems all over the place.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

The double PUSH is on purpose (there is also a POP after the CALL if you look closely)
This should not affect the called library functions actually. There is no problem with our libraries.

Dunno why Tailbite libraries have a problem. We'll have to take a closer look.
quidquid Latine dictum sit altum videtur
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Ah, sorry I didn't notice the extra POP freak. Also I've tested a dll created with PB 4.2 beta 2 with essentially the code in my first post above, and it all works fine.

Could something have changed with PB 4.2 which Tailbite hasn't picked up on yet?
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Freak: It must be something behind the scenes like you said as version 4.2a4 produces the same visible ASM source code, but does not crash.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
Blue
Addict
Addict
Posts: 864
Joined: Fri Oct 06, 2006 4:41 am
Location: Canada

Post by Blue »

DoubleDutch wrote:Is there an easy way in the PB IDE to generate the ASM file? I do this a lot and don't want to have to bother going to DOS and start typing, etc ...
You can simply create a tool that will run the compiler, produce an executable (called PureBasic.exe !!! not my choice) and a commented source file called PureBasic.ASM, both saved in your PB file's directory:

line #1: D:\Basic\Pure\Compilers\PBCompiler.exe ( ...wherever it is on your machine.)
line #2: %FILE /COMMENTED
line #3: <empty>
line #4: Output ASM ( ... whatever name you prefer)

There must be an easy way to automatically rename the output to something other than the odd PureBasic.exe name, but I don't know it.
As well, I've found out that if you rename the asm source to something other than its default PureBasic.asm name, the compiler gets very unhappy with you when you attempt to re-assemble your modified asm source !!!
"That's not a bug..." said the programmer. "it's a feature! "
"Oh! I see..." replied the blind man.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

http://www.purebasic.fr/english/viewtopic.php?t=30843

:wink:

Actually, I might add this to the tricks and tips section.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

@Freak, I don't know if this will help get to the bottom of the problem with Tailbite and calling exported string functions through a procedure?

I tailbited the following small snippet whilst selecting the "Keep source files after making the library" option :

Code: Select all

ProcedureDLL.s Hey(a)
  a$="Heyho, I am "+Str(a) + " today!"
  ProcedureReturn a$
EndProcedure
Now delete the resulting user lib, but grab a copy of the resulting .lib file which Tailbite produces prior to creating the user lib.
I've uploaded a copy : Download 'HeyHo.lib'

Now, place the lib in a folder alongside the following program (which runs fine and produces the correct output) :

Code: Select all

Import "heyho.lib"
  Hey.l(a) As "PB_Hey"
EndImport

a = Hey(6)
a$=PeekS(a)
Debug a$
However, place the above program in a procedure and you'll see that the return string is duplicated :

Code: Select all

Import "heyho.lib"
  Hey.l(a) As "PB_Hey"
EndImport

Procedure.s Display()
  a = Hey(6)
  a$=PeekS(a)
  ProcedureReturn a$
EndProcedure

Debug Display()
As I say I don't know if this will be of any help, -but I see no harm in posting! :)

If you think this is a Tailbite problem rather than a PB one, please let me know and I'll dump this little lot on ABBKlaus ! :twisted:
I may look like a mule, but I'm not a complete ass.
Fred
Administrator
Administrator
Posts: 16616
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Seems to be a problem with tailbite, it now has to handle the double 'push' correctly or you will mess up the stack (that's probably why it runs in the main, but not in the procedure).
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

But, as Freak pointed out, the extra push is balanced with an extra pop after the call to the exported function etc.
I may look like a mule, but I'm not a complete ass.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

srod wrote:... the extra push is balanced with an extra pop ...
I don't understand this either. How (why) should Tailbite handle the extra PUSH if it is followed by a POP ?
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Post Reply