Linux threw this error.. Anyone see it before?

General FreeBASIC programming questions.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

Error in `./stat_builder': corrupted double-linked list: 0xbf849a50
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Linux threw this error.. Anyone see it before?

Post by St_W »

I haven't seen that error before, but according to this:
http://stackoverflow.com/a/14931301/4181989
it's some memory corruption caused by the program (most likely) or a bug in glibc (very unlikely).
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

It's a segfault, but I can't figure out how it's being triggered. It would take a lot of effort on someone else's end to replicate the conditions, but it happens on different machines, with different data being passed to the same function.

I'm batch processing some files, basically, and it calls to save the data to disk as part of the loop. On the 10th or 11th iteration, it throws that error. Always at the same time, with different data, different files etc..

At this point I've boxed off any null pointers, so I'm not seeing what the problem is.
petan
Posts: 683
Joined: Feb 16, 2010 15:34
Location: Europe
Contact:

Re: Linux threw this error.. Anyone see it before?

Post by petan »

No debugger ?...
My advice is simple (if complex problem somewhere) - manual pausing in every iteration, log values prior using them, simplify amount of data&types with block comments until whole empty data skeleton => and problem appeared IMHO.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

Debuggers are for ^&~* jobs. (j/k)

I'm running through the code now. I'll report what I find. The mere fact that it logs different types of errors should be an indication as to how odd this issue is.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Linux threw this error.. Anyone see it before?

Post by St_W »

Memory corruption very often causes weird errors. I'd also suggest using a debugger; e.g. QtCreator is a nice frontend for GDB on Linux. I don't know to what extent FBdebugger already supports Linux, but you may also try that one.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

I've gone over the code a dozen times now. The offending function creates a 30meg string which it then returns. It does not always throw a segfault, but occasionally it does, only in the instance where the string is greater than 10 megs. Even if I track down the error I'm not sure there's anything I can do about it.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Linux threw this error.. Anyone see it before?

Post by St_W »

rolliebollocks wrote:[..]The offending function creates a 30meg string which it then returns.[..]
You are talking about a FreeBasic application (no a FreeBasic library returning a FB string), are you?
Because there are some known problems or rather limitations with FB Strings.
//edit: the problem I was thinking of would leak memory and thus is not your problem. so forget what i've written above :-)
Instead you could compile a debug version of FB's rtlib if you suspect that the issue is not in your code, but the FB runtime. Link to that one instead of the FB default one. You're still out of luck if the compiler is generating faulty code (but that's rather unlikely).
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

I'm going to attempt to build the string a zstring ptr in order to eliminate that as a possibility. If that solves the problem I will try to come up with some sort of test which reproduces the segfault and then others (who understand the compiler better) can determine if it's a bug or not.

At this point I've eliminated the possibility that's a stack overflow or a memory management issue on my end (at least I believe so - lol).
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Linux threw this error.. Anyone see it before?

Post by dkl »

Would you like to post the (compilable) code that shows the problem? Memory corruption & co can be quite a pain, but I wouldn't mind running it through valgrind here, and I have a debug build of FB anyways, that could help.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

I reproduced the error. On 2 million iterations, the code works. On 4 million iterations it segfaults. I dunno.

Code: Select all

#ifndef NULL
#define NULL 0
#endif

#DEFINE DBLQUOTE ascii(34)

dim shared as string*1 ASCII(255)

    for i as integer = 0 to 255
        ASCII(i) = chr(i)
    next
    
function unEscape( byval s as string ) as string
    dim as string res = ""
    dim as integer i = 0
    dim as integer l = len( s ) - 1
    
    Do
        if s[i] = asc("\") andalso i < l then
            select case s[i+1]
            case 34  : res += ascii( 34 ) : i += 1
            case asc("/") : res += "/" : i += 1
            case asc("\") : res += "\" : i += 1
            case asc("b") : res += ascii( 8 ) : i += 1
            case asc("f") : res += ascii( 12 ) : i += 1
            case asc("n") : res += !"\n" : i += 1
            case asc("r") : res += !"\r" : i += 1
            case asc("t") : res += !"\t" : i += 1
            case asc("u") : res += ascii( s[i] ) : i += 2
            case else : res += ascii( s[i] ) : i += 1
            end select
        else
            res += ascii( s[i] )
        endif
        
        i += 1
        if i > l then exit do
    loop
    return res
end function

function IsWhite(c as ubyte) as integer
  if c=32 then return 1
  if c= 9 then return 1
  if c=10 then return 1
  if c=13 then return 1
  return 0
end function

function IsNumberJson(c as ubyte) as integer
  select case as const c
  case asc("0") to asc("9") : return 1
  case asc("-"), asc(".") : return 1
  end select
  return 0
end function

enum varType
  _MALFORMED_ = 0
  _NUMBER_    = 1
  _STRING_    = 2
  _BOOL_      = 3
  _ARRAY_     = 4
  _OBJECT_    = 5
  _NULL_      = 6
end enum

enum JSON_BOOL
    _FALSE_ = 0
    _TRUE_  = 1
end enum

type variable_ as variable

type varArray
    
    Public: 
        declare Destructor()
        declare sub add( byval item as variable_ ptr )
        declare function get( byval index as integer ) as variable_ ptr
        declare function getLength() as integer
        declare sub push( byval idx as integer, byval item as variable_ ptr )
        declare sub push( byval idx as integer, byref item as variable_ )
        declare sub pop( byval item as integer )
        declare sub push_back( byval item as variable_ ptr )
        declare sub clear()
            
        as integer size
        as variable_ ptr items(any)
        
end type

type varObjectField
    as string           key 
    as variable_ ptr    value
end type

type varObject

    Public:
    
        declare Destructor()
        declare sub add( byval key as string, byval item as variable_ ptr )
        declare function get( byval key as string ) as variable_ ptr
        declare function getKey( byval index as integer ) as string
        declare function getValue( byval index as integer ) as variable_ ptr
        declare function getSize() as integer
           
        as integer              size
        as varObjectField ptr   fields(any)

end type

type variable

    Public:
        declare Constructor()
        declare Constructor( byref rhs as variable )
        declare Constructor( byval json as string, byval n as string = "" )
        declare Constructor( byval n as double )
        declare Destructor()
        declare Operator Let( byref rhs as variable )
        declare Operator Let( byval json as string )
        declare Operator Let( byval n as double )
        
        declare sub         init( byval s as string, byval n as string = "" )
        
        declare function    getType() as string
        declare function    getTypeNum() as vartype
        declare function    toString() as string
      
        declare function    getNumber() as double
        declare function    getString() as string
        declare function    getBoolean() as integer
        declare function    getArray() as vararray ptr
        declare function    getObject() as varobject ptr

        as string           lbl
        as varType          typ
        as double           number
        as string           strng
        as integer          bool
        as varArray ptr     array
        as varObject ptr    object

end type

Destructor varArray()
    for i as integer = 0 to this.size-1
        delete items(i)
    next
End Destructor

sub varArray.add( byval item as variable_ ptr )
    size += 1
    redim preserve items(size-1)
    items(size-1) = new variable_
    *items(size-1) = *item
end sub

sub varArray.push( byval idx as integer, byval item as variable_ ptr )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
    
    redim preserve items( size )
    items( size ) = new variable_
    
    for i as integer = size-1 to idx step -1
        swap items(i), items(i+1)
    next i
    
    *items( idx ) = *item
    
    size += 1
end sub

sub varArray.push( byval idx as integer, byref item as variable_ )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
    
    redim preserve items( size )
    
    for i as integer = size-1 to idx step -1
        swap items(i), items(i+1)
    next i
    
    *items( idx ) = item
    
    size += 1
end sub

sub varArray.push_back( byval item as variable_ ptr )    
    redim preserve items( size )
    items( size ) = new variable_
    *items( size ) = *item
    size += 1
end sub

sub varArray.pop( byval idx as integer )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
    if size = 1 then 
        erase( items )
        size = 0
        exit sub
    endif
    
    for i as integer = idx+1 to size-1
        items(i-1) = items(i)
    next
   
    size -= 1
    redim preserve items( 0 to size-1 )        
end sub

sub varArray.clear()
    for i as integer = 0 to size-1
        delete items(i)
    next i
    erase items
    size = 0
end sub

function varArray.get( byval index as integer ) as variable_ ptr
    if index >= size or index < 0 then return NULL
    return items(index)
end function

function varArray.getLength() as integer
    return size
end function

Destructor varObject
    for i as integer = 0 to this.size-1
        delete fields(i)
    next i
end Destructor

sub varObject.add( byval key as string, byval item as variable_ ptr )
    size += 1
    redim preserve fields(size-1)
    fields(size-1) = new varObjectField
    fields(size-1)->key = key
    fields(size-1)->value = new variable_
    *fields(size-1)->value = *item
end sub

function varObject.get( byval key as string ) as variable_ ptr
    key = chr(34)+key+chr(34)
    for i as integer = 0 to size-1
        if fields(i)->key = key then return fields(i)->value
    next i
    return 0
end function

function varObject.getKey( byval index as integer ) as string
    return fields(index)->key
end function

function varObject.getValue( byval index as integer ) as variable_ ptr
    return fields(index)->value
end function

function varObject.getSize() as integer
    return size
end function

declare Operator = ( byref lhs as variable, byref rhs as variable ) as integer

Constructor variable()
end Constructor

Constructor variable( byref rhs as variable )
    this.lbl = rhs.lbl
    this.typ = rhs.typ
    
    select case rhs.typ
        case varType._BOOL_
            this.bool = rhs.bool
        case varType._NUMBER_ 
            this.number = rhs.number
        case varType._STRING_
            this.strng = rhs.strng
        case varType._OBJECT_
            this.object = new varObject
            redim this.object->fields( rhs.object->size - 1 )
            this.object->size = rhs.object->size
            if rhs.object->size then
                for i as integer = 0 to rhs.object->size - 1
                    this.object->fields(i) = new varObjectField
                    this.object->fields(i)->key = rhs.object->fields(i)->key
                    this.object->fields(i)->value = new variable
                    *this.object->fields(i)->value = *rhs.object->fields(i)->value
                next i
            end if
        case varType._ARRAY_
            this.array = new varArray
            if rhs.array->size then 
                redim this.array->items( rhs.array->size - 1 )
                this.array->size = rhs.array->size
                for i as integer = 0 to rhs.array->size - 1
                    this.array->items(i) = new variable
                    *this.array->items(i) = *rhs.array->items(i)
                next i
            end if
    end select
End Constructor

Operator variable.Let( byref rhs as variable )
    if @this <> @rhs then
        this.lbl = rhs.lbl
        this.typ = rhs.typ
        
        select case rhs.typ
            case varType._BOOL_
                this.bool = rhs.bool
            case varType._NUMBER_ 
                this.number = rhs.number
            case varType._STRING_
                this.strng = rhs.strng
            case varType._OBJECT_
                this.object = new varObject
                redim this.object->fields( rhs.object->size - 1 )
                this.object->size = rhs.object->size
                if rhs.object->size then
                    for i as integer = 0 to rhs.object->size - 1
                        this.object->fields(i) = new varObjectField
                        this.object->fields(i)->key = rhs.object->fields(i)->key
                        this.object->fields(i)->value = new variable
                        *this.object->fields(i)->value = *rhs.object->fields(i)->value
                    next i
                end if
            case varType._ARRAY_
                this.array = new varArray
                if rhs.array->size then
                    this.array->size = rhs.array->size
                    redim this.array->items( rhs.array->size - 1 )
                    for i as integer = 0 to rhs.array->size - 1
                        this.array->items(i) = new variable
                        *this.array->items(i) = *rhs.array->items(i)
                    next i
                end if
             case else
				'? "Something is #%$@"
        end select
    end if
end Operator

sub copy_variable( byref var1 as variable, byref var2 as variable )
    var1.lbl = var2.lbl
    var1.typ = var2.typ
    
    select case var2.typ
        case _BOOL_
            var1.bool = var2.bool
        case _NUMBER_ 
            var1.number = var2.number
        case _STRING_
            var1.strng = var2.strng
        case _OBJECT_
            var1.object = new varObject
            redim var1.object->fields( var2.object->size - 1 )
            for i as integer = 0 to var2.object->size - 1
                var1.object->fields(i) = new varObjectField
                var1.object->fields(i)->key = var2.object->fields(i)->key
                *var1.object->fields(i)->value = *var2.object->fields(i)->value
            next i
        case _ARRAY_
            var1.array = new varArray
            redim var1.array->items( var2.array->size - 1 )
            var1.array->size = var2.array->size
            
            for i as integer = 0 to var2.array->size - 1
                var1.array->items(i) = new variable
                *var1.array->items(i) = *var2.array->items(i)
            next i
    end select
end sub

Constructor variable( byval json as string, byval n as string = "" )
    init( json, n )
end Constructor

Constructor variable( byval num as double )
    this.typ = _NUMBER_
    this.number = num
end Constructor

Operator variable.Let( byval json as string )
	init( json )
end Operator

Operator variable.Let( byval num as double )
    this.typ = _NUMBER_
    this.number = num
end Operator

Operator = ( byref lhs as varObjectField, byref rhs as varObjectField ) as integer
    if lhs.key <> rhs.key then return 0
    if ( *lhs.value = *rhs.value ) = 0 then return 0
    return -1
end Operator

Operator = ( byref lhs as variable, byref rhs as variable ) as integer
    if lhs.typ <> rhs.typ then return 0
    select case lhs.typ
    case varType._NUMBER_
        if lhs.number <> rhs.number then return 0
    case varType._STRING_
        if lhs.strng <> rhs.strng then return 0
    case varType._BOOL_
        if lhs.bool <> rhs.bool then return 0
    case varType._ARRAY_
        if lhs.array->size <> rhs.array->size then return 0
        for i as integer = 0 to lhs.array->size-1
            if ( *lhs.array->items(i) = *rhs.array->items(i) ) = 0 then return 0
        next i
    case varType._OBJECT_
        if lhs.object->size <> rhs.object->size then return 0
        for i as integer = 0 to lhs.object->size-1
            if ( *lhs.object->fields(i) = *rhs.object->fields(i) ) = 0 then return 0
        next i
    end select
    
    return -1
end Operator

function array_has overload ( byref arr as variable, byref v as variable ) as integer
	dim as integer res = 0
	if arr.array = 0 then return 0
	for i as integer = 0 to arr.array->size - 1
		if *arr.array->items(i) = v then return i+1
		if arr.array->items(i)->typ = _ARRAY_ then
			res = array_has( *arr.array->items(i), v )
			if res then return res
		end if
	next i
	return res
end function

function array_has overload ( byref arr as variable, byval v as string ) as integer
	dim as integer res = 0
	if arr.array = 0 then return 0
	for i as integer = 0 to arr.array->size - 1
		if arr.array->items(i)->strng = v then return i+1
		if arr.array->items(i)->typ = _ARRAY_ then
			res = array_has( *arr.array->items(i), v )
			if res then return res
		end if
	next i
	return res
end function

function array_has_malformed( byref arr as variable ) as integer
    dim as integer res = 0
    if arr.array = 0 then return 0
    for i as integer = 0 to arr.array->size - 1
        if arr.array->items(i)->typ = _MALFORMED_ then return -1
        if arr.array->items(i)->typ = _ARRAY_ then 
            res = array_has_malformed( *arr.array->items(i) )
            if res then return res
        end if
    next i
    return res
end function

Destructor variable()
end Destructor

sub variable.init( byval s as string, byval n as string = "" )
    dim as integer l = len(s)
    dim as integer arrayIsOpen = 0
    dim as integer objectIsOpen = 0
    dim as integer inQuotes = 0
    
    this.lbl = n

    for i as integer = 0 to l-1
        dim as ubyte c = s[i]

        if isWhite( c ) then continue for
        
        if isNumberJson( c ) then
            if arrayIsOpen or objectIsOpen then
                this.typ = _MALFORMED_
                this.strng = s
                exit sub
            endif

            this.typ = _NUMBER_
            dim as string inNum = ""
            
            Do while IsNumberJson( s[i] )
                inNum += ascii( s[i] )
                if i > l then
                    this.typ = _MALFORMED_
                    this.strng = s 
                    ? "Error: i > l"
                    exit sub
                endif
                i+=1
            loop
            
            this.number = val(inNum)
        endif

        if c = 34 then
            if arrayIsOpen or objectIsOpen then
                this.typ = _MALFORMED_
                this.strng = s
                ? "Array / Object is open"
                exit sub
            endif
            
            i+=1
            this.typ = _STRING_
            dim as string inString = ""
            dim as integer done = 0
            Do 
                if s[i-1] <> asc("\") then
                    if s[i] <> 34 then
                        inString += ascii( s[i] )
                        i+=1
                    else
                        done = 1
                    endif
                else
                    inString += ascii( s[i] )
                    i+=1
                endif

                if i >= l then
                    this.typ = _MALFORMED_
                    this.strng = s
                    ? "Error: i > l"
                    done = 1
                endif
            loop until done = 1
            
            if inString <> "" then this.strng = unEscape( inString )            
         
            if i <> l-1 then
                this.typ = _MALFORMED_
                this.strng = s
                ? "Error: i <> l-1", i, l-1 
                ? instring
            endif
        endif
        
        select case c
            case asc("t"),asc("T"),asc("f"),asc("F"),asc("n"), asc("N")
                if mid(s,i+1,4) = "true" then
                    this.typ = _BOOL_
                    this.bool = _TRUE_
                    i += 3
                elseif mid(s,i+1,4) = "null" then
                    this.typ = _NULL_
                    i += 3
                elseif mid(s,i+1,5) = "false" then
                    this.typ = _BOOL_
                    this.bool = _FALSE_
                    i += 4
                endif
        
            case asc("[")
                arrayIsOpen = 1
                this.typ = _ARRAY_
                this.array = new varArray
                dim as integer level = 1
                dim as string instring = ""
                
                i+=1
                Do 
                    dim as ubyte char2 = s[i]
                    dim as variable tmp
                                        
                    select case char2
                        
                        case 34
                            if inQuotes = 0 then inQuotes = 1 else inQuotes = 0
                            instring += ascii( char2 )
                            
                        case asc("[")
                            level += 1 
                            instring += "["
                            Do
                                i+=1
                                if s[i] = asc("[") then level += 1
                                if s[i] = asc("]") then level -= 1
                                instring += ascii( s[i] )
                            loop until level = 1
                            if instring <> "" then
                                tmp.init( instring )
                                array->add( @tmp )
                                instring = ""
                            endif
                        case asc("]") 
                            if instring <> "" then
                                if isWhite( instring[0] ) = 0 then
                                    tmp.init( instring )
                                    array->add( @tmp )
                                endif
                            endif
                            instring = ""
                            level -= 1
                        case asc(",") 
                            if inQuotes = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    array->add( @tmp )
                                    instring = ""
                                endif
                            else
                                instring += ascii( char2 )
                            endif
                        case asc("{")
                            dim as integer olevel = 1
                            instring += "{"
                
                            Do 
                                i+=1
                                if s[i] = asc("{") then olevel += 1
                                if s[i] = asc("}") then olevel -= 1
                                instring += ascii( s[i] )
                            loop until olevel = 0
                            
                            if instring <> "" then
                                tmp.init( instring )
                                array->add( @tmp )
                                instring = ""
                            endif
                        case else
                            instring += ascii( char2 )
                            
                    end select
                    i+=1
                loop until level = 0
                arrayIsOpen = 0
            
            case asc("{")
                objectIsOpen = 1 
                this.typ = _OBJECT_
                this.object = new varObject
                dim as integer olevel = 1, alevel, inQuotes = 0
                dim as string instring = "", key = ""
                dim as variable tmp
                
                Do
                    i+=1
                    dim as ubyte char2 = s[i]                    
                    
                    if isWhite( char2 ) AND inQuotes = 0 then continue do

                    if inQuotes = 1 then
                        if char2 <> 34 then 
                            instring += ascii( char2 )
                            continue do
                        endif
                    endif
                    
                    select case char2                            
                        case asc(":")
                           key = instring
                           instring = ""
                        case asc("[")
                            alevel += 1
                            instring += ascii( char2 )
                        case asc("]")
                            alevel -= 1
                            instring += ascii( char2 )
                        case asc("{")
                            olevel += 1
                            instring += ascii( char2 )
                            
                            Do
                                i+=1
                                char2 = s[i]
                                if char2 = 34 then
                                    if inQuotes = 1 then inQuotes = 0 else inQuotes = 1 
                                endif

                                if isWhite( char2 ) and inQuotes = 0 then Continue do                                
                                if char2 = asc("{") then olevel += 1
                                if char2 = asc("}") then olevel -= 1
                                if char2 = asc("[") then alevel += 1
                                if char2 = asc("]") then alevel -= 1
                                instring += ascii( char2 )
                            loop until olevel = 1 and alevel = 0
                            
                            if instring <> "" then
                                tmp.init( instring )
                                object->add( key, @tmp )
                                instring = ""
                            endif                            
                        case asc("}")
                            olevel -= 1
                            if olevel = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    object->add( key, @tmp )
                                    instring = ""
                                endif
                            endif
                        case asc(",")
                            if alevel = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    object->add( key, @tmp )
                                    instring = ""
                                endif
                            else
                                instring += ascii( char2 )
                            endif
                        case 34
                            instring += ascii( char2 )
                            if inQuotes = 1 then inQuotes = 0 else inQuotes = 1

                        case else                        
                            instring += ascii( char2 )
                    end select
                loop until olevel = 0
                objectIsOpen = 0
                
        end select
    next i
    
end sub

function variable.getType() as string
    select case typ
    case _NUMBER_:
        return "Number"
    case _STRING_:
        return "String"
    case _BOOL_:
        return "Boolean"
    case _ARRAY_:
        return "Array"
    case _OBJECT_:
        return "Object"
    case _NULL_:
        return "null"
    case _MALFORMED_:
        return "[MALFORMED]"
    end select
end function

function variable.getTypeNum() as vartype
    return typ
end function

function variable.toString() as string
    select case typ
    case _NUMBER_:
        return number & ""
    case _STRING_:
        return strng
    case _BOOL_:
        if bool then return "true"
        return "false"
    case _ARRAY_:
        return "ARRAY"
    case _OBJECT_:
        return "OBJECT"
    case _NULL_:
        return "null"
    case _MALFORMED_:
        return "[MALFORMED]"
  end select
end function

function variable.getNumber() as double
    if typ <> _NUMBER_ then return 0
    return number
end function

function variable.getString() as string
    if typ <> _STRING_ then return ""
    return strng
end function

function variable.getBoolean() as integer
    if typ <> _BOOL_ then return _FALSE_
    return bool
end function

function variable.getArray() as vararray ptr
    if typ <> _ARRAY_ then return NULL
    return array
end function

function variable.getObject() as varobject ptr
    if typ <> _OBJECT_ then return NULL
    return object
end function

declare function stringize_object( byref v as variable, byval l as integer = 0 ) as string 
declare function stringize_array( byref v as variable ) as string 

function stringize_array( byref v as variable ) as string 
	if v.typ <> varType._ARRAY_ then return ""
	dim as integer length = v.array->size
	
	if length = 0 then return "[]"
	
	var s = "["	
	
	for i as integer = 0 to length - 1
		var tmp = *v.array->items(i)
		select case tmp.typ
			case _ARRAY_ 	: s += stringize_array( tmp )
			case _STRING_ 	: 
				s += DBLQUOTE
				s += tmp.strng
				s += DBLQUOTE
			case _BOOL_		: s += tmp.toString
			case _NULL_		: s += "NULL"
			case _NUMBER_	: s &= tmp.number
			case _OBJECT_   : s += stringize_object( tmp )
		end select
		if i <> length-1 then s += "," else s += "]"
	next i 
	
	return s	
end function

function stringize_object( byref v as variable, byval l as integer = 0 ) as string 
	if v.typ <> varType._OBJECT_ then return ""
	dim as integer length = v.object->size 
	dim as string s 
    s += !"\n"
    for i2 as integer = 0 to l : s += !"\t" : next i2
    s += "{"
	
	for i as integer = 0 to length - 1
		var tkey = v.object->fields(i)->key
		s += !"\n\t"
        for i2 as integer = 0 to l : s += !"\t" : next i2
		s += tkey
		if len(tkey) > 6 then s += !":\t" else s+= !":\t\t"
		var tmp = *v.object->fields(i)->value
		select case tmp.typ
			case _ARRAY_ 	: s += stringize_array( tmp )
			case _BOOL_  	: s += tmp.toString
			case _NULL_	 	: s += "NULL"
			case _NUMBER_	: s &= tmp.number
			case _OBJECT_	: s += stringize_object( tmp, l+1 )
			case _STRING_	: 
				s += DBLQUOTE
				s += tmp.strng
				s += DBLQUOTE
		end select
		if i <> length-1 then 
            s += "," 
        else 
            s += !"\n"
            for i2 as integer = 0 to l : s += !"\t" : next i2
            s += "}"
        endif
	next i
	
	return s
end function


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

dim shared as string fake_json_word
fake_json_word = "{"
fake_json_word += DBLQUOTE + "txt" + DBLQUOTE + ": " + DBLQUOTE + "word" + DBLQUOTE + ","
fake_json_word += DBLQUOTE + "tag_tkns" + DBLQUOTE + ": [""NN""],"
fake_json_word += DBLQUOTE + "phone_tag" + DBLQUOTE + ": " + DBLQUOTE + "(W ER D)" + DBLQUOTE+ ","
fake_json_word += DBLQUOTE + "nsyls" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "accent" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "tags" + DBLQUOTE + ": [""stuff"",[""nested"",""array""],""more stuff""]"
fake_json_word += "},"

dim as string test_string = "["

? "Building string"

for i as integer = 0 to 400000
    test_string += fake_json_word
next i

test_string += "2, ]" 'Just to close off the array

? "Initializing variable"
dim shared as variable v 
v = test_string

? "Stringizing array"
? stringize_array( v )
sleep

dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Linux threw this error.. Anyone see it before?

Post by dodicat »

Win 10 also pegs out

reason:
...

Building string
Initializing variable


351223 (this was size)

Aborting due to runtime error 4 (out of memory) at line 156 of C:\Users\User\Desktop\FreeBASIC-1.04.0-win32\FBIde0.4.6r4\FBIDETEMP.bas::ADD()

Press any key to continue . . .
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

It's not an out-of-memory error. Try increasing the stack size.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Linux threw this error.. Anyone see it before?

Post by dodicat »

Now I get a seg.
Seems a lot of recursions.

Building string
Initializing variable
Stringizing (98619 recursions in stringsize_array)

Aborting due to runtime error 12 ("segmentation violation" signal) in C:\Users\User\Desktop\FreeBASIC-1.04.0-win32\FBIde0.4.6r4\FBIDETEMP.bas::STRINGIZE_ARRAY()

Press any key to continue . . .
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Linux threw this error.. Anyone see it before?

Post by rolliebollocks »

That is the issue right there. I have no idea why it's segfaulting or why the size of the string should matter if the memory is allocated properly.
Post Reply