Stream weirdness (linux -2 windows 1)

Miscellaneous Forums/Linux Discussion/Stream weirdness (linux -2 windows 1)

Consider the following code (the THttp type is taken and modified from the code archives):
Framework brl.basic
Import brl.blitz
Import brl.retro
Import brl.system

Import BaH.Libxml

Type rssChannel
  Global _list:TList = New TList
	
	'channel information
	Field Title:String			'title of channel
	Field Description:String	'description of channel
	Field Pubdate:String		'date channel was created?/updated?
	'channel links
	Field lk_Feed:String		'link to the channel's rss feed
	Field lk_Link:String		'link to main feed site
	
	Field chnItems:TList
		
		Method New() 
			chnItems = New TList
		   _list.AddLast(Self) 
			
		End Method
		
		Method SetTitle(_Title:String) 
			Title = _Title
			
		End Method
		
		Method SetDescription(_Desc:String) 
			Description = _Desc
		
		End Method
		
		'fix incoming date for appended timezone data (ex. Thu, 13 Mar 2008 19:26:44 >-0000<)
		Method SetPubdate(pubdateraw:String) 
			Pubdate = pubdateraw
			
		End Method
		
		Method SetLink(Link:String, which:Int) 
		 
			Select which
				Case 0
					lk_Feed = Link
					
				Case 1
					lk_Link = Link
					
			End Select
			
		End Method
		
		Method ReadChannel(root:TxmlNode) 
		  Local channel:TxmlNode = TxmlNode(root.GetFirstChild()) 
		
		   If chnItems.Count() > 0 Then Clear() 
		  
			For Local part:TxmlNode = EachIn channel.getChildren()
			
				Select Lower(part.GetName()) 
				
					Case "title"
						SetTitle(part.getContent()) 
						
					Case "description"
						SetDescription(part.getContent()) 
						
					Case "pubdate"
						SetPubdate(part.getContent()) 
						
					Case "link"
						SetLink(part.getContent(), 1) 
						
					Case "item"
						ReadItem(part) 
						
					Default
						DebugLog("rchn noparse: ~q" + part.getName() + "~q") 
						DebugLog("~t" + part.getName() + " :: " + part.getContent()) 
						
				End Select
			
			Next
		
		End Method
		
		Method ReadItem(parent:TxmlNode) 
		  Local ritem:rssItem = New rssItem
			
			For Local part:TxmlNode = EachIn parent.getChildren() 
			
				Select Lower(part.GetName()) 
				
					Case "title"
						ritem.SetTitle(part.getContent()) 
						
					Case "description"
						ritem.SetDescription(part.getContent()) 
						
					Case "pubdate"
						ritem.SetPubdate(part.getContent()) 
						
					Case "link"
						ritem.SetLink(part.getContent()) 
						
				End Select
			
			Next
			
		   chnItems.AddLast(ritem) 
		   
		End Method
		
		Method Clear() 
		  Local ritem:rssItem
		  
			For ritem = EachIn chnItems
				
				ritem.Clear(Self) 
				
			Next
			
			Title = Null ; Pubdate = Null
			Description = Null
			lk_Feed = Null ; lk_Link = Null
			
		End Method
		
End Type

Type rssItem
	'item information
	Field Title:String			'title of item
	Field Description:String	'description of item
	Field Pubdate:String		'date event occured
	'item links
	Field lk_Link:String		'referring link to event
	
		Method SetTitle(_Title:String) 
			Title = _Title
			
		End Method
		
		Method SetDescription(_Desc:String) 
			Description = _Desc
		
		End Method
		
		'fix incoming date for appended timezone data (Thu, 13 Mar 2008 19:26:44 >-0000<)
		Method SetPubdate(pubdateraw:String) 
			Pubdate = pubdateraw
			
		End Method
		
		Method SetLink(Link:String) 
			lk_Link = Link
			
		End Method
		
		Method Clear(channel:rssChannel) 
			Title = Null
			Description = Null
			Pubdate = Null
			lk_link = Null
			
		  channel.chnItems.Remove(Self) 
		End Method
		
		
		Function Create:rssItem(Title:String, Desc:String, Pubdate:String, lk_Link:String) 
		  Local ritem:rssItem = New rssItem
			
			ritem.Title = Title
			ritem.Description = Desc
			ritem.SetPubdate(Pubdate) 
			ritem.lk_Link = lk_Link
			
		   Return ritem
		   
		End Function
		
End Type

Type Thttp
	Field sock:TSocket
	Field stream:TStream
	Field host:String
	Field agent:String = "BlitzHTTP/1.0"
	Field autoClose:Int
	
		Method Open:Int(host:String, autoClose:Int = False) 
		  Self.sock = CreateTCPSocket()
			 
			If ConnectSocket(Self.sock, HostIp(host), 80) 
				Self.host = host
				Self.stream = CreateSocketStream(Self.sock) 
				Self.autoClose = autoClose
			   Return True
				
			Else
			   Return False
				
			End If
			
		End Method
		
		Method Get:HTTPReturnData(get:String = "") 'def get = ""
		  Local HTRD:HTTPReturnData = New HTTPReturnData, buffer:String, rlnewline:String
			
		   'WriteLine(stream, "GET /" + get + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~n~n") 
		   WriteLine stream, "GET /" + get + " HTTP/1.0" ' GET / gets Default page
		   WriteLine stream, "Host: " + Self.host
		   WriteLine stream, "User-Agent: " + Self.agent
		   WriteLine stream, "Accept: */*"
		   WriteLine stream, ""
		
		  Local cExtType:String, cExt:String, cLength:Int
		   ReadLine(stream)
			While Not Eof(stream)
			  rlnewline = ReadLine(stream)
			  Local spos:Int = Instr(rlnewline, ":")
			Print "rln" + Lower(Left(rlnewline, spos - 1)) + "rln"
				Select Lower(Left(rlnewline, spos - 1))
					Case "content-type"
					  Local prtmp:String = Mid(rlnewline, spos + 2, Instr(rlnewline, ";") - spos - 2), slpos:Int = Instr(prtmp, "/")
					  cExtType = Left(prtmp, slpos - 1) cExt = Right(prtmp, prtmp.Length - slpos)
						
					Case "content-length"
						cLength = Int(Right(rlnewline, rlnewline.Length - spos - 1))
						
					Case ""
					   Exit
						
				End Select
				
			Wend
			
			While Not Eof(stream) 
			  rlnewline = ReadLine(stream)
				
				buffer:+ rlnewline + "~n"
				
			Wend
			
		  HTRD.Set(Left(buffer, buffer.Length - 1), cExtType, cExt, cLength)
			
		   If autoClose Close() 
		   
		   Return HTRD
		 
			
		End Method
		
		Method Post:String(page:String = "", keys:String[] , values:String[] ) 
		  Local buffer:String
		  Local data:String
		  Local i:Int
			
			For i = 0 To keys.Length - 1
				data:+ UrlEncode(keys[i] ) + "=" + UrlEncode(values[i] ) + "&"
				
			Next
			
		  data = Left(data, data.Length - 1) 
			WriteLine(stream, "POST /" + page + " HTTP/1.0~nHost: " + Self.host + "~nUser-Agent: " + Self.agent + "~nContent-Length: " + data.Length + "~nContent-Type: application/x-www-form-urlencoded~n~n" + data) 
			
			While Not Eof(stream) 
				buffer:+ReadLine(stream) + "~n"
				
			Wend
			
		 If autoClose Close() 
		
		   Return Left(buffer, buffer.Length - 1) 
			
		End Method
		
		Method Close() 
			If Self.stream CloseStream(Self.stream) 
			If Self.sock CloseSocket(Self.sock) 
			
		End Method
	
		Function UrlEncode:String(url:String) 
		  Local buffer:String
		  Local Char:Int
		  Local i:Int
			
			For i = 1 To url.Length
			  Char = Asc(Mid(url, i, 1)) 
				
				If(Char >= 48 And Char <= 57) Or (Char >= 65 And Char <= 90) Or (Char >= 97 And Char <= 122) Or Char = 43 Or Char = 45 Or Char = 46 Or Char = 95
					buffer = buffer + Chr(Char) 
					
				Else
					buffer = buffer + "%" + Right(Hex(Char), 2) 
					
				End If
				
			Next
			
		   Return buffer
		
		End Function
		
		Function UrlDecode:String(url:String) 
		  Local sHex:String = "0123456789ABCDEF"
		  Local buffer:String
		  Local i:Int
			
			For i = 1 To url.Length
				If Mid(url, i, 1) = "%"
					buffer = buffer + Chr(Instr(sHex, Mid(url, i + 1, 1)) Shl 4 + Instr(sHex, Mid(url, i + 2, 1)) - 17) 
				   i:+ 2
					
				Else
					buffer = buffer + Mid(url, i, 1)
					 
				End If
				
			Next
			
		   Return buffer
		
		End Function
	
End Type

