Skip to content

Commit

Permalink
Use Boehm-Demers-Weiser Garbage Collector.
Browse files Browse the repository at this point in the history
From their own documentation:

  The Boehm-Demers-Weiser conservative garbage collector can be used as a
  garbage collecting replacement for C malloc or C++ new. It allows you to
  allocate memory basically as you normally would, without explicitly
  deallocating memory that is no longer useful. The collector automatically
  recycles memory when it determines that it can no longer be otherwise
  accessed.

In pgcopydb C code base it's been hard to maintain proper malloc/free
concerns while also implementing proper error-handling, which is a common
problem when writing C code. In order to ease the maintenance of the code
and reduce production hazards, the best way to proceed looks like automating
the memory management altogether by using a Garbage Collector.
  • Loading branch information
dimitri committed Jan 22, 2024
1 parent 81fb66c commit f90572a
Show file tree
Hide file tree
Showing 40 changed files with 84 additions and 670 deletions.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RUN dpkg --add-architecture ${TARGETARCH:-arm64} && apt update \
valgrind \
build-essential \
libedit-dev \
libgc-dev \
libicu-dev \
libkrb5-dev \
liblz4-dev \
Expand Down Expand Up @@ -65,7 +66,8 @@ RUN dpkg --add-architecture ${TARGETARCH:-arm64} && apt update \
sudo \
passwd \
ca-certificates \
libpq5 \
libgc1 \
libpq5 \
libsqlite3-0 \
lsof \
tmux \
Expand Down
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Uploaders:
Build-Depends:
debhelper-compat (= 13),
libedit-dev,
libgc-dev,
libkrb5-dev,
liblz4-dev,
libncurses-dev,
Expand Down
77 changes: 48 additions & 29 deletions src/bin/lib/subcommands.c/runprogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@

#include "pqexpbuffer.h"

/*
* Setup Boehm-Demers-Weiser conservative garbage collector as a garbage
* collecting replacement for malloc. See https://www.hboehm.info/gc/
*/
#include <gc/gc.h>

#define malloc(n) GC_malloc(n)
#define calloc(m,n) GC_malloc((m)*(n))
#define free(p) GC_free(p)
#define realloc(p,n) GC_realloc((p),(n))
#define CHECK_LEAKS() GC_gcollect()

/*
* Now setup internal constants
*/
#define BUFSIZE 1024
#define ARGS_INCREMENT 12

Expand Down Expand Up @@ -51,7 +66,7 @@ typedef struct
char *stdErr;
} Program;

Program run_program(const char *program, ...);
Program *run_program(const char *program, ...);
void initialize_program(Program *prog, char **args, bool setsid);
void execute_subprogram(Program *prog);
void execute_program(Program *prog);
Expand All @@ -77,51 +92,55 @@ static void waitprogram(Program *prog, pid_t childPid);
* the run and then return a Program struct instance with the result of running
* the program.
*/
Program
Program *
run_program(const char *program, ...)
{
int nb_args = 0;
va_list args;
const char *param;
Program prog = { 0 };

prog.program = strdup(program);
prog.returnCode = -1;
prog.error = 0;
prog.setsid = false;
prog.capture = true;
prog.tty = false;
prog.processBuffer = NULL;
prog.stdOutFd = -1;
prog.stdErrFd = -1;
prog.stdOut = NULL;
prog.stdErr = NULL;

prog.args = (char **) malloc(ARGS_INCREMENT * sizeof(char *));
prog.args[nb_args++] = prog.program;
Program *prog = (Program *) malloc(sizeof(Program));

if (prog == NULL)
{
return NULL;
}

prog->program = strdup(program);
prog->returnCode = -1;
prog->error = 0;
prog->setsid = false;
prog->capture = true;
prog->tty = false;
prog->processBuffer = NULL;
prog->stdOutFd = -1;
prog->stdErrFd = -1;
prog->stdOut = NULL;
prog->stdErr = NULL;

prog->args = (char **) malloc(ARGS_INCREMENT * sizeof(char *));
prog->args[nb_args++] = prog->program;

va_start(args, program);
while ((param = va_arg(args, const char *)) != NULL)
{
if (nb_args % ARGS_INCREMENT == 0)
{
char **newargs = (char **) malloc((ARGS_INCREMENT *
(nb_args / ARGS_INCREMENT + 1)) *
sizeof(char *));
for (int i = 0; i < nb_args; i++)
int newcount = (ARGS_INCREMENT * (nb_args / ARGS_INCREMENT + 1));
size_t newsize = newcount * sizeof(char *);

prog->args = (char **) realloc(prog->args, newsize);

if (prog->args == NULL)
{
newargs[i] = prog.args[i];
return NULL;
}
free(prog.args);

prog.args = newargs;
}
prog.args[nb_args++] = strdup(param);
prog->args[nb_args++] = strdup(param);
}
va_end(args);
prog.args[nb_args] = NULL;
prog->args[nb_args] = NULL;

execute_subprogram(&prog);
execute_subprogram(prog);

return prog;
}
Expand Down
1 change: 1 addition & 0 deletions src/bin/pgcopydb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ LIBS += $(shell $(PG_CONFIG) --libs)
LIBS += -lpq
LIBS += -lncurses
LIBS += -lsqlite3
LIBS += -lgc

all: $(PGCOPYDB) ;

Expand Down
Loading

0 comments on commit f90572a

Please sign in to comment.