Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stb_truetype.h crash on android #40

Closed
Discordia opened this issue Sep 8, 2014 · 10 comments
Closed

stb_truetype.h crash on android #40

Discordia opened this issue Sep 8, 2014 · 10 comments

Comments

@Discordia
Copy link

I'm experiencing a crash in stb-truetype.h when running it on android. I have a opengl based codebase and I'm using fontstash to draw text. fontstash uses stb-truetype.h to read and draw truetype fonts. My fork of fontstash is here: https://github.com/Discordia/fontstash. I have updated to the latest version of stb_truetype that I found here: 0.9 (same problem with 0.6 and 0.7). Everything works well on desktop (Linux Mint 17). Text is drawn and no crash, but on android I get a signal 7.

The crash is on row 1633 in the function stbtt__rasterize, the row is "if (p[j].y == p[k].y)".

Here is the stacktrace that I got from using ndk-dump (it starts in my cpp code and goes down through fontstash to stb_truetype.h):
********** Crash dump: **********
Build fingerprint: 'lge/geehrc_open_eu/geehrc:4.1.2/JZO54K/E97510h.1378050911:user/release-keys'
pid: 14257, tid: 14278, name: app.alienattack >>> org.discordia.game.app.alienattack <<<
signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 5a98e34e
Stack frame #00 pc 000ea8d0 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (stbtt__rasterize+376): Routine stbtt__rasterize at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/stb_truetype.h:1633
Stack frame #1 pc 000eb428 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (stbtt_Rasterize+224): Routine stbtt_Rasterize at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/stb_truetype.h:1762
Stack frame #2 pc 000eb824 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (stbtt_MakeGlyphBitmapSubpixel+268): Routine stbtt_MakeGlyphBitmapSubpixel at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/stb_truetype.h:1829
Stack frame #3 pc 000eb8a8 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (stbtt_MakeGlyphBitmap+92): Routine stbtt_MakeGlyphBitmap at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/stb_truetype.h:1836
Stack frame #4 pc 000ef238 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (fons__getGlyph+1180): Routine fons__getGlyph at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/fontstash.c:724
Stack frame #5 pc 000efebc /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (fonsDrawText+580): Routine fonsDrawText at /home/robban/dev/bitbucket/alienattack/deps/audrey/deps/fontstash/src/fontstash/fontstash.c:913
Stack frame #6 pc 000ba0c4 /data/data/org.discordia.game.app.alienattack/lib/libalienattack.so (audrey::Font::drawText(std::string const&, float, unsigned int)+248): Routine audrey::Font::drawText(std::string const&, float, unsigned int) at /home/robban/dev/bitbucket/alienattack/deps/audrey/src/audrey/font/Font.cpp:32

Info about the setup:
I'm using android ndk-r9d.
gcc/g++ version 4.8.2.
Building on Linux Mint 17.
Running on LG Optimus G with android 4.1.2.
The font I'm using is LinerationMono-Regular.ttf.

@nothings
Copy link
Owner

nothings commented Sep 9, 2014

First lets see if I can reproduce the crash on another OS so I can debug it.

