Re: [Jack-Devel] [Fwd: Re: [Guitarix-developer] jack session crash]

PrevNext  Index
DateWed, 02 Nov 2011 23:05:59 +0100
From Andreas Degert <[hidden] at papyrus-gmbh dot de>
ToPaul Davis <[hidden] at linuxaudiosystems dot com>
Cc[hidden] at lists dot jackaudio dot org
In-Reply-ToPaul Davis Re: [Jack-Devel] [Fwd: Re: [Guitarix-developer] jack session crash]
On Wed, 2 Nov 2011 16:51:02 -0400
Paul Davis <[hidden]> wrote:

> On Wed, Nov 2, 2011 at 4:49 PM, Paul Davis
> <[hidden]> wrote:
> > On Wed, Nov 2, 2011 at 4:28 PM, Andreas Degert <[hidden]>
> > wrote:
> >
> >> Hi Paul, I'm the original author of the mail that hermann
> >> forwarded. Which part of my mail do you not understand? I thought
> >> I explained the problem :-)
> >
> >> AFAICS jackweak.h defines JACK_OPTIONAL_WEAK_EXPORT and
> >> JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT, whereas the mentioned
> >> functions from jack/session.h use JACK_WEAK_EXPORT, which is
> >> defined in jack/weakmacros.h, which is included by session.h.
> >
> > fair point, i forgot that this was a mandatorily weakly linked
> > symbol. this doesn't really make any difference to the point.
> >
> > what does this show:
> >
> >    nm YourExecutable | grep jack_
> >
>  just for reference, this is what I get:
> 
> paul@sextet[2930]>cc -o js js.c -l jack
> paul@sextet[2931]>./js
> jack_client_get_uuid = 0x400510, jack_get_uuid_for_client_name = (nil)
> paul@sextet[2932]>nm js | grep jack_
>                  w jack_client_get_uuid
>                  w jack_get_uuid_for_client_name

My post was not about getting weak linking to work, without
weak symbols my test program would just have gotten a linker error.

It's about how weak linking works, and especially about how to test
if a symbol is in the shared library loaded into the current process.

If you test if the address of the function in your program is 0,
according to my test program you will not get that information (but
you need to execute the test program with both jackd1 and jackd2 libs
without recompiling).

Specifically to the situation we have in guitarix:

for session handling we need the uuid of the second guitarix jack
client (for the first its in the event structure). The two functions
in the test program can be used for that, but jackd1 has only the first
function, and jackd2 only the second.

So I thought the theory was to write something like

if (jack_client_get_uuid) {
    jack_client_get_uuid(...);
} else if (jack_get_uuid_for_client_name) {
    jack_get_uuid_for_client_name(...);
}

and e.g. compile it with jackd1 libs. When you start it the first
branch is taken. fine. Then uninstall jackd1, install jackd2 and
start it again. Second branch taken? no... crash...
jack_client_get_uuid is not 0, but when it's called it will crash at
address 0. Even if jack_client_get_uuid had been 0 now,
jack_get_uuid_for_client_name is set to constant 0 by the linker
building the executable because it didn't find it in any library.

When you recompile with jackd2, now you can start it (takes second
branch), but will crash with jackd1.

So we had to solve it by not referencing the functions in the program
but instead resolving them manually with dlsym().

ciao
Andreas
PrevNext  Index

1320271605.2166_0.ltw:2,a <20111102230559.4146207c at pluto dot noname>