Author Topic: [FIXED] Glitch between _LOADFONT and PRINT  (Read 1259 times)

Offline SMcNeill

  • QB64 Developer
[FIXED] Glitch between _LOADFONT and PRINT
« on: July 18, 2017, 07:15:04 AM »
Code: [Select]
SCREEN _NEWIMAGE(640, 120, 32)

FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    PRINT i
    PRINT f(i)
NEXT

A very simple little program to highlight a very odd glitch.  Somewhere between _LOADFONT and PRINT, QB64 basically just falls apart and dies..

The output I'm currently getting is:
Code: [Select]
0
32
1
ows/

After which point, the program then proceeds to simply print blank lines -- even for the line which should relate to PRINT i and increment every pass.

How do I know it's printing blank lines?

Because the screen is scrolling every second as it continues to run, until it finishes working.  (Which is why I chose such a small screen height to highlight the issue.)

Now, how the heck can PRINT f(i) -- which should print a SINGLE value in this case -- end up printing a STRING result of "ows/"???

Something bad is broke in there somewhere, and I'll be danged if I can sort out where or what it is at the moment.

***********************
***********************

NOTE:  I don't guarantee that other users will experience the same results as I do in this example.  It seems as if f(i) is being corrupted and displaying just something random in memory, rather than anything reliable or sensible.  Change those 2 lines into a single line, separated by a comma, like the following --     PRINT i, f(i)   -- and see how the results change...

Code: [Select]
0          32  32
1          -1  -1

For whatever reason, if we use a comma and keep to a single PRINT statement, it prints f(i) TWICE...  And then, once it gets to the -1 value for f(i), it goes back to printing blank lines from that point on.

NOTE 2:  If we substitute _PRINTSTRING into the program, it works just peachy fine.

NOTE 3: And, if we try to mix and match with _PRINTSTRING and PRINT, we get really odd results...

Code: [Select]
FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    PRINT f(i)
    _PRINTSTRING (10, i + 1), STR$(f(i))
NEXT

The above makes it seem as if _LOADFONT is failing, with results being generated with values which print -1 for the _PRINTSTRING results.  (Though the PRINT results are blank.)

And yet, if we try the following, we see that _LOADFONT itself is working just fine with the _PRINTSTRING command, however, it generates completely unpredictable results when PRINT is in use:

Code: [Select]
FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    _PRINTSTRING (1, i + 1), STR$(f(i))
NEXT

FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    LOCATE i + 1, 10: PRINT f(i)
NEXT

In fact, the results are odd enough for the last program, that I'm going to share a screenshot of them for folks to scratch their heads over...

**********************
**********************

Now, here's the $22,000,000 question:  Does anyone have any idea what the heck is going on here??  Something somewhere is broken bad, but I'll be danged if I can sort out exactly what the heck it is, at the moment.
« Last Edit: October 30, 2018, 12:50:12 AM by odin »

Offline SMcNeill

  • QB64 Developer
Re: Glitch between _LOADFONT and PRINT
« Reply #1 on: July 18, 2017, 09:15:42 AM »
After some digging, I think I've found the source of the problem.  Luke suggested it was the autopath routine in _LOADFONT which was acting up, and after some experimenting, it does seem as if it was the source of the problem.  (Though why we'd start printing corrupted results with the PRINT statement is still beyond me.)

Attached is a copy of libqb.cpp which seems to fix the issue, without breaking anything else for me.

[Edit: Unattached as the changes have pushed into the repo and no longer need testers. :P)

What changed??

Now, instead of doing an automatic call to gfs_open with the path automatically appended to it, we instead go back and reprocess func__loadfont itself for a second run with the "C:\Windows\Fonts\" path prepended.  At first, even this process failed to work, but simply removing the STATIC from our variable declarations so that they'd be instanced values and not permanent values, corrected that issue.

As it is, it's working as it should be for me now.  If some other windows users want to plug it into QB64's internal/c folder and then "purge_libqb_only.bat", the samples above should all work as expected, without generating such random crap and  unpredictable results for us.
« Last Edit: July 21, 2017, 12:57:22 PM by SMcNeill »

Offline Cobalt

  • At 60 I become highly radioactive!
Re: Glitch between _LOADFONT and PRINT
« Reply #2 on: July 18, 2017, 06:42:50 PM »
I would have believed it to be inadvisable to have a font load over and over in a loop like that to begin with. Wonder if it would still do that loading 10 different fonts rather than the same one over and over. Not that I see why that would make any difference but just a thought.

