crash calling proc with xml from a librarythread

Just starting out? Need help? Post your questions and find answers here.
Lukaso
User
User
Posts: 20
Joined: Fri Apr 29, 2005 11:53 am
Location: Germany
Contact:

crash calling proc with xml from a librarythread

Post by Lukaso »

hi guys,

i have a problem (probably a logical one) from calling some procedures from a dll that are stored in the mainexe (small plugininterface). i use more than 100 procedures without problems but this xml stuff is makes my crazy :cry:.

some code for testing purposes:

test.exe

Code: Select all

EnableExplicit

Structure uGWCoreOption
  sFile.s
  hXML.l
  hRootNode.l
  hMainNode.l
EndStructure

Define uGWCoreOption.uGWCoreOption

Procedure.b GWCoreOptionClose()
  Shared uGWCoreOption
  Protected bReturn.b = #False
  With uGWCoreOption
    If \hXML
      FreeXML(\hXML)
      \hXML = #Null
      \hRootNode = #Null
      \hMainNode = #Null
      bReturn = #True
    EndIf
  EndWith
  ProcedureReturn bReturn
EndProcedure

Procedure.b GWCoreOptionSave()
  Shared uGWCoreOption
  Protected bReturn.b = #False
  With uGWCoreOption
    If \hXML
      FormatXML(\hXML, #PB_XML_WindowsNewline | #PB_XML_ReduceNewline | #PB_XML_ReIndent)
      SaveXML(\hXML, \sFile, #PB_XML_StringFormat)
    EndIf
  EndWith
  ProcedureReturn bReturn
EndProcedure

Procedure.l GWCoreOptionInit()
  Shared uGWCoreOption
  With uGWCoreOption
    \sFile = "test.xml"
    \hXML = LoadXML(#PB_Any, \sFile, #PB_Unicode)
    If \hXML
      If XMLStatus(\hXML) = #PB_XML_Success
        \hRootNode = RootXMLNode(\hXML)
        \hMainNode = MainXMLNode(\hXML)
        If Not \hRootNode Or Not \hRootNode Or Not GetXMLNodeName(\hMainNode) = "gwcore"
          GWCoreOptionClose()
        EndIf
      Else
        GWCoreOptionClose()
      EndIf
    EndIf
    If Not \hXML
      DeleteFile(\sFile)
      \hXML = CreateXML(#PB_Any, #PB_Unicode)
      If \hXML
        \hRootNode = RootXMLNode(\hXML)
        \hMainNode = CreateXMLNode(\hRootNode)
        SetXMLNodeText(CreateXMLNode(\hRootNode, 0, #PB_XML_Comment), "gwcore preference file, manual editing can cause instability and crashes")
        SetXMLNodeName(\hMainNode, "gwcore")
        GWCoreOptionSave()
      EndIf
    EndIf
    ProcedureReturn \hXML
  EndWith
EndProcedure

Procedure.l GWCoreOptionGetModuleNode(sModule.s, bCreate.b = #False)
  Shared uGWCoreOption
  Protected lReturn.l = #Null, *lNode.l, lNode.l
  With uGWCoreOption
    If \hXML
      Repeat
        lNode + 1
        *lNode = XMLNodeFromPath(\hMainNode, "module[" + Str(lNode) + "]")
        If *lNode And GetXMLAttribute(*lNode, "name") = sModule
          lReturn = *lNode
          Break
        EndIf
      Until Not *lNode
      If Not lReturn And bCreate
        lReturn = CreateXMLNode(\hMainNode)
        SetXMLNodeName(lReturn, "module")
        SetXMLAttribute(lReturn, "name", sModule)
        GWCoreOptionSave()
      EndIf
    EndIf
  EndWith
  ProcedureReturn lReturn
EndProcedure

Procedure.b GWCoreOptionSetValueS(sModule.s, sName.s, sValue.s)
  Protected bReturn.b = #False, *lMainNode.l, *lNode.l
  *lMainNode = GWCoreOptionGetModuleNode(sModule)
  If *lMainNode
    *lNode = XMLNodeFromPath(*lMainNode, sName)
    If Not *lNode
      *lNode = CreateXMLNode(*lMainNode)
      SetXMLNodeName(*lNode, sName)
    EndIf
    If *lNode
      SetXMLNodeText(*lNode, sValue)
      GWCoreOptionSave()
      bReturn = #True
    EndIf
  EndIf
  ProcedureReturn bReturn
EndProcedure

GWCoreOptionInit()

OpenLibrary(0, "test.dll")
CallCFunction(0, "test", @GWCoreOptionSetValueS())

Delay(1000)

CloseLibrary(0)
test.dll

Code: Select all

Prototype.b GWCoreOptionSetValueS(sModule.s, sName.s, sValue.s)
Global GWCoreOptionSetValueS.GWCoreOptionSetValueS

EnableExplicit

Procedure Thread(lDummy.l)
  GWCoreOptionSetValueS("gwpp", "load", "true") ; <<< crash
EndProcedure

ProcedureDLL.l test(hProc.l)
  GWCoreOptionSetValueS = hProc
  
  ;CreateThread_(0, 0, @Thread(), 0, 0, 0)
  CreateThread(@Thread(), 0)

  ;GWCoreOptionSetValueS("gwpp", "load", "true") ; <<< works without problems

  Delay(100)
  ProcedureReturn #True
EndProcedure
Using GWCoreOptionSetValueS directly in the dll proc test() works but in a thread created in the dll i got a crash and i dont know why :(

i hate errors (mostly logical failure) that i can not explain myself.

thanks for helping :D
Last edited by Lukaso on Fri Aug 29, 2008 9:25 pm, edited 3 times in total.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You haven't given us any code we can run! Missing the procedure : GWCoreOptionGetModuleNode() !
I may look like a mule, but I'm not a complete ass.
Lukaso
User
User
Posts: 20
Joined: Fri Apr 29, 2005 11:53 am
Location: Germany
Contact:

Post by Lukaso »

sorry, deleted too much :lol:
edited ;)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Okay, this has nothing to do with the xml library. It is a string / threadsafety issue and I suspect a bug with PB. I am guessing that with the threadsafety switch, there may be some confusion between the two heaps used to store strings (one for the client, one for the dll) caused by thread local storage, although I will concede that Fred may simply say that we are doing something here which PB isn't designed to do. :wink:

Let me hack up a simple example which shows the problem and then we can think about a bug report.
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 »

Okay here is an example which shows the problem.

Set the threadsafety switch for both client and dll.


"test.dll" - compile to a dll.

Code: Select all

;Ensure threadsafe switch is enabled.

Prototype ClientFunction() 
  Global gClient.ClientFunction

Procedure Thread(lDummy.l) 
  gClient()
EndProcedure 

ProcedureDLL.l test(hProc.l) 
  gClient = hProc
  CreateThread(@Thread(), 0) 
  ProcedureReturn #True 
EndProcedure
"client.pb"

Code: Select all

;Ensure threadsafe switch is enabled.

Procedure ClientFunction() 
  a$=Str(10)  ;Crash here!
EndProcedure 

OpenLibrary(0, "test.dll") 
CallCFunction(0, "test", @ClientFunction()) 

Delay(1000) 

CloseLibrary(0)
The program is crashing at the first string manipulation (in this case the only such manipulation) within the client function called by the thread instigated in the dll.

The more I think about it the more I suspect that somehow the various string buffers are becoming 'entwined' because of various instance (module) variables. I'd certainly be interested in finding out! :)

The question now is whether we file a bug report?
Last edited by srod on Sat Aug 30, 2008 4:34 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
Lukaso
User
User
Posts: 20
Joined: Fri Apr 29, 2005 11:53 am
Location: Germany
Contact:

Post by Lukaso »

srod wrote:The question now is whether we file a bug report?
A fix in 4.30 would be nice ... big parts of my project using this :cry:
*need small workaround* :roll:

Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Workaround : Shift all functions called within the thread into the dll or create the thread in the client program.

Shall I make the bug report or would you rather?
I may look like a mule, but I'm not a complete ass.
Lukaso
User
User
Posts: 20
Joined: Fri Apr 29, 2005 11:53 am
Location: Germany
Contact:

Post by Lukaso »

srod wrote:Workaround : Shift all functions called within the thread into the dll or create the thread in the client program.

Shall I make the bug report or would you rather?
I think your english is better and you have more technical expirience :wink:
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Okay. :)
I may look like a mule, but I'm not a complete ass.
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

srod wrote:Okay here is an example which shows the problem.
Maybe I'm missing something but your client function take a parameter ("Procedure ClientFunction(a) "), but it's not being called with one ("gClient()").

Edit: I've read the bug report, so ignore what I said about stack corruption causing the crash. It's still there though :)
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes, I altered the source so many times whilst testing that I obviously mixed up the dll and client from two different tests! :roll:

I have altered the post above now, but as you say; the problem remains! :)
I may look like a mule, but I'm not a complete ass.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

quidquid Latine dictum sit altum videtur
Post Reply