Re: [R-pkg-devel] R session crash on closing a graphic device on Windows
Hi Tomas, Thanks, but, if I understand correctly, there's no room to call the Rust allocator's "free" function in the case of `DevDesc`. A `DevDesc` is supposed to be freed in `GEdestroyDevDesc()` when the device is closed. If I free it by myself, it would cause double-free. So, now I'm wondering if it makes sense that R provides either an API that creates a `DevDesc` instance, or one that accepts a custom allocator for DevDesc. But, as I expect this is a minor use case, I'm not confident enough this would be meaningful. I might end up filing such a feature request on Bugzilla, but let me hold off for a while. Best, Yutani 2022年1月27日(木) 0:21 Tomas Kalibera : > > > On 1/26/22 15:44, Hiroaki Yutani wrote: > > Hi Tomas, > > > > Thanks for your helpful advice. This time, it seems the cause of the > > error was an allocator mismatch; I mistakenly allocated the struct on > > Rust's side, which means it's allocated by Rust's allocator, but a > > `DevDesc` is to be freed on R's side. The problem is solved by using > > libc::calloc(), which allocates using the C runtime's allocator, and > > compiling it with the same toolchain that compiles R. > > Hi Yutani, > > congratulations on tracing it down. > > Particularly on Windows, whenever a DLL (or any API) is providing a > function to allocate anything, it should provide also a function to free > it, and only that function should be used to do so, even if it is just a > wrapper for malloc() etc. So I would recommend following that, there > should be a Rust allocator's "free" function which you could then call > from R. > > Best > Tomas > > > > > I also saw some errors when it relates to GC, so it might be some > > PROTECT issue. Thanks for the hint. > > > > During debugging, I learned a lot about how to build R with DEBUG=T > > and use gdb, and it really helped me. I'm yet to unlock the power of > > WinDBG, but I will try next time... > > > > Best, > > Yutani > > > > 2022年1月26日(水) 23:20 Tomas Kalibera : > > > >> Hi Yutani, > >> > >> if you haven't done that already, I would recommend building R with > >> debug symbols (DEBUG=T, so that make file don't strip them) and with -O0 > >> (no optimizations), so that the debug symbols are more accurate. Without > >> that, the stack traces can be very misleading. You might try both with > >> windbg and gdb, sometimes one of them provides an extra hint. Ideally > >> you would also build the involved package(s) the same way. > >> > >> Then, it is important to check where the free() is called from, whether > >> it is directly or from the GC. In both cases (but more likely in the > >> latter), it could be caused by somewhat unrelated memory corruption, > >> which may be hard to find - e.g. possibly a PROTECT error. Running with > >> gctorture() might help, if gctorture() changes where the crash happens, > >> it is more likely a somewhat unrelated memory corruption. > >> > >> If it were a double-free or similar allocation error inside R itself (or > >> some of the involved packages), it would be easy to find with a debugger. > >> > >> If debugging this way does not help, you can try narrowing down the > >> example, while preserving the crash. That may make debugging easier, and > >> if you eventually get to a point that you have a reproducible example > >> involving only base R and base packages, you know it is a bug in R, and > >> can submit that in a bug report for others to debug. > >> > >> Best > >> Tomas > >> > >> On 1/22/22 10:50, Hiroaki Yutani wrote: > >>> Hi, > >>> > >>> I'm trying to create a Rust library that can implement an R graphic > >>> device[1], but the R session crashes on `dev.off()` on Windows with R > >>> 4.1.2. Strangely, it works without errors on Linux, on macOS, and even > >>> on Windows with R-devel. > >>> > >>> Looking at the stack trace below by WinDbg, the problem is probably > >>> that either of the two free()s in GEdestroyDevDesc() tries to free > >>> some memory that was already freed (I'm a very beginner of this kind > >>> of debugging, so I might be wrong). > >>> > >>> # Child-SP RetAddr Call Site > >>> 00 `0441cb70 7ffb`3df0be63 > >>> ntdll!RtlReportFatalFailure+0x9 > >>> 01 `0441cbc0 7ffb`3df14c82 > >>> ntdll!RtlReportCriticalFailure+0x97 > >>> ...snip... > >>> 08 `0441cfc0 7ffb`3c30c6ac ntdll!RtlFreeHeap+0x51 > >>> 09 `0441d000 `6c7bcf99 msvcrt!free+0x1c > >>> 0a `0441d030 `6c79e7de R!GEdestroyDevDesc+0x59 > >>> 0b `0441d080 `6fc828e9 R!GEcurrentDevice+0x37e > >>> 0c `0441d0f0 `6c7a15fa grDevices!devoff+0x59 > >>> ...snip... > >>> > >>> But, I found no difference in the related code (around devoff() and > >>> GEdestroyDevDesc()) between R 4.1.2 and R-devel. I know there are a > >>> lot of feature additions in R-devel, but I don't think it affects > >>> here. Is there anyone who suffered
Re: [R-pkg-devel] R session crash on closing a graphic device on Windows
I see, thanks. I filed here: https://bugs.r-project.org/show_bug.cgi?id=18292 Best, Yutani 2022年1月27日(木) 1:35 Tomas Kalibera : > > Hi Yutani, > > On 1/26/22 16:42, Hiroaki Yutani wrote: > > Hi Tomas, > > > > Thanks, but, if I understand correctly, there's no room to call the > > Rust allocator's "free" function in the case of `DevDesc`. A `DevDesc` > > is supposed to be freed in `GEdestroyDevDesc()` when the device is > > closed. If I free it by myself, it would cause double-free. > > > > So, now I'm wondering if it makes sense that R provides either an API > > that creates a `DevDesc` instance, or one that accepts a custom > > allocator for DevDesc. But, as I expect this is a minor use case, I'm > > not confident enough this would be meaningful. > > I might end up filing such a feature request on Bugzilla, but let me > > hold off for a while. > > I see. If you are using the public interface and it allows you to > (indirectly) free the devices, it should allow you also to allocate > them. So yes, please file a bug report and please provide enough context > there so that the report is self-sufficient. > > Beyond the general rule than any API allowing to allocate or free needs > to allow both, I'd leave this to the experts on graphics in R. > > Thanks, > Tomas > > > > > Best, > > Yutani > > > > 2022年1月27日(木) 0:21 Tomas Kalibera : > >> > >> On 1/26/22 15:44, Hiroaki Yutani wrote: > >>> Hi Tomas, > >>> > >>> Thanks for your helpful advice. This time, it seems the cause of the > >>> error was an allocator mismatch; I mistakenly allocated the struct on > >>> Rust's side, which means it's allocated by Rust's allocator, but a > >>> `DevDesc` is to be freed on R's side. The problem is solved by using > >>> libc::calloc(), which allocates using the C runtime's allocator, and > >>> compiling it with the same toolchain that compiles R. > >> Hi Yutani, > >> > >> congratulations on tracing it down. > >> > >> Particularly on Windows, whenever a DLL (or any API) is providing a > >> function to allocate anything, it should provide also a function to free > >> it, and only that function should be used to do so, even if it is just a > >> wrapper for malloc() etc. So I would recommend following that, there > >> should be a Rust allocator's "free" function which you could then call > >> from R. > >> > >> Best > >> Tomas > >> > >>> I also saw some errors when it relates to GC, so it might be some > >>> PROTECT issue. Thanks for the hint. > >>> > >>> During debugging, I learned a lot about how to build R with DEBUG=T > >>> and use gdb, and it really helped me. I'm yet to unlock the power of > >>> WinDBG, but I will try next time... > >>> > >>> Best, > >>> Yutani > >>> > >>> 2022年1月26日(水) 23:20 Tomas Kalibera : > >>> > Hi Yutani, > > if you haven't done that already, I would recommend building R with > debug symbols (DEBUG=T, so that make file don't strip them) and with -O0 > (no optimizations), so that the debug symbols are more accurate. Without > that, the stack traces can be very misleading. You might try both with > windbg and gdb, sometimes one of them provides an extra hint. Ideally > you would also build the involved package(s) the same way. > > Then, it is important to check where the free() is called from, whether > it is directly or from the GC. In both cases (but more likely in the > latter), it could be caused by somewhat unrelated memory corruption, > which may be hard to find - e.g. possibly a PROTECT error. Running with > gctorture() might help, if gctorture() changes where the crash happens, > it is more likely a somewhat unrelated memory corruption. > > If it were a double-free or similar allocation error inside R itself (or > some of the involved packages), it would be easy to find with a debugger. > > If debugging this way does not help, you can try narrowing down the > example, while preserving the crash. That may make debugging easier, and > if you eventually get to a point that you have a reproducible example > involving only base R and base packages, you know it is a bug in R, and > can submit that in a bug report for others to debug. > > Best > Tomas > > On 1/22/22 10:50, Hiroaki Yutani wrote: > > Hi, > > > > I'm trying to create a Rust library that can implement an R graphic > > device[1], but the R session crashes on `dev.off()` on Windows with R > > 4.1.2. Strangely, it works without errors on Linux, on macOS, and even > > on Windows with R-devel. > > > > Looking at the stack trace below by WinDbg, the problem is probably > > that either of the two free()s in GEdestroyDevDesc() tries to free > > some memory that was already freed (I'm a very beginner of this kind > > of debugging, so I might be wrong). > > > ># Child-SP RetAddr Call Site > >00 `0441cb70 00