Hi,

Sorry, I did get your email yesterday, but I wanted to spend some more
time checking it. I did patch my code according to your suggestions
and it did not help - also, we are using dlsym to locate functions, so
they would definitely not be NULL.

Maybe also some background on the issue - I am using TclKit, which
allows single binary distribution of Tcl apps. It does the unpack +
dlopen + unlink to unpack and load C extensions. That does not work at
all with people using docker, which caused some of them to complain
back to me. I am no aufs/docker expert, mainly creating an application
that does not work on docker. I will probably need to work around it
somehow for now, but I'd also want aufs to properly handle this.

I will try and recompile latest aufs (I am using the one from Ubuntu
12.04) - just to understand if this may have be because of older aufs
version in Ubuntu. I will let you know once I do that.

As for read/write differences - I added checking for write() and
read() result and I did not see any differences. I am wondering,
however, if it is possible that the created .so was smaller and this
is why it was working fine for you. I am attaching an updated code
that creates much larger .so files and more exported functions in case
this was why it was working fine for you. Maybe that will allow
reproducing it on your side?

2013/10/8  <sf...@users.sourceforge.net>:
>
> Hmm, the bug ticket service on SourceForge doesn't seem to deliver my
> mail expectedly. So I am forwarding here with hoping Wojciech Kocjan
> awares.
>
> sf...@users.sourceforge.net:
>>
>> Hello Wojciech,
>>
>> "Wojciech Kocjan":
>> > 1/ open() a temp file, write() contents of .so to the file and close() it
>> > 2/ perform dlopen() on the file and dlsym() to find one or more symbols
>> > 3/ perform unlink() to remove it, while keeping handle from dlopen() open 
>> > - NOT calling dlclose() - since the code calls APIs from the temp .so
>> > 4/ this library works, but subsequent calls fail
>>
>> Will you see an error after fixing your test code like this?
>>
>> --- /tmp/aufs-dlopen-unlink-error.c   2013-10-07 18:06:53.000000000 +0900
>> +++ ./a.c     2013-10-07 22:13:09.626923806 +0900
>> @@ -24,10 +24,15 @@
>>       dl = dlopen(filebuf, RTLD_NOW | RTLD_GLOBAL);
>>       if (dl != NULL)
>>       {
>> -         if (dlsym(dl, funcname) == NULL)
>> -             printf("%s: unable to dlsym()\n", funcname);
>> +         void *p;
>> +         char *s;
>> +         dlerror();
>> +         p = dlsym(dl, funcname);
>> +         s = dlerror();
>> +         if (s)
>> +             printf("%s: unable to dlsym(), %s\n", funcname, s);
>>           else
>> -             printf("%s: OK\n", funcname);
>> +             printf("%s: OK, %p\n", funcname, p);
>>       }
>>       else
>>           printf("%s: unable to dlopen()\n", funcname);
>>
>> According to "man dlsym", the return value NULL doesn't indicate an
>> error. But I don't know you can call the function via NULL ptr.
>> Anyway, regardless this patch, I could not reproduce the problem on my
>> test system.
>>
>> (result on my test system)
>> Test_FuncA: OK, 0x7f7e66c20670
>> Test_FuncB: OK, 0x7f7e66a1f670
>>
>> For deeper investigate,
>> - in your test program, you should check the return value of all
>>   libraries and systemcalls.
>> - please read aufs README file, and post the necessary info to
>>   aufs-users ML.
>>
>>
>> J. R. Okajima
>
> And most suspicious part in your test program is the shortage of read()
> and write(). Eg. their return value is smaller than its argument.
>
>
> J. R. Okajima
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

void test_dlopen(char *funcname, int dlsize, char *dldata)
{
    char filebuf[64];
    void *dl;
    int fd;
    int s2;

    strcpy(filebuf, "/tmp/dlopenXXXXXX");
    mktemp(filebuf);
    fd = open(filebuf, O_CREAT|O_WRONLY|O_TRUNC, 0755);
    if (fd >= 0)
    {
	s2 = write(fd, dldata, dlsize);
	if (s2 != dlsize)
	    printf("Unable to write data - %08x vs %08x", dlsize, s2);
	close(fd);
	dl = dlopen(filebuf, RTLD_NOW | RTLD_GLOBAL);
	if (dl != NULL)
	{
	    if (1)
	    {
		void *p;
		char *s;
		dlerror();
		p = dlsym(dl, funcname);
		s = dlerror();
		if (s)
		{
		    printf("%s: %s\n", funcname, s);
		}
		else
		{
		    printf("%s: OK, %p\n", funcname, p);
		}
	    }
	    else
		printf("%s: OK\n", funcname);
	}
	else
	    printf("%s: unable to dlopen()\n", funcname);
	unlink(filebuf);
    }  else  {
	printf("%s: unable to create temp file\n", funcname);
    }
}

char *build_so(int *sizePtr, char *funcname)
{
    static char buf[1048576];
    char filebuf[64];
    char filebufc[64];
    int i;
    int s1, s2;
    char *result = NULL;
    struct stat statbuf;
    void *dl;
    int fd;

    strcpy(filebuf, "/tmp/dlopenXXXXXX");
    mktemp(filebuf);
    sprintf(filebufc, "%s.c", filebuf);

    unlink(filebuf);

    strcpy(buf, "#include <stdlib.h>\n");
    sprintf(buf + strlen(buf), "static char *dummyBuffer = \"\"\n");
    for (i = 0 ; i < 2048; i++) {
	sprintf(buf + strlen(buf), "    \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\n");
    }
    sprintf(buf + strlen(buf), "    \"\";\n");
    for (i = 0 ; i < 4096; i++) {
    sprintf(buf + strlen(buf), "char *Dummy_%s_%04d(void) { return dummyBuffer; }\n", funcname, i);
    }
    sprintf(buf + strlen(buf), "char *%s(void) { return dummyBuffer; }\n", funcname);

    fd = open(filebufc, O_CREAT|O_WRONLY|O_TRUNC, 0644);
    if (fd >= 0)
    {
	write(fd, buf, strlen(buf));
	close(fd);
	sprintf(buf, "gcc -shared -o \"%s\" \"%s\"", filebuf, filebufc);
	system(buf);
    }

    fd = open(filebuf, O_RDONLY);
    if (fd >= 0)
    {
	stat(filebuf, &statbuf);
	s1 = statbuf.st_size;
	*sizePtr = s1;
	result = malloc(s1);
	s2 = read(fd, result, s1);
	if (s1 != s2) {
	    printf("UNABLE TO READ SO: %08x vs %08x\n", s1, s2);
	}
	close(fd);
    }
    return result;
}


main()
{
    char *buf1, *buf2;
    int bufSize1, bufSize2;
    buf1 = build_so(&bufSize1, "Test_FuncA");
    buf2 = build_so(&bufSize2, "Test_FuncB");

    test_dlopen("Test_FuncA", bufSize1, buf1);
    test_dlopen("Test_FuncB", bufSize2, buf2);
}

------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clktrk

Reply via email to