While attempting to make use of the readline alternate interface, I found
what looks like a memory leak in Readline 6.2-8 (Ubuntu 12.04) when run
under valgrind. I don't know if this is because I am using
rl_callback_read_char() and friends improperly or if this really is a
problem with readline. I hope it is the former, and if so I would
appreciate the correct usage of the interface, on which documentation seems
to be very scant. I have attached a C program that illustrates my usage of
readline's interface, and while it works correctly as far as the interface
is concerned, whenever I attempt to use Ctrl-R to do a reverse isearch
valgrind notices the following memory leak report after I quit. The memory
leak does not appear if I do not attempt to search the history.

$ valgrind --tool=memcheck --leak-check=full --leak-resolution=high
--num-callers=20 ./rltest
==26946== Memcheck, a memory error detector
==26946== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==26946== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==26946== Command: ./rltest
==26946==
>> hello there
You said: 'hello there'
>> hello there
You said: 'hello there'
>> ==26946==
==26946== HEAP SUMMARY:
==26946==     in use at exit: 109,851 bytes in 187 blocks
==26946==   total heap usage: 322 allocs, 135 frees, 123,725 bytes allocated
==26946==
==26946== 23 bytes in 1 blocks are definitely lost in loss record 8 of 43
==26946==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26946==    by 0x4E5E618: xmalloc (xmalloc.c:61)
==26946==    by 0x4E52A7B: expand_prompt (display.c:275)
==26946==    by 0x4E53A7D: rl_message (display.c:2185)
==26946==    by 0x4E516D1: rl_display_search.isra.0 (isearch.c:198)
==26946==    by 0x4E52486: rl_search_history.isra.2 (isearch.c:656)
==26946==    by 0x4E44AED: _rl_dispatch_subseq (readline.c:774)
==26946==    by 0x4E450F1: readline_internal_char (readline.c:552)
==26946==    by 0x4E5A8EC: rl_callback_read_char (callback.c:201)
==26946==    by 0x400D0B: main (in /home/dido/rltest)
==26946==
==26946== 24 bytes in 1 blocks are definitely lost in loss record 11 of 43
==26946==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26946==    by 0x4E5E618: xmalloc (xmalloc.c:61)
==26946==    by 0x4E52A7B: expand_prompt (display.c:275)
==26946==    by 0x4E53A7D: rl_message (display.c:2185)
==26946==    by 0x4E516D1: rl_display_search.isra.0 (isearch.c:198)
==26946==    by 0x4E520E6: _rl_isearch_dispatch (isearch.c:621)
==26946==    by 0x4E52553: _rl_isearch_callback (isearch.c:693)
==26946==    by 0x4E5A7FF: rl_callback_read_char (callback.c:134)
==26946==    by 0x400D0B: main (in /home/dido/rltest)
==26946==
==26946== LEAK SUMMARY:
==26946==    definitely lost: 47 bytes in 2 blocks
==26946==    indirectly lost: 0 bytes in 0 blocks
==26946==      possibly lost: 0 bytes in 0 blocks
==26946==    still reachable: 109,804 bytes in 185 blocks
==26946==         suppressed: 0 bytes in 0 blocks
==26946== Reachable blocks (those to which a pointer was found) are not
shown.
==26946== To see them, rerun with: --leak-check=full --show-reachable=yes
==26946==
==26946== For counts of detected and suppressed errors, rerun with: -v
==26946== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

System information:

Readline Version: 6.2-8
Machine and OS: Linux 3.2.0-41-generic #66-Ubuntu SMP Thu Apr 25 03:27:11
UTC 2013 x86_64 x86_64 x86_64 GNU/Linux (Ubuntu 12.04)
#include <readline/readline.h>
#include <readline/history.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>

static char *line_read;
static int read_eof;

void rl_lthandler(char *str)
{
  line_read = str;
  if (str == NULL)
    read_eof = 1;
}

static int my_rlgetc(FILE *fp)
{
  char ch;
  int ret;

  ret = read(0, &ch, 1);
  if (ret < 0) {
    perror("read()");
    abort();
  } else if (ret == 0)
    return(EOF);
  return((int)ch);
}

int main(void)
{
  fd_set rfds;
  int retval;

  setvbuf(stdout, NULL, _IONBF, 0);
  using_history();
  rl_variable_bind("blink-matching-paren", "on");
  rl_basic_quote_characters = "\"";
  rl_basic_word_break_characters = "[]()!:~\"";
  rl_already_prompted = 1;
  rl_callback_handler_install(">> ", rl_lthandler);
  line_read = NULL;
  printf(">> ");
  for (;;) {
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    retval = select(1, &rfds, NULL, NULL, NULL);
    if (retval == -1)
      perror("select()");
    else if (retval)
      rl_callback_read_char();
    else
      continue;
    if (read_eof)
      break;

    if (line_read == NULL)
      continue;

    if (line_read && *line_read) {
      add_history(line_read);
      next_history();
      printf("You said: '%s'\n", line_read);
      printf(">> ");
      rl_on_new_line_with_prompt();
    }
    free(line_read);
    line_read = NULL;
  }
  rl_callback_handler_remove();
  return(0);
}
_______________________________________________
Bug-readline mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-readline

Reply via email to