dankamongmen / notcurses

blingful character graphics/TUI library. definitely not curses.
https://nick-black.com/dankwiki/index.php/Notcurses
Other
3.51k stars 112 forks source link

[rust] segfault after creating a plane bound to the stdplane after displaying an ncvisual #1510

Closed joseluis closed 3 years ago

joseluis commented 3 years ago

I've setup the pixel-cell.rs example where if you uncomment the couple of lines, it segfaults. And if you then comment the pixels rendering it doesn't segfault.

NcPlane::new_bound() is a wrapper over ncplane_create with minimal options, just passing the x, y, rows, and cols.

dankamongmen commented 3 years ago

looking into it now. you definitely ought be able to render visuals to the standard plane.

dankamongmen commented 3 years ago

how do i build the examples? cargo build leaves no results in target/debug/examples...

joseluis commented 3 years ago

you can run a rust example manually from anywhere inside the /rust directory tree with e.g.: cargo re pixel-cell (which is an alias I setup for cargo run --example pixel-cell), that would run rust/examples/pixel-cell.rs.

dankamongmen commented 3 years ago
brk(0x55ffa3be8000)                     = 0x55ffa3be8000
write(3, "\33_Ga=d\33\\", 8)            = 8
write(3, "\33[?1h", 5)                  = 5
write(3, "\33[?25l", 6)                 = 6
write(3, "\33[39;49m", 8)               = 8
write(3, "\33(B\33[m", 6)               = 6
write(3, "\33]104\7", 6)                = 6
write(3, "\33[?1002;1006l", 13)         = 13
write(3, "\33[?1049h", 8)               = 8
write(3, "\33[H\33[2J", 7)              = 7
fcntl(3, F_GETFL)                       = 0xc02 (flags O_RDWR|O_APPEND|O_NONBLOCK)
ioctl(0, TIOCGWINSZ, {ws_row=45, ws_col=87, ws_xpixel=1044, ws_ypixel=1035}) = 0
write(1, "0\342\226\227\342\224\202\342\226\226\n\342\224\202\342\224\200 \342\224\200\n2\342\226\235\342\224\202\342\226\230"..., 33) = 33
write(1, "a cell is 23x12 pixels\n", 23) = 23
getrandom(NULL, 0, GRND_NONBLOCK)       = 0
getrandom("\xf7\x5d\x28\x3a\x8f\xfe\x10\xdf\x8f\xe3\x87\xee\x3c\xc9\xea\xe5\xc9\x7d\x39\x11\x99\x0b\xd4\x68\xdc\xd5\x42\x78\x5a\xb9\x11\x81", 32, 0) = 32
ioctl(3, TIOCGWINSZ, {ws_row=45, ws_col=87, ws_xpixel=1044, ws_ypixel=1035}) = 0
brk(0x55ffa3c0c000)                     = 0x55ffa3c0c000
mmap(NULL, 188416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc96f9fb000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x20} ---
dankamongmen commented 3 years ago

so all you seem to be doing here is creating a 4x4 plane...how do i set notcurses_options.loglevel in this code? ncplane_new_internal() is pretty good about emitting diagnostics.

dankamongmen commented 3 years ago

if i move the two suspect lines higher in the program, they do not segfault. interesting.

dankamongmen commented 3 years ago
==35359== Invalid read of size 4
==35359==    at 0x48C4D42: ??? (in /usr/lib/libnotcurses-core.so.2.2.5)
==35359==    by 0x48BD360: ??? (in /usr/lib/libnotcurses-core.so.2.2.5)
==35359==    by 0x48BFC38: ncpile_render (in /usr/lib/libnotcurses-core.so.2.2.5)
==35359==    by 0x48C09C0: notcurses_render (in /usr/lib/libnotcurses-core.so.2.2.5)
==35359==    by 0x115383: libnotcurses_sys::notcurses::methods::<impl libnotcurses_sys::bindings::ffi::notcurses>::render (src/notcurses/methods.rs:500)
==35359==    by 0x111F9E: pixel_cell::main (examples/pixel-cell.rs:62)
==35359==    by 0x112CE1: core::ops::function::FnOnce::call_once (function.rs:227)
==35359==    by 0x111189: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:125)
==35359==    by 0x111235: std::rt::lang_start::{{closure}} (rt.rs:66)
==35359==    by 0x180E46: call_once<(),Fn<()>> (function.rs:259)
==35359==    by 0x180E46: do_call<&Fn<()>,i32> (library/std/src/panicking.rs:379)
==35359==    by 0x180E46: try<i32,&Fn<()>> (library/std/src/panicking.rs:343)
==35359==    by 0x180E46: catch_unwind<&Fn<()>,i32> (library/std/src/panic.rs:431)
==35359==    by 0x180E46: std::rt::lang_start_internal (library/std/src/rt.rs:51)
==35359==    by 0x111206: std::rt::lang_start (rt.rs:65)
==35359==    by 0x1122D9: main (in /home/dank/src/dankamongmen/notcurses/rust/target/debug/examples/pixel-cell)
==35359==  Address 0x20 is not stack'd, malloc'd or (recently) free'd
dankamongmen commented 3 years ago

interesting...according to that stack trace, we're failing in

pixels.destroy()

where pixels is a NcVisual created using from_rgba(). why would that lead to a render?

dankamongmen commented 3 years ago

NcVisual::destroy() only seems to call ncvisual_destroy()...

dankamongmen commented 3 years ago
YANK THAT FB 62640
YANKED THAT FB 62640 0x558588594ec0
Created new 45x87 plane "std" @ 0x0

hrmmm so we're only getting one plane created before the segfault (never even hitting ncplane_new_internal() a second time)....

dankamongmen commented 3 years ago

there's no coredump if i comment out the following line:

//pixels.render(&mut nc, &voptions)?;

i can have the next two (currently commented-out) lines enabled just fine without that.

joseluis commented 3 years ago

there's no coredump if i comment out the following line: //pixels.render(&mut nc, &voptions)?;

yeah I noticed that in my first post...

And if you then comment the pixels rendering it doesn't segfault.

I'm thinking if an equivalent C code doesn't core dump, maybe I did something wrong in the rust wrappers.

dankamongmen commented 3 years ago

there's no coredump if i comment out the following line: //pixels.render(&mut nc, &voptions)?; yeah I noticed that in my first post...

ahh, indeed

And if you then comment the pixels rendering it doesn't segfault. I'm thinking if an equivalent C code doesn't core dump, maybe I did something wrong in the rust wrappers.

.nod, i am just trying to figure out exactly what the equivalent C code would be., i expected to see things pretty clearly using ltrace, but it did not yield the insights that i had hoped for.

i do know that i put a diagnostic in ncplane_new_internal() (where all ncplane manufacture converges), and only saw one plane even attempt to be created (the standard plane). that seems surprising, given that you're doing an ncvisual_render() with a NULL ncvisual_options.n (presumably).

dankamongmen commented 3 years ago

i'm thinking about cutting a 2.2.6 today, but if you'd like me to hold off, that's no problem and just let me know

joseluis commented 3 years ago

you can release if you want. you know... the rust bindings are always going to be out of sync in any case

I've just fixed several things

dankamongmen commented 3 years ago

you can release if you want. you know... the rust bindings are always going to be out of sync in any case

I've just fixed several things

sure, but i'd rather not narrowly miss anything etc! =]

joseluis commented 3 years ago

This bug has been fixed automatically also :)