Type HTTPReturnData
	Field Content:String
	Field ContLength:Int
	
	Field ExtensionType:String
	Field Extension:String		
		
		Method Set(Cont:String, ExtType:String, Ext:String, CLen:Int)
			Content = Cont
			ContLength = CLen
			Extension = Ext
			ExtensionType = ExtType
			
		End Method
		
		Method SaveContent(File:String, useExt:Int = False)
		 
		 If useExt File:+ "." + Extension
			
			SaveText(Content, File)
			
		End Method
		
		Method ToString:String()
			Return "Content-Type: " + ExtensionType + "/" + Extension + "~nContent-Length: " + ContLength
			
		End Method
		
End Type

'Print "start"
  Local feedurl:String = "www.hulu.com/feed/show/60/episodes" 
  Local httpg:Thttp = New Thttp, htrd:HTTPReturnData
  
Local tmstart:Int = MilliSecs()
	If httpg.Open("www.hulu.com", True) 
	  Local doc:TxmlDoc, root:TxmlNode, rchan:rssChannel = New rssChannel
		'Print "get"
		htrd = httpg.Get("feed/show/60/episodes") 
		htrd.SaveContent("rss2", True)
		Print "cont " + htrd.ToString()
		'Print "parse"
		doc = TxmlDoc.parseDoc(htrd.Content) 
		root = doc.GetRootElement() 
		
		rchan.ReadChannel(root) 
			rchan.lk_Feed = feedurl
		'Print "showdata"	
	  Local ritem:rssItem, pageCont:String = "<html><body>~r~n"
		For ritem = EachIn rchan.chnItems
			
			'Print ritem.Title + " date: " + ritem.PubDate
			'Print "~t" + ritem.lk_link
			'Print ritem.Description
			
			pageCont = pageCont + "<a href=~q" + ritem.lk_Link + "~q>" + ritem.Title + "</a>~r~n" + ..
			ritem.Description + "~r~n"
			
			
		Next
	   pageCont = pageCont + "~r~n</body></html>"
	 SaveText(pageCont, "op2.html")
	
	End If
Print "time! " + (MilliSecs() - tmstart)
Input()

It runs perfect in win32, however in Ubuntu (Gutsy Gibbons, 7.10), it crashes on line 242 "rlnewline = ReadLine(stream)" with this "Unhandled Exception:appstub.linux signal handler 11" (debug mode is on) - which makes no sense at all.

Compiling the program without debug and running outside of maxide does nothing either - no errors pop up (if run from inside maxide, I get the signal handler error again).

The signal handler hides the actual error the program is throwing. It is possible to change appstub.linux.c *not* to handle the error, and allow the app to nuke itself, which you can then run through gdb (for example) and see exactly where the app is breaking.
... if you know what you are doing ;-)

eg. try commenting out
signal( SIGSEGV,sighandler );


Just be careful.


Actually, it would be nice if BlitzMax didn't catch this at all for debug builds - would make life easier in certain cases...

Be careful eh!?

it would be nice if BlitzMax didn't catch this at all for debug builds
I don't know why you say "Just be careful" (inform me), but wouldn't this just be fine?
?NotDebug 'I know NotDebug is not valid - I can't remember any of them EDIT: oh wait, you can do this "?Not Debug"
	signal( SIGSEGV,sighandler );
?


Anyways, now all I'm getting is "Segmentation fault (core dumped)". :(

EDIT: Using debugstop just before the loop that contains the line its crashing on does a "Segmentation fault (core dumped)" error again..

well, no.. ?NoDebug is a BlitzMax thing.. that code is C.

Now you have a segmentation fault... you can run your app with gdb, for example :
gdb ./myappname

in gdb, type the letter "r", followed by return. (no quotes!).
Then, when it crashes, type "bt", followed by return (no quotes!).

That should qive you a "back trace" showing where it was when it crashed.

to quit gdb, type quit :-)

I suppose I have no idea what I'm doing.

Here is the output on gdb:
(gdb) r
Starting program: /home/timhow/Desktop/dev/max/bvm/rss/rsstestbmx.debug 
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1212705088 (LWP 6166)]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
rlnserverrln
rlncontent-typerln
rlnstatusrln
rlncontent-lengthrln
rlnx-varnishrln
rlncache-controlrln
rlnexpiresrln
rlndaterln
rlnconnectionrln
rlnrln

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1212705088 (LWP 6166)]
0x080ea3ca in ?? ()
(gdb) bt
#0  0x080ea3ca in ?? ()
#1  0x00000418 in ?? ()
#2  0xbf99dae8 in ?? ()
#3  0x00000000 in ?? ()
(gdb) 

I have no idea what any of that means.

well, that was less than useful, hey?

That generally means (given the lack of labels) that it's specifically a line of BlitzMax's generated assembler that's broken - otherwise you tend to get a C function name if something went wrong elsewhere.

