Double free or corruption (!prev) but in python
Question:
cI am using pygame on repl.it, and as far as I can tell from digging around, this error usually coms from a c or c++ compiler when you attempt to free the same memory twice, but this is python, and it seems to be a repl.it thing because the error doesn’t happen in atom using my python install. This is the full error for those who can understand much of it:
double free or corruption (!prev)
SIGABRT: abort
PC=0x7f20afd05baa m=0 sigcode=18446744073709551610
signal arrived during cgo execution
goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x4bb800, 0xc000061cd8)
runtime/cgocall.go:156 +0x5c fp=0xc000061cb0 sp=0xc000061c78 pc=0x40651c
main._Cfunc_pry_eval_file(0x1ca4c10, 0x1ccf930, 0x1, 0x1d130e0)
_cgo_gotypes.go:562 +0x4c fp=0xc000061cd8 sp=0xc000061cb0 pc=0x4b944c
main.Python.EvalFile.func5(0x1d130e0, 0x8, {0xc000012230, 0x0, 0x40ced5}, 0x0)
github.com/replit/prybar/languages/python3/main.go:92 +0x75 fp=0xc000061d28 sp=0xc000061cd8 pc=0x4ba455
main.Python.EvalFile({}, {0x7fff05d4a31d, 0x7}, {0xc000012230, 0x0, 0x0})
github.com/replit/prybar/languages/python3/main.go:92 +0x20c fp=0xc000061de0 sp=0xc000061d28 pc=0x4ba22c
main.(*Python).EvalFile(0x5d56d0, {0x7fff05d4a31d, 0x5d56d0}, {0xc000012230, 0x0, 0xc00007f110})
<autogenerated>:1 +0x45 fp=0xc000061e18 sp=0xc000061de0 pc=0x4bb265
github.com/replit/prybar/utils.Language.EvalFile({{0x5075d0, 0x5d56d0}, {0x7fff05d4a307, 0xc000064100}}, {0x7fff05d4a31d, 0x7}, {0xc000012230, 0x0, 0x0})
github.com/replit/prybar/utils/language.go:86 +0xa2 fp=0xc000061e78 sp=0xc000061e18 pc=0x4b8102
github.com/replit/prybar/utils.DoCli({0x5075d0, 0x5d56d0})
github.com/replit/prybar/utils/utils.go:67 +0x2e8 fp=0xc000061f60 sp=0xc000061e78 pc=0x4b89a8
main.main()
github.com/replit/prybar/languages/python3/generated_launch.go:7 +0x27 fp=0xc000061f80 sp=0xc000061f60 pc=0x4b8bc7
runtime.main()
runtime/proc.go:255 +0x227 fp=0xc000061fe0 sp=0xc000061f80 pc=0x436d67
runtime.goexit()
runtime/asm_amd64.s:1581 +0x1 fp=0xc000061fe8 sp=0xc000061fe0 pc=0x462e41
rax 0x0
rbx 0x6
rcx 0x7f20afd05baa
rdx 0x0
rdi 0x2
rsi 0x7fff05d48c40
rbp 0x7fff05d48f80
rsp 0x7fff05d48cb8
r8 0x0
r9 0x7fff05d48c40
r10 0x8
r11 0x200246
r12 0x7fff05d48ea0
r13 0x1000
r14 0x2
r15 0x7f2086992000
rip 0x7f20afd05baa
rflags 0x200246
cs 0x33
fs 0x0
gs 0x0
repl process died unexpectedly: exit status 2
so.. that’s that, I’d be surprised if anyone can fix this I just thought it was funny, here’s the repl https://replit.com/@JSLink/Anti-aliasing#main.py, I know I’m supposed to have a minimum reproducible example but the error gives no indication (at least to my pea brain) of what is causing the error, for those wondering the change that made this start happening was adding the -1
s to lines 69, 71 and 73. If anyone wants to tell me all the flaws in my code that is welcome too as even before this error it would only work half the time and crash the rest.
here is my code
import pygame, random, math
pygame.init()
WIN_SIZE = (640, 480)
win = pygame.display.set_mode(WIN_SIZE)
pygame.display.set_caption("Anti-aliasing")
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
win.fill(WHITE)
class point:
def __init__(self, x, y):
self.x = x
self.y = y
class lineSegment:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.v = point(p2.x - p1.x, p2.y - p1.y)
def hray(self, y):
if self.v.y == 0: return None
n = (y - self.p1.y)/self.v.y
if not 0<=n<=1: return None
return self.p1.x + self.v.x * n
def vray(self, x):
if self.v.x == 0: return None
n = (x - self.p1.x)/self.v.x
if not 0<=n<=1: return None
return self.p1.y + self.v.y * n
class tri:
def __init__(self, p1, p2, p3):
self.p1 = p1
self.p2 = p2
self.p3 = p3
self.l1 = lineSegment(p2, p3)
self.l2 = lineSegment(p3, p1)
self.l3 = lineSegment(p1, p2)
left = min(p1.x, p2.x, p3.x)
top = min(p1.y, p2.y, p3.y)
right = max(p1.x, p2.x, p3.x)
bottom = max(p1.y, p2.y, p3.y)
self.bounds = pygame.Rect(left, top, right - left, bottom - top)
def hray(self, y):
output = []
l1r = self.l1.hray(y)
if l1r != None:
output.append(l1r - self.bounds.x)
l2r = self.l2.hray(y)
if l2r != None:
output.append(l2r - self.bounds.x)
l3r = self.l3.hray(y)
if l3r != None:
output.append(l3r - self.bounds.x)
if len(output) == 0: return None
if len(output) == 1:
print("fuck")
return None
#print([min(output), max(output)])
return [min(output), max(output)]
def draw(self):
surf = pygame.Surface((self.bounds.width, self.bounds.height), flags = pygame.SRCALPHA)
array = pygame.PixelArray(surf)
for y in range(self.bounds.height):
mHray = self.hray(y + self.bounds.y)
if mHray != None:
array[round(mHray[0])-1 : round(mHray[1]), y] = BLACK
shade = math.ceil(255 * (mHray[0]%1))
array[round(mHray[0])-1 , y] = (shade, shade, shade)
shade = math.ceil(255 * (mHray[1]%1))
array[round(mHray[1])-1 , y] = (shade, shade, shade)
array.close()
win.blit(surf, (self.bounds.x, self.bounds.y))
pygame.draw.rect(win, GREEN, self.bounds, 1)
pygame.draw.circle(win, RED, (self.p1.x, self.p1.y), 2)
pygame.draw.circle(win, RED, (self.p2.x, self.p2.y), 2)
pygame.draw.circle(win, RED, (self.p3.x, self.p3.y), 2)
p1 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
p2 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
p3 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
mTri = tri(p1, p2, p3)
mTri.draw()
pygame.display.update()
print("done")
Answers:
I’ve done a lot of debugging and I think I know what the problem is, because of faulty conversion from precise float coordinates to array coordinates a negative result can sometimes be outputed, or worse but this doesn’t seem to bother pygame as much, a slice can be taken where the upper coordinate is lower than the lower coordinate. I’m guessing that pygame’s indexing function can’t cope with this and doesn’t know what error to give. I’m honestly not sure how to fix the issue as it occurs in an edge case where I’m not sure myself what it should do, in any case I consider this question closed.
cI am using pygame on repl.it, and as far as I can tell from digging around, this error usually coms from a c or c++ compiler when you attempt to free the same memory twice, but this is python, and it seems to be a repl.it thing because the error doesn’t happen in atom using my python install. This is the full error for those who can understand much of it:
double free or corruption (!prev)
SIGABRT: abort
PC=0x7f20afd05baa m=0 sigcode=18446744073709551610
signal arrived during cgo execution
goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x4bb800, 0xc000061cd8)
runtime/cgocall.go:156 +0x5c fp=0xc000061cb0 sp=0xc000061c78 pc=0x40651c
main._Cfunc_pry_eval_file(0x1ca4c10, 0x1ccf930, 0x1, 0x1d130e0)
_cgo_gotypes.go:562 +0x4c fp=0xc000061cd8 sp=0xc000061cb0 pc=0x4b944c
main.Python.EvalFile.func5(0x1d130e0, 0x8, {0xc000012230, 0x0, 0x40ced5}, 0x0)
github.com/replit/prybar/languages/python3/main.go:92 +0x75 fp=0xc000061d28 sp=0xc000061cd8 pc=0x4ba455
main.Python.EvalFile({}, {0x7fff05d4a31d, 0x7}, {0xc000012230, 0x0, 0x0})
github.com/replit/prybar/languages/python3/main.go:92 +0x20c fp=0xc000061de0 sp=0xc000061d28 pc=0x4ba22c
main.(*Python).EvalFile(0x5d56d0, {0x7fff05d4a31d, 0x5d56d0}, {0xc000012230, 0x0, 0xc00007f110})
<autogenerated>:1 +0x45 fp=0xc000061e18 sp=0xc000061de0 pc=0x4bb265
github.com/replit/prybar/utils.Language.EvalFile({{0x5075d0, 0x5d56d0}, {0x7fff05d4a307, 0xc000064100}}, {0x7fff05d4a31d, 0x7}, {0xc000012230, 0x0, 0x0})
github.com/replit/prybar/utils/language.go:86 +0xa2 fp=0xc000061e78 sp=0xc000061e18 pc=0x4b8102
github.com/replit/prybar/utils.DoCli({0x5075d0, 0x5d56d0})
github.com/replit/prybar/utils/utils.go:67 +0x2e8 fp=0xc000061f60 sp=0xc000061e78 pc=0x4b89a8
main.main()
github.com/replit/prybar/languages/python3/generated_launch.go:7 +0x27 fp=0xc000061f80 sp=0xc000061f60 pc=0x4b8bc7
runtime.main()
runtime/proc.go:255 +0x227 fp=0xc000061fe0 sp=0xc000061f80 pc=0x436d67
runtime.goexit()
runtime/asm_amd64.s:1581 +0x1 fp=0xc000061fe8 sp=0xc000061fe0 pc=0x462e41
rax 0x0
rbx 0x6
rcx 0x7f20afd05baa
rdx 0x0
rdi 0x2
rsi 0x7fff05d48c40
rbp 0x7fff05d48f80
rsp 0x7fff05d48cb8
r8 0x0
r9 0x7fff05d48c40
r10 0x8
r11 0x200246
r12 0x7fff05d48ea0
r13 0x1000
r14 0x2
r15 0x7f2086992000
rip 0x7f20afd05baa
rflags 0x200246
cs 0x33
fs 0x0
gs 0x0
repl process died unexpectedly: exit status 2
so.. that’s that, I’d be surprised if anyone can fix this I just thought it was funny, here’s the repl https://replit.com/@JSLink/Anti-aliasing#main.py, I know I’m supposed to have a minimum reproducible example but the error gives no indication (at least to my pea brain) of what is causing the error, for those wondering the change that made this start happening was adding the -1
s to lines 69, 71 and 73. If anyone wants to tell me all the flaws in my code that is welcome too as even before this error it would only work half the time and crash the rest.
here is my code
import pygame, random, math
pygame.init()
WIN_SIZE = (640, 480)
win = pygame.display.set_mode(WIN_SIZE)
pygame.display.set_caption("Anti-aliasing")
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
win.fill(WHITE)
class point:
def __init__(self, x, y):
self.x = x
self.y = y
class lineSegment:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.v = point(p2.x - p1.x, p2.y - p1.y)
def hray(self, y):
if self.v.y == 0: return None
n = (y - self.p1.y)/self.v.y
if not 0<=n<=1: return None
return self.p1.x + self.v.x * n
def vray(self, x):
if self.v.x == 0: return None
n = (x - self.p1.x)/self.v.x
if not 0<=n<=1: return None
return self.p1.y + self.v.y * n
class tri:
def __init__(self, p1, p2, p3):
self.p1 = p1
self.p2 = p2
self.p3 = p3
self.l1 = lineSegment(p2, p3)
self.l2 = lineSegment(p3, p1)
self.l3 = lineSegment(p1, p2)
left = min(p1.x, p2.x, p3.x)
top = min(p1.y, p2.y, p3.y)
right = max(p1.x, p2.x, p3.x)
bottom = max(p1.y, p2.y, p3.y)
self.bounds = pygame.Rect(left, top, right - left, bottom - top)
def hray(self, y):
output = []
l1r = self.l1.hray(y)
if l1r != None:
output.append(l1r - self.bounds.x)
l2r = self.l2.hray(y)
if l2r != None:
output.append(l2r - self.bounds.x)
l3r = self.l3.hray(y)
if l3r != None:
output.append(l3r - self.bounds.x)
if len(output) == 0: return None
if len(output) == 1:
print("fuck")
return None
#print([min(output), max(output)])
return [min(output), max(output)]
def draw(self):
surf = pygame.Surface((self.bounds.width, self.bounds.height), flags = pygame.SRCALPHA)
array = pygame.PixelArray(surf)
for y in range(self.bounds.height):
mHray = self.hray(y + self.bounds.y)
if mHray != None:
array[round(mHray[0])-1 : round(mHray[1]), y] = BLACK
shade = math.ceil(255 * (mHray[0]%1))
array[round(mHray[0])-1 , y] = (shade, shade, shade)
shade = math.ceil(255 * (mHray[1]%1))
array[round(mHray[1])-1 , y] = (shade, shade, shade)
array.close()
win.blit(surf, (self.bounds.x, self.bounds.y))
pygame.draw.rect(win, GREEN, self.bounds, 1)
pygame.draw.circle(win, RED, (self.p1.x, self.p1.y), 2)
pygame.draw.circle(win, RED, (self.p2.x, self.p2.y), 2)
pygame.draw.circle(win, RED, (self.p3.x, self.p3.y), 2)
p1 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
p2 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
p3 = point(random.randrange(0, WIN_SIZE[0]), random.randrange(0, WIN_SIZE[1]))
mTri = tri(p1, p2, p3)
mTri.draw()
pygame.display.update()
print("done")
I’ve done a lot of debugging and I think I know what the problem is, because of faulty conversion from precise float coordinates to array coordinates a negative result can sometimes be outputed, or worse but this doesn’t seem to bother pygame as much, a slice can be taken where the upper coordinate is lower than the lower coordinate. I’m guessing that pygame’s indexing function can’t cope with this and doesn’t know what error to give. I’m honestly not sure how to fix the issue as it occurs in an edge case where I’m not sure myself what it should do, in any case I consider this question closed.