multibake improvement with symbol collisions

  • From: Antti Kantee <pooka@xxxxxx>
  • To: rumpkernel-users <rumpkernel-users@xxxxxxxxxxxxx>
  • Date: Fri, 25 Sep 2015 18:50:44 +0000

Hi,

Sebastian reported that multibaking didn't work with programs which have been linked against the same library. Fixing it was so easy (*) that I wonder if I forgot completely about something, but I haven't been able to figure out what I'd have forgotten, and things seem to work, so maybe I didn't forget about anything.

*) Added -G $main into the objcopy invocations in the cc wrapper.

After the change, multibaked programs won't see each others *symbol* namespaces. They will still be able to access the rump kernel (global) and also each others memories via pointers. The attached two programs sort of demonstrate things. When baked together, they produce the output at the end of the mail. And no, we still don't have a way to pass individual argv's to multibaked programs, so argv[0] = binary name.

- antti


=== calling "rr" main() ===

2: daemonizing listening proc
2: waiting for incoming connections

=== calling "rr" main() ===

3: connected
3: got mutex at 0x3520a0
2: jee
2: jee
3: got lock

=== main() of "rr" returned 0 ===

=== _exit(0) called ===
2: jee2

=== main() of "rr" returned 0 ===

=== _exit(0) called ===
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <err.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>

pthread_mutex_t mymtx = PTHREAD_MUTEX_INITIALIZER;

const char *polku = "/tmp/local-sucket";

/* XXX */
void rumprun_daemon(void);

void
myprint(const char *fmt, ...)
{
va_list ap;

printf("%d: ", getpid());
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}

int
main()
{
struct sockaddr_un sun;
socklen_t slen;
int s, s2;
pthread_mutex_t *mtxptr;

memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, polku);
sun.sun_len = SUN_LEN(&sun);

s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1)
err(1, "unix socket");

if (bind(s, (struct sockaddr *)&sun, sizeof(sun)) == -1)
err(1, "bind");
if (listen(s, 1) == -1)
err(1, "listen");

myprint("daemonizing listening proc\n");
rumprun_daemon();

slen = sizeof(sun);
myprint("waiting for incoming connections\n");
if ((s2 = accept(s, (struct sockaddr *)&sun, &slen)) == -1)
err(1, "accept");

mtxptr = &mymtx;
pthread_mutex_lock(mtxptr);
write(s2, &mtxptr, sizeof(mtxptr));

sched_yield();
myprint("jee\n");
sched_yield();
myprint("jee\n");

pthread_mutex_unlock(mtxptr);
sched_yield();

myprint("jee2\n");
return 0;
}
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <err.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>

pthread_mutex_t *mymtx;

const char *polku = "/tmp/local-sucket";

/* XXX */
void rumprun_daemon(void);

void
myprint(const char *fmt, ...)
{
va_list ap;

printf("%d: ", getpid());
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}

int
main()
{
struct sockaddr_un sun;
socklen_t slen;
int s, s2;
pthread_mutex_t *mtxptr;

memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, polku);
sun.sun_len = SUN_LEN(&sun);

s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1)
err(1, "unix socket");

if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1)
err(1, "connect");

myprint("connected\n");

read(s, &mymtx, sizeof(mymtx));

myprint("got mutex at %p\n", mymtx);

pthread_mutex_lock(mymtx);
myprint("got lock\n");

return 0;
}

Other related posts: