bugmake - Bugs: bug #64295, Detect plugin binary compatibility...

 
 

bug #64295: Detect plugin binary compatibility at load time

Submitter:  Dmitry Goncharov <dgoncharov>
Submitted:  Sun 11 Jun 2023 02:36:50 PM UTC
   
 
Severity:  3 - Normal Item Group:  Enhancement
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Open
Component Version:  SCM Operating System:  None
Fixed Release:  None Triage Status:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Sun 11 Jun 2023 02:58:02 PM UTC, comment #2: 

Paul, i see that you introduced a new parameter to the setup function.
This new parameter will cause make to crash (if the user is fortunate) or it will cause some undefined behavior otherwise.
From the users point of view the cause will be difficult to figure out. The user has been using their plugin for the past 4 years and all of a sudden (they may not even know that the admin updated make on the build farm) things no longer work.
There is no indication that there is an issue with the plugin.
It looks like a crash in make (at best).
Do you think we can revert this new parameter?
If the is a reason for plugins to know the abi version of make inside their setup routine, we can add a new function that returns make abi version. The setup routine can call this new function.
i see that you mention function gmk_get_version in the manual, but i don't see such function in the source code. Did you forget to add it under git control?

There is this addition to the manual
"The major version is incremented when there is a change to the loaded object ABI, which might cause . "
Looks like an incomplete sentence.

Dmitry Goncharov <dgoncharov>
Sun 11 Jun 2023 02:44:48 PM UTC, comment #1: 

This patch implements make abi versioning for loadable plugins.

The proposed patch is binary compatible with existing plugins.
This patch allows make to detect if a plugin is binary compatible and exit with an error in the case of a binary incompatible plugin.

The patch embeds the version of make abi to the plugin in the form of a strong symbol at build time.
Then at load time make can know which version of abi each plugin was built with.  This allows make to compare the needed abi version against its load-time version and exit with an error message, if the pluging was built with an incompatible version.

The patch sets the initial version of make abi to 1.0.

Suppose have mk_temp.so plugin built with make abi 1.0.


$ ls
makefile  mk_temp.c
$ cat mk_temp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <gnumake.h>
#include <gnumake_abi_version.h>

int plugin_is_GPL_compatible;

struct tmpfile {
  struct tmpfile *next;
  char *name;
};
static struct tmpfile *files = NULL;

static char *
gen_tmpfile(const char *nm, unsigned int argc, char **argv)
{
  int fd;

  /* Compute the size of the filename and allocate space for it.  */
  int len = strlen (argv[0]) + 6 + 1;
  char *buf = gmk_alloc (len);

  strcpy (buf, argv[0]);
  strcat (buf, "XXXXXX");

  fd = mkstemp(buf);
  if (fd >= 0)
    {
      struct tmpfile *new = malloc (sizeof (struct tmpfile));
      new->name = strdup (buf);
      new->next = files;
      files = new;

      /* Don't leak the file descriptor.  */
      close (fd);
      return buf;
    }

  /* Failure.  */
  fprintf (stderr, "mkstemp(%s) failed: %s\n", buf, strerror (errno));
  gmk_free (buf);
  return NULL;
}
int
mk_temp_gmk_setup (unsigned int abi, const gmk_floc *floc)
{
  printf ("mk_temp plugin abi %u loaded from %s:%lu, needed abi %d.%d\n",
          abi, floc->filenm, floc->lineno, GMK_ABI_VERSION, GMK_ABI_AGE);
  /* Register the function with make name "mk-temp".  */
  gmk_add_function ("mk-temp", gen_tmpfile, 1, 1, 1);
  return 1;
}

void
mk_temp_gmk_unload ()
{
  while (files)
    {
      struct tmpfile *f = files;
      files = f->next;
      printf ("mk_temp removing %s\n", f->name);
      remove (f->name);
      free (f->name);
      free (f);
    }
  printf ("mk_temp plugin closed\n");
}

$ cat makefile
all:
        @echo Temporary file: $(mk-temp tmpfile.)
        @echo Temporary file: $(mk-temp tmpfile.)

-load mk_temp.so

mk_temp.so: mk_temp.c;  $(CC) -I ~/src/gmake/make/src -shared -fPIC -o $@ $^

$ make
cc -I ~/src/gmake/make/src -shared -fPIC -o mk_temp.so mk_temp.c
mk_temp plugin abi 1 loaded from makefile:5, needed abi 1.0
Temporary file: tmpfile.Uh53l3
Temporary file: tmpfile.7EQCH3
mk_temp removing tmpfile.7EQCH3
mk_temp removing tmpfile.Uh53l3
mk_temp plugin closed
$


The plugin included gnumake_abi_version.h.
mk_temp_gmk_setup uses macros GMK_VERSION, GMK_AGE.

Then we keep mk_temp.so intact and introduce a compatible change to make abi and set the version to 2.1 and rebuild make.
At load time make reads 1.0 from mk_temp.so and compares its current abi 2.1 against 1.0 and proceeds with loading the plugin.


$ make --debug=v |tail -17
Loading symbol mk_temp_gmk_setup from mk_temp.so
Loaded shared object mk_temp.so
Make abi 2.1, mk_temp.so needed abi 1.0
Detected symbol mk_temp_gmk_unload in mk_temp.so
mk_temp plugin abi 2 loaded from makefile:5, needed abi 1.0
Updating makefiles....
Updating goal targets....
Considering target file 'all'.
 File 'all' does not exist.
Finished prerequisites of target file 'all'.
Must remake target 'all'.
Temporary file: tmpfile.mKD3cK
Temporary file: tmpfile.0fr5VI
Successfully remade target file 'all'.
mk_temp removing tmpfile.0fr5VI
mk_temp removing tmpfile.mKD3cK
mk_temp plugin closed
$



Now we introduce an incompatible change to make abi and set the version to 3.0 and rebuild make.
At load time make reads 1.0 from mk_temp.so and compares 3.0 against 1.0 and exits with an error message.


$ make --debug=v 2>&1 |tail -6
Reading makefiles...
Reading makefile 'makefile'...
Loading symbol mk_temp_gmk_setup from mk_temp.so
Loaded shared object mk_temp.so
Make abi 3.0, mk_temp.so needed abi 1.0
makefile:5: *** mk_temp.so needed abi 1.0 is incompatible with make abi 3.0.  Stop.


Tested on sunos (32 and 64 bit), linux (32 and 64 bit) and aix (64 bit).

Dmitry Goncharov <dgoncharov>
Sun 11 Jun 2023 02:36:50 PM UTC, original submission:  

.

Dmitry Goncharov <dgoncharov>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by dgoncharov (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-06-11 dgoncharov Attached File- Added sv64295_detect_plugin_compat.diff, #54828

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code