Your next task, should you choose to accept it, is to debug your code. Hope you've nothing else to do today ;-)

Perhaps the stream handle is null or something.

Stick a debugstop in there and examine the variables.

Hope you've nothing else to do today ;-)
That would be a tonight for me sir.

I am not liking max on Linux right now :/, ironically the graphics issue, and this, are both required to work for my current project.

Thanks for the help, I'll post my findings tomorrow - unless I manage to find the problem before I hit the sack.

EDIT:
well, no.. ?NoDebug is a BlitzMax thing.. that code is C.
After many late nights, I would say it is fair to say I am less attentive to details at night :)

It seems to me Signal handler 11 is similar to b3Ds MAV.

What line in the debugger is it terminating on?
If its terminating deeper then try adding lines like:

debuglog 342349872(a random number)

in progressive locations in your code and you will see in the terminal which was the last number before the crash to progressively narrow it down.

Code works ok in Ubuntu 8.04.
Just on the off chance make sure that your compiling against gcc-3.3 and not system linking to gcc-4.2/4.1 and the libxml2 libs are installed.

Here's a list of the sig codes http://www.comptechdoc.org/os/linux/programming/linux_pgsignals.html

I just got libxml2 (note that I'm on 8.04 now) and removed all symlinks of gcc, still getting 'Segmentation fault'.


EDIT:
If I change the read loop to this
Local ln:Int = 0
			DebugLog "getcontent"
			While Not Eof(stream) 
					rlnewline = ReadLine(stream)
				ln:+1
				DebugLog ln
				buffer:+ rlnewline + "~n"
				
			Wend

The last DebugLog message is ALWAYS 41.. (there are currently 141 lines in the xml file)

P.S. Does anyone have a gtk compiled version of maxide working? my ldconfig has
/usr/lib/firefox/libgtkembedmoz.so
/usr/lib/firefox/

in it, but I get this from terminal
./maxide: error while loading shared libraries: libgtkembedmoz.so: cannot open shared object file: No such file or directory

Have things changed in firefox 3.0? (it worked fine on 7.10)

After removing all symlink files that had gcc-x.x in them, and reinstalling gcc-3.3 I tried to rebuild all modules and got this:
Compiling:freeaudio.cpp
ar: creating /home/timhow/BlitzMax/mod/pub.mod/zlib.mod/zlib.debug.linux.x86.a
gcc-3.3: installation problem, cannot exec `cc1plus': No such file or directory
Build Error: failed to compile /home/timhow/BlitzMax/mod/pub.mod/freeaudio.mod/freeaudio.cpp
Process complete

I looked for cc1plus and anything similar in synaptics but found nothing.

After removing all symlink files that had gcc-x.x in them.


I think this is where you went wrong here.
Re-install gcc-4.2 and then reinstall gcc-3.3

Some people make a system link named g++-3.3 that links to g++-4.2 ( or g++ which is a system link in it's self to the current compiler suit ) to force BlitzMax to use gcc-4.x/g++-4.x

BlitzMax for some reason looks to be hard-coded to use the gcc-3.3 suit of tools.

Check to see if you have these packages installed after re-installing gcc-4.2

cpp
cpp-4.2
cpp-3.3
gcc
gcc-3.3-base
gcc-4.2-base
libgcc1
g++
g++-3.3
g++-4.2
libstdc++6 ( or/and ) libstdc++5

All versions of gcc/g++ will live quite happily side by side. The only problems that you may have is if you are using the 64bit edition of ubuntu. The problem there is that there is only a 64bit version of the gcc-3.3 libs where as gcc-4.1/gcc-4.2 has both the 64bit and 32bit libs.

cc1plus

Is part of the gcc suit and can be found in...
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6 (if gcc-3.3 is installed)
or in a sub-directory of
/usr/lib/gcc/i486-linux-gnu/

Is Ubuntu 8.04 an upgrade or a clean install ?

Nope, another upgrade. It's a pain in the arse to install linux on a computer with no cd drive.

EDIT: I did not remove any g++ symlinks, but I am trying what you suggested.

EDIT2: Compiling modules! w00t.

!!! That worked, thanks. It seems like I was compiling everything before in gcc-4.2, going to try graphics stuff again.

It's a pain in the arse to install linux on a computer with no cd drive.

I wonder if there is a way to install off a USB pen drive ?

I do know that you can install ubuntu into a USB pen drive.

Edit: There is as long as your machine can boot off of a usb drive. https://help.ubuntu.com/community/Installation/FromUSBStick

I tried to get usb stick to work. Can't remember what put me off, but if I need to reinstall linux I'll take a look at that first.

BTW, graphics work now! :)