1. kevin kevin rowe
  2. PowerBuilder
  3. Friday, 24 February 2023 16:53 PM UTC

i have a code module that was working fine,

I have had to add a section of code to it to place a database field of (up to) 1000 characters in 4 dot matrix report fields of flat 70 characters.

To do this I created a subroutine that would read the field in from the database, chunk it into words, then pack the words into the available space in the print fields and exit if it ran out of fields, or text to pack in.

This turned into a nightmare of random IDE crashes and random .exe crashes when the code is executed. 

IDE is PB 2017 R3 Build 1915.

I have looked into debug logs and the fault is always c0000005 in PBSH170.DLL offset 000C34C0 in the IDE and if the compiled .exe is run, then it is offset 00060E95.

Nothing I have tried has resolved this issue, as it is random if it fails in the IDE, and when it does, it takes the IDE down. It always fails in the .exe in some way, but usually an immediate app crash.

Can anyone see an obvious cause for this in the code? 

 

If I debug step this code in the IDE it works fine. If I run it, it randomly crashes.  Compiled exes invariably crash.

 

// pack words from memo into each item of printfields up to ailength until no room left or out of words

string lsPrintFields[4]
int liMaxRows = 4
string lsWords[500]
int liMaxword = 500
string ls_parm = "", c
int liPrintLineLen = 0
int liLineCount = 1 
int i = 0, li_idx = 0
int liPrintLength = 70
string ls_memo
int limemolen

//ids_1 is a object level datastore the is packed in the calling routine from the data for the report.

ls_memo = ids_1.getitemstring(1, "fdcompinvmemo")
limemolen = Len (ls_memo)

for i = 1 to limemolen
	c = Mid (ls_memo, i, 1)
	// match whitespace chars

	choose case c
		case "~t", "~r", "~n", " "
			if (li_idx >= liMaxword) then
				exit
			else
				if ls_parm <> "" then
					li_idx ++
					lsWords[li_idx] = ls_parm
					ls_parm = ""
				end if
			end if
		case "&" 
			ls_parm += '&'
			ls_parm += c
		case "'", "~""
			ls_parm += '~~'
			ls_parm += c
		case else
			ls_parm += c
end choose
	
next

if (li_idx < liMaxword) then
	if ls_parm <> "" then
		li_idx ++
		lsWords[li_idx] = ls_parm
	end if
end if

lsprintfields[liLineCount] = ""

for i = 1 to limaxword
	
	if lswords[i] = "" or isnull(lswords[i]) then
		exit
	end if
	
	// if there is enough room left add word/block
	
	if (liPrintLineLen +  len(lsWords[i])  + 1) < liPrintLength then
	
		if len(lsprintfields[liLineCount]) > 0 then
		  lsprintfields[liLineCount] = lsprintfields[liLineCount] + " "
		end if
		
		lsprintfields[liLineCount] = lsprintfields[liLineCount] + lsWords[i]
		
		liPrintLineLen = len(lsprintfields[liLineCount])  
	else
		//go to next line unless we're out of space 

		if (liLineCount >= liMaxRows) then
			exit
		else
			liLineCount++
		
             lsprintfields[liLineCount] = lsWords[i] + " "

			liPrintLineLen = len(lsprintfields[liLineCount])
		end if
	end if
next 

//copy lines into memo fields if not blank
// report datawindow contains text fields t_memo1, ... t_memo4

limaxrows = 0
for i = 1 to 4
	if lsprintfields[i] <> "" then
		limaxrows++
		ids_1.Modify ("t_memo" + string(i)+ ".Text='"+ lsprintfields[i] + "'")
	end if
next

return limaxrows

 

Accepted Answer
mike S Accepted Answer Pending Moderation
  1. Sunday, 26 February 2023 14:27 PM UTC
  2. PowerBuilder
  3. # Permalink

is it running out of memory or anything like that?

 

 

string processing in PB is not great, especially in that version (PB22 is better).  Maybe try using blobs instead, at the very least it should run (and crash) faster.  

 

I would use long instead of int as datatype, although you should not be going over 32768 so i really doubt that is any problem.

 

 

Comment
There are no comments made yet.
Kevin Ridley Accepted Answer Pending Moderation
  1. Sunday, 26 February 2023 17:49 PM UTC
  2. PowerBuilder
  3. # 1

Have you tried wrapping the code in a try/catch?  Sometimes you can get a more helpful error.

try

   <your code>
catch(runtimeerror re)

   //display the error

   MessageBox("Runtimeerror", re.getmessage())

end try

Comment
There are no comments made yet.
kevin kevin rowe Accepted Answer Pending Moderation
  1. Tuesday, 28 February 2023 08:47 AM UTC
  2. PowerBuilder
  3. # 2

Thanks for all the suggestions people.

 

I started by adding a try catch around the code, and also added a check on the return of the modify. (if modify <> "" then messagebox it)

Unfortunately, the code is not crashing anymore, even after I commented out the try / catch. inside and outside the IDE. I even tried to use the data that was causing the crash from last week. Still no crash. Go figure.

 

In the end as I was running out of time I opted to chunk the incoming string strictly on the character length of the output string.

It's not ideal but it works.

 

Regards,

 

Kevin.

Comment
  1. Miguel Leeuwe
  2. Tuesday, 28 February 2023 11:03 AM UTC
sometimes you'll have a constant crash, until you close pb and open it up again. I think those cases have something to do with 'caching' code.

Anyway, great to hear the problem seems to be solved.

regards.
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 24 February 2023 17:01 PM UTC
  2. PowerBuilder
  3. # 3

Hi Kevin;

  FYI: The abort in the PBSHRnnn.dlll just tells me that the problem is most likely in your PowerScript code. The "PBSHR" module is basically a "broker" that takes your PowerScript command (in most cases) and just calls its equivalent MS-Windows APIs to implement the feature being used. For example, the ProfileString () command in PowerScript just calls the MS-Windows GetProfileString API.

Regards ... Chris

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Sunday, 26 February 2023 15:21 PM UTC
  2. PowerBuilder
  3. # 4

Hi,

Just another idea: I'm not too sure of how well text objects on a datawindow would accept large strings of text in a Modify() statement.

1. Comment out the last for loop and see if the code still crashes.

2. If that works, then temporarily put in a messagebox "before modify" and another messagebox "after modify" (there's only 4 loops so that shouldn't be too difficult to debug)

3. check the return value of your Modify() statement.

4. The fact that it seems to work in "Debug" mode (which is something I have seen too many times), might mean you have to do some GarbageCollect() / Yield() or Sleep() ?? Just guessing on this one.

regards.

Comment
  1. Olan Knight
  2. Sunday, 26 February 2023 16:49 PM UTC
To add to what Miguels said, create the string first, in its entirety, THEN use the Modify command to updated the field. That's a faster and cleaner approach, and allows you to view the string you are going to use with the Modify code; there may be invalid/NULL charachters in that string!
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.