Results 1 to 9 of 9

Thread: [RESOLVED] Um, why is this crashing?

  1. #1

    Thread Starter
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Resolved [RESOLVED] Um, why is this crashing?

    This crashes VB when I run it. This is the line that I have found to be the problem.

    vbexStreamHandler.cls
    ProcessStream()
    vb Code:
    1. objStream.Value = Stream()

    I'm attaching the project.

    I placed a breakpoint in the Property Let Value() procedure in the vbexByteArray class, and it doesn't even get that far.
    Attached Files Attached Files

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: Um, why is this crashing?

    this is the line where error occurs
    Code:
    Public Sub ProcessStream(ByVal Index As Long, ByRef Stream() As Byte)
        
        Dim objStream As vbexByteArray, lonPos As Long
        Dim bytParams() As Byte, lonParams As Long
        Dim lonHeaderLength As Long, bytHeader() As Byte
        
        'Header information
        Dim sinVersion As Single, sinHeader As Single
        Dim lonParamCount As Long, varTypes() As VbVarType
        Dim lonLengths() As Long, bolEncrypted As Boolean
        Dim lonDataLength As Long
        
        Set objStream = New vbexByteArray
        
         objStream.Value = Stream()
        
        'Version        Header      Parameters      Types       Lengths     Encrypted?      Data
        '4 bytes        4 bytes     4 bytes         4*Params    4*Params    2 bytes
    but you know that already
    Last edited by westconn1; Jun 20th, 2009 at 05:45 AM.
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  3. #3
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Um, why is this crashing?

    While I fail to figure out the actual cause of the crash, I can see that you could simply use a non-class byte array solution instead.

    These should get you started:
    Code:
    Option Explicit
    
    Private Declare Function ArrayPtr Lib "msvbvm60" Alias "VarPtr" (ByRef Ptr() As Any) As Long
    Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Ptr As Long, ByRef Value As Long)
    Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Ptr As Long, ByVal Value As Long)
    
    Public Sub AppendBytes(ByRef ByteArray() As Byte, ParamArray Data())
        Dim blnInit As Boolean, bytData() As Byte
        Dim lngA As Long, lngB As Long, lngBound As Long, lngHeader(5) As Long, lngPtr As Long
        blnInit = Not Not ByteArray
        Debug.Assert App.hInstance
        If blnInit Then
            lngHeader(0) = 1
            lngHeader(1) = 1
            PutMem4 ArrayPtr(bytData), VarPtr(lngHeader(0))
            For lngA = 0 To UBound(Data)
                lngBound = UBound(ByteArray)
                Select Case VarType(Data(lngA))
                    Case vbByte
                        ReDim Preserve ByteArray(lngBound + 1)
                        ByteArray(lngBound + 1) = Data(lngA)
                    Case vbBoolean, vbInteger
                        ReDim Preserve ByteArray(lngBound + 2)
                        ByteArray(lngBound + 1) = Data(lngA) And &HFF
                        ByteArray(lngBound + 2) = (Data(lngA) And &HFF00&) \ &H100&
                    Case vbLong
                        Dim lngData As Long
                        lngData = Data(lngA)
                        lngHeader(3) = VarPtr(lngData)
                        lngHeader(4) = 4
                        ReDim Preserve ByteArray(lngBound + 4)
                        ByteArray(lngBound + 1) = bytData(0)
                        ByteArray(lngBound + 2) = bytData(1)
                        ByteArray(lngBound + 3) = bytData(2)
                        ByteArray(lngBound + 4) = bytData(3)
                    Case vbSingle
                        Dim sngData As Single
                        sngData = Data(lngA)
                        lngHeader(3) = VarPtr(sngData)
                        lngHeader(4) = 4
                        ReDim Preserve ByteArray(lngBound + 4)
                        ByteArray(lngBound + 1) = bytData(0)
                        ByteArray(lngBound + 2) = bytData(1)
                        ByteArray(lngBound + 3) = bytData(2)
                        ByteArray(lngBound + 4) = bytData(3)
                    Case vbCurrency
                        Dim curData As Currency
                        curData = Data(lngA)
                        lngHeader(3) = VarPtr(curData)
                        lngHeader(4) = 8
                        ReDim Preserve ByteArray(lngBound + 8)
                        ByteArray(lngBound + 1) = bytData(0)
                        ByteArray(lngBound + 2) = bytData(1)
                        ByteArray(lngBound + 3) = bytData(2)
                        ByteArray(lngBound + 4) = bytData(3)
                        ByteArray(lngBound + 5) = bytData(4)
                        ByteArray(lngBound + 6) = bytData(5)
                        ByteArray(lngBound + 7) = bytData(6)
                        ByteArray(lngBound + 8) = bytData(7)
                    Case vbDate, vbDouble
                        Dim dblData As Double
                        dblData = Data(lngA)
                        lngHeader(3) = VarPtr(dblData)
                        lngHeader(4) = 8
                        ReDim Preserve ByteArray(lngBound + 8)
                        ByteArray(lngBound + 1) = bytData(0)
                        ByteArray(lngBound + 2) = bytData(1)
                        ByteArray(lngBound + 3) = bytData(2)
                        ByteArray(lngBound + 4) = bytData(3)
                        ByteArray(lngBound + 5) = bytData(4)
                        ByteArray(lngBound + 6) = bytData(5)
                        ByteArray(lngBound + 7) = bytData(6)
                        ByteArray(lngBound + 8) = bytData(7)
                    Case vbByte Or vbArray
                        lngHeader(4) = UBound(Data(lngA)) - LBound(Data(lngA)) + 1
                        If lngHeader(4) Then
                            GetMem4 VarPtr(Data(lngA)) + 8, lngPtr
                            GetMem4 lngPtr, lngPtr
                            GetMem4 lngPtr + 12, lngHeader(3)
                            ReDim Preserve ByteArray(lngBound + lngHeader(4))
                            For lngB = 0 To lngHeader(4) - 1
                                ByteArray(lngBound + lngB + 1) = bytData(lngB)
                            Next lngB
                        End If
                    Case vbBoolean Or vbArray, vbInteger Or vbArray
                        lngHeader(4) = (UBound(Data(lngA)) - LBound(Data(lngA)) + 1) * 2
                        If lngHeader(4) Then
                            GetMem4 VarPtr(Data(lngA)) + 8, lngPtr
                            GetMem4 lngPtr, lngPtr
                            GetMem4 lngPtr + 12, lngHeader(3)
                            ReDim Preserve ByteArray(lngBound + lngHeader(4))
                            For lngB = 0 To lngHeader(4) - 1
                                ByteArray(lngBound + lngB + 1) = bytData(lngB)
                            Next lngB
                        End If
                    Case vbLong Or vbArray, vbSingle Or vbArray
                        lngHeader(4) = (UBound(Data(lngA)) - LBound(Data(lngA)) + 1) * 4
                        If lngHeader(4) Then
                            GetMem4 VarPtr(Data(lngA)) + 8, lngPtr
                            GetMem4 lngPtr, lngPtr
                            GetMem4 lngPtr + 12, lngHeader(3)
                            ReDim Preserve ByteArray(lngBound + lngHeader(4))
                            For lngB = 0 To lngHeader(4) - 1
                                ByteArray(lngBound + lngB + 1) = bytData(lngB)
                            Next lngB
                        End If
                    Case vbCurrency Or vbArray, vbDate Or vbArray, vbDouble Or vbArray
                        lngHeader(4) = (UBound(Data(lngA)) - LBound(Data(lngA)) + 1) * 8
                        If lngHeader(4) Then
                            GetMem4 VarPtr(Data(lngA)) + 8, lngPtr
                            GetMem4 lngPtr, lngPtr
                            GetMem4 lngPtr + 12, lngHeader(3)
                            ReDim Preserve ByteArray(lngBound + lngHeader(4))
                            For lngB = 0 To lngHeader(4) - 1
                                ByteArray(lngBound + lngB + 1) = bytData(lngB)
                            Next lngB
                        End If
                    Case vbString
                        lngHeader(4) = LenB(Data(lngA))
                        If lngHeader(4) Then
                            lngHeader(3) = StrPtr(Data(lngA))
                            ReDim Preserve ByteArray(lngBound + lngHeader(4))
                            For lngB = 0 To lngHeader(4) - 1
                                ByteArray(lngBound + lngB + 1) = bytData(lngB)
                            Next lngB
                        End If
                End Select
            Next lngA
            PutMem4 ArrayPtr(bytData), 0
        End If
    End Sub
    
    Public Property Get MidBytes(ByRef ByteArray() As Byte, ByVal Start As Long, Optional ByVal Length As Long) As Byte()
        Dim blnInit As Boolean, bytMid() As Byte, lngHeader(5) As Long, lngMaxLen As Long
        blnInit = Not Not ByteArray
        Debug.Assert App.hInstance
        If blnInit Then
            lngMaxLen = UBound(ByteArray) - LBound(ByteArray) + 1
            If Length = 0 Then
                Length = lngMaxLen - Start
            ElseIf Length + Start > lngMaxLen Then
                Length = lngMaxLen - Start
            End If
            If Length >= 0 Then
                lngHeader(0) = 1
                lngHeader(1) = 1
                lngHeader(3) = VarPtr(ByteArray(Start))
                lngHeader(4) = Length
                PutMem4 ArrayPtr(bytMid), VarPtr(lngHeader(0))
                MidBytes = bytMid
                PutMem4 ArrayPtr(bytMid), 0
            End If
        End If
    End Property
    Usage samples:
    Code:
    Private Sub Form_Load()
        Dim bytTest() As Byte, intTest(2) As Integer
        bytTest = "Did you know test"
        intTest(0) = 65
        intTest(1) = 66
        intTest(2) = 67
        AppendBytes bytTest, "ing is great", AscW("!"), &H420041, &H440043, intTest
        Debug.Print MidBytes(bytTest, 26)
    End Sub

  4. #4
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Um, why is this crashing?

    I've not found the error, but I've found what might be another one...

    (vbexByteArray::Append)
    Code:
                Case vbByte Or vbArray 'Byte array
                    bytData = Data(l)
                    lonLBData = LBound(bytData)
                    lonUBData = UBound(bytData)
                    
                    lonDataLen = lonUBData - lonLBData + 1 '<--added + 1 
                    
    '                If lonLBData = 0 Then 
    '                    lonDataLen = lonDataLen + 1   <-- no need
    '                End If
                    
                    ReDim Preserve m_Data(1 To lonUB + lonDataLen) As Byte
                    CopyMemory m_Data(lonUB + 1), bytData(lonLBData), lonDataLen
    Redundant if you go with Merri's suggestion

    I'm sure your aware that a mistake with RtlMoveMemory is by far the most likely source of the crash. If some memory has been corrupted a crash does not always happen straight away. I count 11 calls to it before the crash occurs.

  5. #5
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Um, why is this crashing?

    No feature updates to the code, but a shorter version of AppendBytes with some comments:
    Code:
    Public Sub AppendBytes(ByRef ByteArray() As Byte, ParamArray Data())
        Dim blnInit As Boolean, bytData() As Byte
        Dim lngA As Long, lngB As Long, lngBound As Long, lngHeader(5) As Long, lngPtr As Long
        Dim lngDataLen As Long, vvtData As VbVarType
        blnInit = Not Not ByteArray
        Debug.Assert App.hInstance
        If Not blnInit Then ByteArray = vbNullString
        lngHeader(0) = 1
        lngHeader(1) = 1
        PutMem4 ArrayPtr(bytData), VarPtr(lngHeader(0))
        For lngA = 0 To UBound(Data)
            lngBound = UBound(ByteArray)
            vvtData = VarType(Data(lngA))
            If vvtData And vbArray Then
                ' is an array: figure out length of data
                Select Case vvtData And Not vbArray
                    Case vbByte
                        lngDataLen = 1
                    Case vbBoolean, vbInteger
                        lngDataLen = 2
                    Case vbLong, vbSingle
                        lngDataLen = 4
                    Case vbCurrency, vbDate, vbDouble
                        lngDataLen = 8
                    Case Else
                        lngDataLen = 0
                End Select
                ' calculate length of data
                lngHeader(4) = (UBound(Data(lngA)) - LBound(Data(lngA)) + 1) * lngDataLen
                ' if we got data...
                If lngHeader(4) Then
                    ' get pointer to array variable from a Variant
                    GetMem4 VarPtr(Data(lngA)) + 8, lngPtr
                    ' get pointer to safe array header from the array variable
                    GetMem4 lngPtr, lngPtr
                    ' get pointer to array's data
                    GetMem4 lngPtr + 12, lngHeader(3)
                    ' reserve memory & copy bytes
                    ReDim Preserve ByteArray(lngBound + lngHeader(4))
                    For lngB = 0 To lngHeader(4) - 1
                        ByteArray(lngBound + lngB + 1) = bytData(lngB)
                    Next lngB
                End If
            Else ' not an array
                Select Case vvtData
                    Case vbByte
                        Dim bytData2 As Byte
                        bytData2 = Data(lngA)
                        lngHeader(3) = VarPtr(bytData2)
                        lngHeader(4) = 1
                    Case vbBoolean, vbInteger
                        Dim intData As Integer
                        intData = Data(lngA)
                        lngHeader(3) = VarPtr(intData)
                        lngHeader(4) = 2
                    Case vbLong
                        Dim lngData As Long
                        lngData = Data(lngA)
                        lngHeader(3) = VarPtr(intData)
                        lngHeader(4) = 4
                    Case vbSingle
                        Dim sngData As Single
                        sngData = Data(lngA)
                        lngHeader(3) = VarPtr(sngData)
                        lngHeader(4) = 4
                    Case vbCurrency
                        Dim curData As Currency
                        curData = Data(lngA)
                        lngHeader(3) = VarPtr(curData)
                        lngHeader(4) = 8
                    Case vbDate, vbDouble
                        Dim dblData As Double
                        dblData = Data(lngA)
                        lngHeader(3) = VarPtr(dblData)
                        lngHeader(4) = 8
                    Case vbString
                        lngHeader(4) = LenB(Data(lngA))
                        If lngHeader(4) Then lngHeader(3) = StrPtr(Data(lngA))
                    Case Else
                        lngHeader(4) = 0
                End Select
                If lngHeader(4) Then
                    ReDim Preserve ByteArray(lngBound + lngHeader(4))
                    For lngB = 0 To lngHeader(4) - 1
                        ByteArray(lngBound + lngB + 1) = bytData(lngB)
                    Next lngB
                End If
            End If
        Next lngA
        PutMem4 ArrayPtr(bytData), 0
    End Sub
    Thought to leave the original for reference.
    Last edited by Merri; Jun 20th, 2009 at 03:50 PM. Reason: Even shorter and now allows for an uninitialized byte array to be passed.

  6. #6
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Um, why is this crashing?

    It is indeed due to use of CopyMemory. I made some comparisons and noticed that the Append function I provide gives quite different results.

    Code:
    Private Sub Form_Load()
        Dim bytTest() As Byte
        bytTest = vbNullString
        AppendBytes bytTest, 10.1, False, StrConv("Test!", vbFromUnicode)
        Debug.Print StrConv(bytTest, vbUnicode)
    End Sub
    This outputs: 333333$@ Test!

    Then I made the following changes in DigiRev's code:
    Code:
        Set objStream = New vbexStreamHandler
        bytPacket = objStream.BuildDatagram(10.1, False, "Test!")
    
        Debug.Print StrConv(bytPacket, vbUnicode)
    
        'objStream.ProcessStream 1, bytPacket
    And in BuildDatagram:
    Code:
    '12 bytes (version, header, and no. of parameters)
        objRet.Append m_Version, Header, Parameters(0)
        BuildDatagram = objRet.Value
        Exit Function
    And this outputs: š™!ATest!


    Tip: you can use a PropertyBag to easily store all kinds of data.

  7. #7
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Um, why is this crashing?

    Interesting
    RtlMoveMemory (aka CopyMemory) is not the source of the crash. If every instance is removed from the project including the declares the crash still happens at exactly the same spot. There is no other API and no extra references that I can see so it looks like its caused by pure VB

    BTW with the adjustment I posted I get this " š™!A   Test!" which I think is correct it's Sng(0),Sng(10.1),Lng(1),Lng(8),Lng(5),"Test!"

  8. #8

    Thread Starter
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Um, why is this crashing?

    Thanks for the suggestions. I think I might try Merri's code. I don't want to use a property bag because I like the way it's setup now. I really wish I knew why it's crashing, though. I might look at it in a debugger and try to figure out what's going on, but I'm not really an expert in that area.

    Thanks.

  9. #9
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: [RESOLVED] Um, why is this crashing?

    I don't know if it helps, but when you compile the application the memory location that points to the crash changes from 0x00000000 to 0x00133000. It indeed seems like some kind of a bug in VB6 at the moment, but why it happens is harder to tell.

    Oh and Milk, my error was that I didn't make sure the variable type was correct. I should have done like this:
    AppendBytes bytTest, CSng(10.1), CBool(False), StrConv("Test!", vbFromUnicode)

    Which then gives š™!A Test!


    I also updated the shorter version of AppendBytes to be even shorter.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width