Hi,

I'm using urxvtd on OpenBSD, I've recently changed my setup to a larger
screen and I found when I open a bunch of terminals urxvtd was crashing.

My setup has a few points that turned out to exacerbate this:

- Tiling window manager; in order to workaround the issue where the
  cursor ends up in the middle of the screen I forced the geometry to be
  larger:
  URxvt*.geometry: 80x100

- By default OpenBSD has a somewhat low ulimit -d:
  -d: data seg size (kbytes)          1572864

- I set saveLines to 100000 for *lots* of scrollback...

The result of all this is the chunk buffer is about 160M, which with
~9 terminals in a urxvtd instance hits the ulimit -d, particularly
as it needs twice the amount for a moment (e.g. the geometry above, then
resizing to the actual size). Now I've figured out what's happening
obviously I can up the ulimit -d or lower the saveLines, but crashing
the whole urxvtd isn't nice.

With this diff I get a more obvious:

        failed chunk_alloc(164039360, 0): Cannot allocate memory

But more importantly just that instance fails to start (or is
destroyed, if it's a resize). Given there are various other places
malloc failures aren't checked this could still have some unpredictable
results, but in my testing means the new terminal fails to open, while
the daemon stays alive.

diff --git a/src/main.C b/src/main.C
index 10e5065b..721ffb12 100644
--- a/src/main.C
+++ b/src/main.C
@@ -1163,6 +1163,12 @@ rxvt_term::resize_all_windows (unsigned int newwidth, 
unsigned int newheight, in
   if (fix_screen || old_height == 0)
     scr_reset ();
 
+  if (chunk == NULL)
+    {
+      destroy();
+      return;
+    }
+
 #if USE_XIM
   im_set_position ();
 #endif
diff --git a/src/screen.C b/src/screen.C
index 8fdfad9d..b3098590 100644
--- a/src/screen.C
+++ b/src/screen.C
@@ -183,6 +183,11 @@ rxvt_term::scr_alloc () noexcept
 
   chunk_size = (sizeof (line_t) + rsize + tsize) * all_rows;
   chunk = chunk_alloc (chunk_size, 0);
+  if (chunk == NULL)
+    {
+      fprintf (stderr, "failed chunk_alloc(%d, 0): %s\n", chunk_size, 
strerror(errno));
+      return;
+    }
 
   char *base = (char *)chunk + sizeof (line_t) * all_rows;
 
@@ -254,6 +259,13 @@ rxvt_term::scr_reset ()
   line_t *prev_row_buf   = row_buf;
 
   scr_alloc ();
+  if (chunk == NULL)
+    {
+      want_refresh = 0;
+      drawn_buf = swap_buf = row_buf = 0;
+      chunk_free (prev_chunk, prev_chunk_size);
+      return;
+    }
 
   if (!prev_row_buf)
     {
@@ -446,7 +458,8 @@ rxvt_term::scr_reset ()
 void ecb_cold
 rxvt_term::scr_release () noexcept
 {
-  chunk_free (chunk, chunk_size);
+  if (chunk != NULL)
+    chunk_free (chunk, chunk_size);
   chunk = 0;
   row_buf = 0;
 
@@ -1827,6 +1840,9 @@ rxvt_term::scr_refresh_rend (rend_t mask, rend_t value) 
noexcept
 {
   bool found = false;
 
+  if (!drawn_buf)  /* sanity check */
+    return found;
+
   for (int i = 0; i < nrow; i++)
     {
       rend_t *drp = drawn_buf[i].r;


I'm also not sure mmap here serves much benefit, it doesn't look like
anything calls chunk_realloc, so given we know OpenBSD's malloc will
behave with allocations like this, it might make sense to turn this off
on OpenBSD, e.g.:

diff --git a/src/emman.c b/src/emman.c
index 65cc9e02..4647fca6 100644
--- a/src/emman.c
+++ b/src/emman.c
@@ -23,7 +23,7 @@
 # include <unistd.h>
 #endif
 
-#if _POSIX_MAPPED_FILES > 0
+#if _POSIX_MAPPED_FILES > 0 && !defined(__OpenBSD__)
 # define USE_MMAP 1
 # include <sys/mman.h>
 # ifndef MAP_FAILED

David

_______________________________________________
rxvt-unicode mailing list
[email protected]
http://lists.schmorp.de/mailman/listinfo/rxvt-unicode

Reply via email to