P.S. : sure enough on my laptop running QB64 ver 0.98, 1.0, 1.1 it doesn't error out for me.
« Last Edit: July 18, 2017, 06:51:38 PM by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline Petr

  • I am instructed.
Re: Glitch between _LOADFONT and PRINT
« Reply #3 on: July 20, 2017, 11:41:53 AM »
Hi Steve, you're absolutely right! This is an error in the source code for this command, when i on the Long changes the output that shows the part of the write path that the command sets

Code: [Select]
DEFLNG I

SCREEN _NEWIMAGE(640, 120, 32)
FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    PRINT i
    PRINT f(i)
NEXT


Offline SMcNeill

  • QB64 Developer
Re: Glitch between _LOADFONT and PRINT
« Reply #4 on: July 21, 2017, 12:23:39 PM »
Hi Steve, you're absolutely right! This is an error in the source code for this command, when i on the Long changes the output that shows the part of the write path that the command sets

Code: [Select]
DEFLNG I

SCREEN _NEWIMAGE(640, 120, 32)
FOR i = 0 TO 10
    _DELAY 1
    f(i) = _LOADFONT("cour.ttf", 16)
    PRINT i
    PRINT f(i)
NEXT


Pushed a fix to this issue into the Repo.  Things should work now, as advertised, without this glitch popping up on us any longer.  (Assuming folks get a copy of the latest version generated from today onwards.)

Re: Glitch between _LOADFONT and PRINT
« Reply #5 on: July 22, 2017, 05:11:47 AM »
Any thread that begins like "WTH" and ends like "pushed to the repo" belong in a category of its own.

I'm going to petition to Odin that we have a new section for bug reports, and to move this thread under it as the first entry.

Also, anyone opposed to renaming the thread to something more descriptive, state your mind sooner rather than later.
"An eye for an eye like a fish needs a bicycle" - Adolf Lincoln

Efforts:
http://www.barnesreport.net/scripturam/

Offline Calloway

  • I still have Laser Disc...
    • Calloway Sutton
Re: Glitch between _LOADFONT and PRINT
« Reply #6 on: July 22, 2017, 05:13:40 AM »
Any thread that begins like "WTH" and ends like "pushed to the repo" belong in a category of its own.

I'm going to petition to Odin that we have a new section for bug reports, and to move this thread under it as the first entry.

Also, anyone opposed to renaming the thread to something more descriptive, state your mind sooner rather than later.
Can we rename it WTF?

Offline SMcNeill

  • QB64 Developer
Re: Glitch between _LOADFONT and PRINT
« Reply #7 on: July 22, 2017, 05:07:34 PM »
Any thread that begins like "WTH" and ends like "pushed to the repo" belong in a category of its own.

I'm going to petition to Odin that we have a new section for bug reports, and to move this thread under it as the first entry.

Also, anyone opposed to renaming the thread to something more descriptive, state your mind sooner rather than later.

WTH seemed like a more than suitable title for the thread when I created it.  We use a command once, it works fine.  We use it twice, it works fine.  We call it in a loop and on try number 3 it fails, that's a case of WTH??  Add in the fact that it's not the command itself which is seeming to fail (_LOADFONT in this case), but an unrelated separate command (PRINT), and it's definitely a case of WTH??!!

Why the autopath routine failed,is still to me at least, a complete and utter mystery.  LOADFONT has a section which basically says, "Try and load the font the user specified.  If we can't get a valid file handle, return an error code."

Code: [Select]
    fh=gfs_open(f,1,0,0);
    if (fh<0) return -1;

All we were doing is a basic retry of the command with the default windows path added to the user's input.

Code: [Select]
            if (fh<0) {fh=gfs_open(qbs_add(qbs_new_txt("C:/Windows/Fonts/"),f),1,0,0);}
Now, how this manages to break PRINT -- of all things -- is completely beyond me.  Why it works twice, but then fails on the third call in a loop, is completely beyond me.  You would think that if it was something wrong, it'd be wrong all the time -- not only after the third and subsequent time! 

The patch I pushed fixed the immediate issue (we simply don't append the default windows path and try to open the file handle -- instead, we call the whole magical routine over again with the windows path appended to the name.), but I still think there's something weirder than heck going on behind the scenes somewhere.  WTH corrupted the PRINT output string?  Why was we getting garbage? 

The patch fixes the problem and _LOADFONT now works as it should, but I still find myself scratching my head and saying, "WTH", over the whole situation.

Even after all this time of working with the internals of QB64 and playing around with it, I find myself wondering from time to time just how the heck it works at all sometimes.

re:Glitch between _LOADFONT and PRINT
« Reply #8 on: July 23, 2017, 10:56:34 AM »
https://www.qb64.org/forum/index.php?topic=10.0
Code: [Select]
            if (fh<0) {fh=gfs_open(qbs_add(qbs_new_txt("C:/Windows/Fonts/"),f),1,0,0);}try splitting this code into a few lines. it should
A. make it easier to find where the error starts.
B. sometimes it's not an 'error' in the code, but how the nesting is handled (I've seen some cases where a nested function's result 'expired' before the initial function had any change to use it)

and another thing, is it followed by if (fh<0) return -1;?

P.S. As I have stated in the off-topic section, I would prefer it if the bugs-section allows direct replying as it would be much easier to keep track of things.
« Last Edit: July 23, 2017, 11:00:35 AM by SkyCharger001 »

Offline SMcNeill

  • QB64 Developer
Re: re:Glitch between _LOADFONT and PRINT
« Reply #9 on: July 23, 2017, 12:00:39 PM »
Problem is, that IS one line of code.

if (fh<0) {
     fh=gfs_open(qbs_add(qbs_new_txt("C:/Windows/Fonts/"),f),1,0,0);
}

In BASIC, what this would be is more or less:

IF filehandle < 0 THEN
    filehandle = GlobalFileSystem_Open("C:/Windows/Fonts/" + f$) FOR BINARY No_Lock No_Length
END IF

qbs_new_text ("C:/Windows/Fonts/")   would translate to basic as more or less, TEMP$ = "C:/Windows/Fonts"

qbs_add is the command to add QB64 Strings.  qbs_add("C:/...",f) is basically "C:/..." + f$

gfs_open(file$, method, lock, length) is basically how we open a file and get an internal handle for it..

*************

I don't see where breaking that line apart would change anything, or make it easier to correct.   What has me really confused is how PRINT is involved with the thing at all.

OPEN "C:/Windows/Fonts/" + f$ FOR BINARY doesn't have a dang thing to do with PRINT, so WTH would it break the output for us??  And WTH always on the third pass inside a loop, but never if called individually outside the loop??

This is, to me at least, just one of those magical, mysterious things that can occur when working inside the QB64 source.  Is it something in the file open routine?  The new text command?  The add string together command?  Is it from some shared internal sub command they share with something else?  Or is it just a QB64 Bigfoot sighting, with no reasonable explaination?

I have no idea WTH actually broke.  I'm just glad that it appears to be working now -- at least, until someone can provide code which shows where it doesn't in some odd circumstance once again...

Re: re:Glitch between _LOADFONT and PRINT
« Reply #10 on: July 23, 2017, 12:31:02 PM »
you misunderstand, that one line of code is a line of nested functions
While you seem to understand the intent of the nested functions, you don't seem to have tested them separately

Code: [Select]
if (fh<0)
{
tmpA = qbs_new_txt("C:\windows\fonts\");
tmpB = qbs_add(tmpA,f);
fh = gfs_open(tmpB,1,0,0);
}

and, while not that likely in this specific case, it's possible that we are dealing with a silent stack-overflow. (this is why you shouldn't nest functions too deep.)

Offline SMcNeill

  • QB64 Developer
Re: re:Glitch between _LOADFONT and PRINT
« Reply #11 on: July 23, 2017, 01:32:54 PM »
Tested.

Can confirm, alteration changes nothing.

PRINT still breaks just like before, with zero change to results.

Stacking overflow from nested functions can be marked off the list of possible problems. 

Re: re:Glitch between _LOADFONT and PRINT
« Reply #12 on: July 23, 2017, 01:50:07 PM »
So everyone is telling me that you can't reply to posts over in the Bugs section? If I go over there and posting a reply fails, then I'll say SkyCharger was right for once and tell Odin to fix it. Otherwise, don't follow Sky like the pied piper.
"An eye for an eye like a fish needs a bicycle" - Adolf Lincoln

Efforts:
http://www.barnesreport.net/scripturam/

Re: Glitch between _LOADFONT and PRINT
« Reply #13 on: July 23, 2017, 01:51:26 PM »
(test)

If you can read this, then posting replies to Bugs topics DOES in fact work.

When in doubt, actually try it next time.

(text)
"An eye for an eye like a fish needs a bicycle" - Adolf Lincoln

Efforts:
http://www.barnesreport.net/scripturam/

Offline SMcNeill

  • QB64 Developer
Re: Glitch between _LOADFONT and PRINT
« Reply #14 on: July 23, 2017, 02:04:45 PM »
It does now, but it didn't last night.  ;)

PRAISE ODIN!!