| Summary: | SIGSEGV in SDL_ConvertSurface() for certain formats in SDL2 | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Marcus von Appen <mva> |
| Component: | video | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | major | ||
| Priority: | P2 | CC: | gabomdq |
| Version: | HG 2.0 | ||
| Hardware: | All | ||
| OS: | All | ||
| Attachments: |
SDL_ConvertSurface() SIGSEGV test program
Only use Blit1* functions to blit to/from palette based formats Only use Blit0*/Blit1* functions to blit from palette based formats |
||
Are there any news on this bug? Created attachment 1125 [details]
Only use Blit1* functions to blit to/from palette based formats
The attached patch solves the SIGSEGV.
The problem is that SDL_MapSurface doesn't create a map for the formats you are using (SDL_PIXELFORMAT_RGB332 and SDL_PIXELFORMAT_RGB444), given currently it only checks if either of those formats are indexed/palette based, and if they are not it checks if both formats are the same. If they are not the same, it just keeps on going, without setting a transformation nor failing (should it return -1 in this case? )
The patch forces SDL_CalculateBlit to skip SDL_CalculateBlit1 (which returns functions that seem to be conversion map based, and depend on SDL_MapSurface to set a correct map), and instead it uses SDL_Blit_Slow unconditionally (previously there was a check, which the patch removes, to see if bytes per pixel was > 1, though there's nothing in SDL_Blit_Slow indicating that the function can't handle BPP==1).
Anyway, it seems to work here (I traced through SDL_Blit_Slow and it seems to be doing something reasonable) though I haven't checked the resulting image.
I'm leaving the patch here for Sam or Ryan to review or if anyone else is more familiarized with the surface conversion code, speak up!
Another possible fix, instead of checking if SDL_ISPIXELFORMAT_INDEXED would be checking if map->info.table != NULL (which would be more generic) Created attachment 1147 [details]
Only use Blit0*/Blit1* functions to blit from palette based formats
Fixed! http://hg.libsdl.org/SDL/rev/414ad123be9b Gabriel, I went with the INDEXED check instead of checking for the map table because I want to catch any problems where it's an indexed format without a mapping table. Thanks everyone! :) Unfortunately another crash occurs, for the combination of SDL_PIXELFORMAT_INDEX8 and SDL_PIXELFORMAT_ARGB2101010:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 805c07400 (LWP 100806/foo)]
0x00000008008dfd2e in BlitNto1 (info=0x805d5c320)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_N.c:2005
2005 DUFFS_LOOP(
(gdb) bt
#0 0x00000008008dfd2e in BlitNto1 (info=0x805d5c320)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_N.c:2005
#1 0x00000008008c1f86 in SDL_SoftBlit (src=0x806feb1c0,
srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit.c:88
#2 0x000000080090878f in SDL_LowerBlit (src=0x806feb1c0,
srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_surface.c:506
#3 0x000000080090918d in SDL_ConvertSurface (surface=0x806feb1c0,
format=0x805cd34c0, flags=0)
Within the test program, simply change SDL_PIXELFORMAT_RGB332 to SDL_PIXELFORMAT_ARGB2101010 and SDL_PIXELFORMAT_RGB444 to SDL_PIXELFORMAT_INDEX8.
And another one:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 805c07400 (LWP 100775/foo)]
0x000000080091120a in SDL_Blit_Slow (info=0x805d5c320)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_slow.c:95
95 DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
(gdb) bt
#0 0x000000080091120a in SDL_Blit_Slow (info=0x805d5c320)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_slow.c:95
#1 0x00000008008c1f86 in SDL_SoftBlit (src=0x806feb1c0,
srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit.c:88
#2 0x000000080090878f in SDL_LowerBlit (src=0x806feb1c0,
srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
at /home/marcus/devel/projects/extern/SDL/src/video/SDL_surface.c:506
#3 0x000000080090918d in SDL_ConvertSurface (surface=0x806feb1c0,
format=0x805cd34c0, flags=0)
for the combination SDL_PIXELFORMAT_RGB332 to SDL_PIXELFORMAT_ARGB2101010.
Okay, I fixed surface conversion with SDL_PIXELFORMAT_ARGB2101010, and added an automated test to cover converting between all supported pixel formats. Thanks! |
Created attachment 894 [details] SDL_ConvertSurface() SIGSEGV test program Using SDL_ConvertSurface() to convert from SDL_PIXELFORMAT_RGB444 to SDL_PIXELFORMAT_RGB332 or SDL_PIXELFORMAT_ARGB2101010 causes a SIGSEGV in the DUFFS_LOOP unrolled code segments. The problem can be reproduced on Win32 platforms, Linux and BSD, x64 builds, with the attached test program. Other source pixel formats were not tested yet. gdb backtrace: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 800e041c0 (LWP 100441/initial thread)] 0x00000008006d9017 in Blit1to2 (info=0x800e2fd20) at ../src/video/SDL_blit_1.c:103 103 DUFFS_LOOP( (gdb) bt #0 0x00000008006d9017 in Blit1to2 (info=0x800e2fd20) at ../src/video/SDL_blit_1.c:103 #1 0x00000008006d7146 in SDL_SoftBlit (src=0x800f2e5e0, srcrect=0x7fffffffe6c0, dst=0x800f2e580, dstrect=0x7fffffffe6c0) at ../src/video/SDL_blit.c:88 #2 0x000000080072079f in SDL_LowerBlit (src=0x800f2e5e0, srcrect=0x7fffffffe6c0, dst=0x800f2e580, dstrect=0x7fffffffe6c0) at ../src/video/SDL_surface.c:494 #3 0x0000000800721116 in SDL_ConvertSurface (surface=0x800f2e5e0, format=0x800ef0900, flags=0) at ../src/video/SDL_surface.c:811 #4 0x00000000004009b4 in main (argc=1, argv=0x7fffffffe7a8) at main.c:35