Can you check what the parameters to stbtt_MakeGlyphBitmap (stack frame #3) are in the call that crashes? This is the function at the boundary between fontstash and stb_truetype,

Also, I guess you meant Li_b_erationMono.ttf?

@Discordia
Copy link
Author

Yes you are correct on the font, there is a typo in there, it should be LiberationMono-Regular.ttf.

I will debug and check the parameter to stbtt_MakeGlyphBitmap when I get home from work tonight.

@Discordia
Copy link
Author

This is what I got:

I/stbtt_MakeGlyphBitmap( 3027): info->data:
I/stbtt_MakeGlyphBitmap( 3027): info->fontstart: 0
I/stbtt_MakeGlyphBitmap( 3027): info->numGlyphs: 2392
I/stbtt_MakeGlyphBitmap( 3027): info->loca: 15736
I/stbtt_MakeGlyphBitmap( 3027): info->head: 300
I/stbtt_MakeGlyphBitmap( 3027): info->glyf: 25308
I/stbtt_MakeGlyphBitmap( 3027): info->hhea: 356
I/stbtt_MakeGlyphBitmap( 3027): info->hmtx: 520
I/stbtt_MakeGlyphBitmap( 3027): info->kern: 0
I/stbtt_MakeGlyphBitmap( 3027): info->index_map: 10116
I/stbtt_MakeGlyphBitmap( 3027): info->indexToLocFormat: 1
I/stbtt_MakeGlyphBitmap( 3027): output:
I/stbtt_MakeGlyphBitmap( 3027): out_w: 6
I/stbtt_MakeGlyphBitmap( 3027): out_h: 9
I/stbtt_MakeGlyphBitmap( 3027): out_stride: 512
I/stbtt_MakeGlyphBitmap( 3027): scale_x: 5.172414E-03
I/stbtt_MakeGlyphBitmap( 3027): scale_y: 5.172414E-03
I/stbtt_MakeGlyphBitmap( 3027): glyph: 54

@nothings
Copy link
Owner

I can't reproduce it on Windows. It may be that I need more precision on scale_x & scale_y to reproduce the exact behavior, or it may just be an issue specific to the compiler etc.

Please check the following values in stbtt__rasterize when it crashes:

  • pts: check if this is a valid pointer, as this seems like the most likely way for it to go wrong
  • m,j,k: these are the integer values used to index that are causing the crash.
  • if all of the above look sane, try displaying p[j].y and p[k].y in the debugger and see which one is triggering the crash

if this mostly behaves the same as on my machine:

  • windings should be 1
  • wcount[0] should be 36
  • m should be 0
  • j,k should be less than 36
  • p == pts

@Discordia
Copy link
Author

Hey

I have had much on my plate but now I got some time for this. I'm sad to say that I have not set up gdb debugging on android yet. Maybe I should get around to doing so...anyway I'm printing the variables.

Here are the values of the variables:
I/stbtt__rasterize(21062): pts is a VALID pointer
I/stbtt__rasterize(21062): windings: 1
I/stbtt__rasterize(21062): wcount[0]: 36
I/stbtt__rasterize(21062): m: 36
I/stbtt__rasterize(21062): j: 35
I/stbtt__rasterize(21062): k: 0
I/stbtt__rasterize(21062): pts: 1617490482
I/stbtt__rasterize(21062): p: 1617490482

Only thing that is different from your machine so far is that m=36. Maybe because I'm printing inside the double for-loop and you mean the value of m before the line: m += wcount[i];

When trying to print p[j].y and p[k].y it crashes. So both of them seams to be NOK.

Better precision on scale_x and scale_y?
I/stbtt_MakeGlyphBitmap(31750): scale_x: 0.0051724137738347054
I/stbtt_MakeGlyphBitmap(31750): scale_y: 0.0051724137738347054

EDIT:
This is what I'm using to decide if pts is a valid pointer:
if (!pts) LOG("stbtt__rasterize", "pts is not a valid pointer");
else LOG("stbtt__rasterize", "pts is a VALID pointer");

But since I can't print either p[0].y or p[35].y it is probably not a valid pointer (array of stbtt_point), and my test is just crude.

EDIT 2:
Ok, I have been trying to figure this out. But I can't seam to understand it.

I think the problem is around the malloc (STBTT_malloc) for the stbtt__point *points in the function stbtt_FlattenCurves. If I add a print line in stbtt__add_point at the end trying to print the newly created point it will crash. So it does not crash on the assignment to the points variable in that function, but it do crash if I try to use it.

My stbtt__add_point:
static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
{
LOG("stbtt__add_point", "ENTER");
if (!points) return; // during first pass, it's unallocated
LOG("stbtt__add_point", "Adding a point n: %i x: %.9g y: %.9g", n, x, y);
points[n].x = x;
points[n].y = y;

LOG("stbtt__add_point", "Have added point. Printing it's value x: %.9g, y: %.9g", points[n].x, points[n].y);
}

It crashes the first time it hits the last log line. But if I do not have that line it prints all the "Adding a point", 36 of them.

@nothings
Copy link
Owner

That is pretty weird and I have no clue. :(

Is it possible you're running out of memory and Android is doing weird things as you run out?

@nothings
Copy link
Owner

Ok, here's the issue:

"signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 5a98e34e"

BUS_ADRALN is "address alignment", presumably. The memory address is not 4-byte-aligned. For whatever reason, the instruction that writes out x & y doesn't care about alignment, but the instructions that are reading the memory do care.

We can easily check this: pts is "1617490482". This would be immediately obvious if it was printed in hex, but I can type that in a calculator and divide by 4 and see that it's not a multiple of 4.

So now you need to find out why your malloc is returning you a pointer that isn't a multiple of 4. Mallocs on most/all modern platforms default to 8- or 16-byte alignment. So either you've configured this malloc to misbehave, or you (or stb_truetype) has corrupted the memory malloc uses to track memory and are causing it to misbehave.

@Discordia
Copy link
Author

Ok. To my knowledge I have not configured malloc in any way, so it's probably a memory/heap corruption that is happening. I will see if can track it down.

@Discordia
Copy link
Author

Ok, I have found the error and I have accused stb_truetype.h falsely. It is fontstash that holds the error. fontstash overrides the STBTT_malloc with this:

static void* fons__tmpalloc(size_t size, void* up)
{
unsigned char* ptr;

struct FONScontext* stash = (struct FONScontext*)up;
if (stash->nscratch+(int)size > FONS_SCRATCH_BUF_SIZE)
    return NULL;
ptr = stash->scratch + stash->nscratch;
stash->nscratch += (int)size;
return ptr;

}

That implementation of malloc wont hold the alignment property that malloc guarantees.

I have made a simple change to that malloc implementation so that I always pad the size so that it is a multiple of 4. Then I get no crash (the text written on android is garbage though, so that is the next error to try and solve).

Thanks for all your help and thanks for stb, it's a great library. I'm sorry that I bugged you when it was not stb_truetype.h that hold the error. You can close this and i will take up the error in the fontstash project instead.

@nothings
Copy link
Owner

Thanks for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants