ALT Linux Team development discussions
 help / color / mirror / Atom feed
From: Alexey Tourbin <at@altlinux.ru>
To: ALT Devel discussion list <devel@altlinux.ru>
Subject: [devel] DynaLoader.a
Date: Wed, 1 Jun 2005 22:11:41 +0400
Message-ID: <20050601181141.GV5867@solemn.turbinal.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 5003 bytes --]

On Wed, Jun 01, 2005 at 08:11:13PM +0400, Dmitry V. Levin wrote:
> On Wed, Jun 01, 2005 at 07:55:13PM +0400, Alexey Tourbin wrote:
> > Теперь признавайтесь, кто линкуется с DynaLoader.a.
> 
> [beehive@basalt success]$ fgrep -l DynaLoader.a *
> apache-1.3.33rusPL30.20-alt2
> exim-4.51-alt1
> gaim-1.3.0-alt1
> ices-0.4-alt3.2
> inn-2.4.1-alt7
> irssi-0.8.10-alt0.3
> mmc-4.1-alt2
> net-snmp-5.2-alt1
> openldap-2.2.26-alt1
> perl-1:5.8.7-alt0.1
> perl-CGI-SpeedyCGI-2.22-alt1
> postgresql-7.4.8-alt1
> postgresql8.0-8.0.3-alt1
> vim-4:6.3.074-alt1
> weechat-0.1.1-alt1
> xchat-2.4.3-alt1

Спасибо.

Попробую объяснить суть проблемы, насколько я сам её понял.
Есть два типа приложений, которые используют perlapi(1) и,
соответственно, perl ABI.  Первый тип -- это compiled extensions,
которые сам перл, т.е. /usr/bin/perl, умеет подгружать при помощи
DynaLoader.  Это все perl-*.i586.rpm пакеты, в которых имеется *.so
файл и соответствующий ему *.pm файл.  

Механизм загрузки модулей следующий: $name.pm файл подгружает
DynaLoader.pm, а DynaLoader.pm подгружает соответствующий $name.so файл.
DynaLoader фактически является оберткой над dlopen(3) и dlsym(3).

Второй тип приложений -- это приложения, которые имеют внутри себя
встроенный интерпретатор перла, то есть имеют внутри себя некий типичный
кусок кода, похожий на кусок кода из /usr/bin/perl.  Встроенный
интерпретатор линкуется с libperl.so + DynaLoader.a и не нуждается в
/usr/bin/perl.  Последний, кстати, тоже слинкован с libperl.so +
DynaLoader.a.  Подробности встраивания описаны в perlembed(1).

Сейчас речь идет только о втором типе приложений, именно они перечислены
в списке.

Сам DynaLoader оформлен в виде DynaLoader.pm и DynaLoader.a файлов,
последний из которых содержит функцию (символ) boot_DynaLoader.  Если
встраиваемый интерпретатор поддерживает загрузку компилируемых модулей,
то при инициализации этого интерпретатора должен выполняться код:

	extern void boot_DynaLoader(); /* K&R */
	newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);

newXS заворачивает "сишную" (XS) функцию в структуру CV и вклеивает её
внутрь перлового пространства имен (gv_stashpv).  Если этого не сделать,
то сам DynaLoader.pm не сможет загрузиться, т.к. при инициализации
выполняется boot_DynaLoader(), который будет недоступен.


Ближе к делу, сейчас *любой* встроенный интерпретатор перла линкуется с
libperl.so + DynaLoader.a.  Помимо дублирования кода, возникает проблема
несовместимости между DynaLoader.pm и DynaLoader.a, которая никак не
учитывается.  На самом деле требуется, чтобы версии DynaLoader.pm и
DynaLoader.a совпадали (версия DynaLoader.a задается на стадии
компиляции).  Проведем эксперимент: отредактируем $DynaLoader::VERSION
и попробуем его загрузить:

$ diff /usr/lib/perl5/i386-linux/DynaLoader.pm{~,}
20c20
< $VERSION = '1.05';    # avoid typo warning
---
> $VERSION = '1.06';    # avoid typo warning

$ perl -MDynaLoader -e1
DynaLoader object version 1.05 does not match $DynaLoader::VERSION 1.06 at /usr/lib/perl5/i386-linux/DynaLoader.pm line 106.
Compilation failed in require.
BEGIN failed--compilation aborted.
$

То есть все встроенные интерпретаторы, слинкованные с DynaLoader.a,
совместимы с DynaLoader.pm с точностью до версии.  Это описано в
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=247291 -- при
обновлении perl-5.8.3 -> perl-5.8.4 все встроенные интерпретаторы
стали неспособны загрузить компилируемые модули.

Решение этой проблемы для меня более-менее очевидно:

1) влинковать DynaLoader.a в libperl.so.

Т.к. libperl.so и DynaLoader.pm находятся в одном пакете (perl-base),
то версия DynaLoader.a и DynaLoader.pm всегда будет одинаковой.

2) при сборке libperl.so специально пометить новые функции:

DynaLoader {
	boot_DynaLoader;
	XS_DynaLoader_dl_error;
	XS_DynaLoader_dl_find_symbol;
	XS_DynaLoader_dl_install_xsub;
	XS_DynaLoader_dl_load_file;
	XS_DynaLoader_dl_undef_symbols;
	XS_DynaLoader_dl_unload_file;
};

Тогда у пакетов, которые используют boot_DynaLoader, появится
зависимость на libperl.so.5.8(DynaLoader).

3) исключить DynaLoader.a из флагов компиляции:

$ perl -MExtUtils::Embed -e ldopts
-rdynamic -Wl,-O1 -Wl,-O1 -L/usr/local/lib64 -L/usr/local/lib /usr/lib/perl5/i386-linux/auto/DynaLoader/DynaLoader.a -L/usr/lib/perl5/i386-linux/CORE -lperl -ldl -lm -lpthread -lc -lcrypt
$

DynaLoader.a здесь быть не должно.

4) не паковать DynaLoader.a в perl-devel.


После всего остается только один вопрос: почему вообще используется
такая странная схема линковки встроенного интерпретатора: libperl.so +
DynaLoader.a.  Я не знаю точного ответа на этот вопрос.  Насколько я
предполагаю или смутно помню, это связано с особенностями загрузки
разделяемых библиотек и с работой dlopen() на некоторых экзотических
платформах.  А также на некоторых экзотических платформах dlopen()
просто не существует.


Если есть какие-нибудь соображения -- пишите.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

             reply	other threads:[~2005-06-01 18:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-01 18:11 Alexey Tourbin [this message]
2005-06-01 18:38 ` Sergey Vlasov
2005-06-01 19:43   ` [devel] DynaLoader.a Alexey Tourbin
2005-06-01 21:10   ` Alexey Tourbin
2005-06-01 21:05 ` Michael Shigorin
2005-06-01 21:27   ` Alexey Tourbin
2005-06-02  0:09     ` Alexey Tourbin
2005-06-02  0:20       ` Alexey Tourbin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050601181141.GV5867@solemn.turbinal.org \
    --to=at@altlinux.ru \
    --cc=devel@altlinux.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git