Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-06

loadlibrary() unsafe ?

15 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

fredvs

Hello.

Here the thing: a open-source program, eSpeak (voice synthezer) uses 2 libraries: espeak-library and portaudio.

In eSpeak source =>

- For the Windows version, the libraries are included in the executable (static linked).
To do run the program => it is easy => just run the executable via TProcess (espeak.exe).

- For Linux, the eSpeak source produces a executable with static espeak-library included but without static portaudio-library included in executable.
So portaudio library must be installed in library path of the system. If portaudio is not installed in library path of the system, a trick that works is:

To do run the program =>
- first dynamic load portaudio with
loadlibrary('/the_path_you_want/libportaudio.so').
- run the executable via TProcess (espeak).

- For freeBSD, the eSpeak source produces a executable without static espeak-library nor static portaudio-library included in executable. So both espeak-library and portaudio-library must be installed in library path of the system.
If libraries are not installed in library path of the system, a trick that works is:

To do run the program =>
- first dynamic load portaudio with
loadlibrary('/the_path_you_want/libportaudio.so').
- then dynamic load libespeak with
loadlibrary('/the_path_you_want/libespeak.so').
- run the executable via TProcess (speak).

All is working like charms.

Now i heard that this trick is unsafe.

Why ?

Many thanks.

Fre;D

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801.html Sent from the Free Pascal - General mailing list .
Fred van Stappen

Hello.

Here the thing: a open-source program, eSpeak (voice synthezer) uses 2 libraries: espeak-library and portaudio.

In eSpeak source =>

- For the Windows version, the libraries are included in the executable (static linked).

To do run the program => it is easy => just run the executable via TProcess (espeak.exe).

- For Linux, the eSpeak source produces a executable with static espeak-library included but without static portaudio-library included in executable.

So portaudio library must be installed in library path of the system.

If portaudio is not installed in library path of the system, a trick that works is:

To do run the program =>

- first dynamic load portaudio with loadlibrary('/the_path_you_want/libportaudio.so').

- run the executable via TProcess (espeak).

- For freeBSD, the eSpeak source produces a executable without static espeak-library nor static portaudio-library included in executable.

So both espeak-library and portaudio-library must be installed in library path of the system.

If libraries are not installed in library path of the system, a trick that works is:

To do run the program =>

- first dynamic load portaudio with loadlibrary('/the_path_you_want/libportaudio.so').

- then dynamic load libespeak with loadlibrary('/the_path_you_want/libespeak.so').

- run the executable via TProcess (speak).

All is working like charms.

Now i heard that this trick is unsafe.

Why ?

Many thanks.

Fre;D

Mark Morgan Lloyd
to fredvs: Hello. Here the thing: a open-source program, eSpeak (voice synthezer) uses 2 libraries:…
fredvs wrote 19 lines
- For [...], the eSpeak source produces a executable without static espeak-library nor static portaudio-library included in executable. So both espeak-library and portaudio-library must be installed in library path of the system. If libraries are not installed in library path of the system, a trick that works is: To do run the program => - first dynamic load portaudio with loadlibrary('/the_path_you_want/libportaudio.so'). - then dynamic load libespeak with loadlibrary('/the_path_you_want/libespeak.so'). - run the executable via TProcess (speak). All is working like charms. Now i heard that this trick is unsafe. Why ?

I suspect that the point is that whatever reference counts that the OS maintains for the library will be decremented if the outer program terminates, at which point the demand-loaded code will be removed from memory.

Before trying anything like this, I suggest that it would be worth finding under what circumstances appropriate symlinks etc. are set up.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Ewald
to fredvs: Hello. Here the thing: a open-source program, eSpeak (voice synthezer) uses 2 libraries:…
fredvs wrote
To do run the program => - first dynamic load portaudio with loadlibrary('/the_path_you_want/libportaudio.so'). - run the executable via TProcess (espeak).

I must admit this is a creative way of solving this particular issue :-) I wonder if you have tried to set the environment variable `LD_LIBRARY_PATH` to contain `the_path_you_want` before you spawn the other process?

See also
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html : section 3.3.

Ewald
fredvs
to Ewald

@ Ewald and Mark => thanks for answer. ;-)

Yep, i agree, the process is "exotic" but works so good.

I have to agree too, following Martin Schreiber way: => export LD_PRELOAD=$LIBPORTAUDIO, before to run the executable works too.

And is maybe safer.
And do not need dynlibs in uses section.
And no need to unloadlib().

So, in short, use loadlibrary() to pre-load a library works but better not use it ;-)

Many thanks.

Fre;D

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801p5721822.html Sent from the Free Pascal - General mailing list .
Mark Morgan Lloyd
to fredvs
fredvs wrote 13 lines
@ Ewald and Mark => thanks for answer. ;-) Yep, i agree, the process is "exotic" but works so good. I have to agree too, following Martin Schreiber way: => export LD_PRELOAD=$LIBPORTAUDIO, before to run the executable works too. And is maybe safer. And do not need dynlibs in uses section. And no need to unloadlib(). So, in short, use loadlibrary() to pre-load a library works but better not use it ;-)

The best way would be to first find out what package in the OS installs the symlink or files you need, and to document this as a prerequisite.

The next-best way would be to investigate whether the wrapper can set LD_LIBRARY_PATH and export this to the loaded program.

The next-next-best way would be LD_PRELOAD, since this potentially has path issues of its own.

After that comes the way you first thought of :-)

For problems like this, man ld.so is your friend.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
fredvs
to Ewald: I must admit this is a creative way of solving this particular issue :-) I wonder if you…

Hello.

Sorry to come back with that story... ;-(

I have used inside a script LD_LIBRARY_PATH` and at end runs the espeak executable.

So a Tprocess run the script.

Ok, it works but... now i do not have access to espeak anymore, not possible to cancel the speech.

AProcess.terminate has impact on the script but not on what has done by the script.

So, the loadlibrary() approach is more efficient because the process runs espeak directly => so possible to cancel it...

Does it really have problems to use that loadlibrary() approach ?

Ok maybe first a process that run a script for assign path of lib and then a other process to run espeak ?

Many thanks.

Fre;D

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801p5721856.html Sent from the Free Pascal - General mailing list .
Ewald
to fredvs
fredvs wrote 8 lines
Hello. Sorry to come back with that story... ;-( I have used inside a script LD_LIBRARY_PATH` and at end runs the espeak executable. So a Tprocess run the script.

Why use a script? When you exec(), a parameter is available to set the environment variables[1]. Using a TProcess, try setting the `Environment` property before running it[2].

Hope it helps :-)

[1] http://linux.die.net/man/3/exec
[2]
http://www.freepascal.org/docs-html/fcl/process/tprocess.environment.html

Ewald
fredvs
to Ewald: Why use a script? When you exec(), a parameter is available to set the environment…

Re_hello.

Huh, i am loosed...

Here the working script run by TProcess (but that cannot be canceled)=> ________________________________________________
#!/bin/sh
LIBPORTAUDIO=libportaudio.so #portaudio library
ESPEAKBIN=espeak #espeak binary
CALLDIR=${0%/*}/ # directory where is ESPEAKBIN export LD_PRELOAD=$CALLDIR$LIBPORTAUDIO
$CALLDIR/$ESPEAKBIN
_______________________________________________

Now, i try to do the same with TProcess.environment =>

 - AProcess.Environment.Text := 'export
LD_PRELOAD=/home/fred/sak/sak/sakit/liblinux64/libportaudio.so'  ;
=> do not work ;-(
 - AProcess.Environment.Text :=
'LD_LIBRARY_PATH=/home/fred/sak/sak/sakit/liblinux64/'  ;
=> do not work too ;-(

Is the way how i use AProcess.Environment ok ?
Maybe i did something wrong while using environment...

Thanks.

Fre;D

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801p5721866.html Sent from the Free Pascal - General mailing list .
Giuliano Colla
to fredvs

Il 20/06/2015 17:11, fredvs ha scritto:

Show quoted text 9 lines
Re-re-re-Hello. This one does not work too ;-( => - AProcess.Environment.Text := 'LD_PRELOAD=/home/fred/sak/sak/sakit/liblinux64/libportaudio.so' ; ??? Many thanks.

Have you tried:
AProcess.Environment.Text :=
LD_LIBRARY_PATH=/home/fred/sak/sak/sakit/liblinux64/ ?
Once supplied the right folder, this should be sufficient to make the loader search the proper file.

Giuliano

Giuliano Colla Project planning question: when it's 90% done, are we halfway or not yet?
fredvs
to Giuliano Colla

@ Giuliano => thanks for advice ;-)

Hum, finally, using =>
AProcess.Environment.Text :=
'LD_PRELOAD=/home/fred/sak/sak/sakit/liblinux64/libportaudio_x64.so'  ;

It works ;-) ( was a wrong character...)

So, many, many thanks, i get the solution.

Many thanks to everybody.

Fre;D

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801p5721869.html Sent from the Free Pascal - General mailing list .
waldo kitty
to fredvs: Re-re-re-Hello. This one does not work too ;-( => - AProcess.Environment.Text :=…
fredvs wrote 5 lines
Re-re-re-Hello. This one does not work too ;-( => - AProcess.Environment.Text := 'LD_PRELOAD=/home/fred/sak/sak/sakit/liblinux64/libportaudio.so' ;

how many "sak" are there really? you have two plus "sakit"... this is the first you've posted anything of your directory structure... perhaps you can modify your script to echo the data so you can compare it?

________________________________________________
#!/bin/sh
LIBPORTAUDIO=libportaudio.so #portaudio library
ESPEAKBIN=espeak #espeak binary
CALLDIR=${0%/*}/ # directory where is ESPEAKBIN echo "export LD_PRELOAD=$CALLDIR$LIBPORTAUDIO"
export LD_PRELOAD=$CALLDIR$LIBPORTAUDIO
echo "$CALLDIR/$ESPEAKBIN"
$CALLDIR/$ESPEAKBIN
_______________________________________________

note the two echo lines i added... you should be able to see or retrieve them to see/know the live data so you can make your direct attempts work with the same...

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list* unless private contact is specifically requested and granted.
fredvs
to waldo kitty

@ Waldo => thanks for help. ;-)

But TProcess.Environment kills the script...
No script needed anymore ;-)
The script will become a program.ini...

=> Works perfectly.
TProcess.Environment.Text := 'LD_PRELOAD='/the/directory/of/thelibrary.so'
;

=> And now, canclel_speech (= TProcess.terminate) woks perfectly (not with a script).

Fre;D

PS: Excellent tip to know, many thanks for the gem.

-----
Many thanks ;-)

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/loadlibrary-unsafe-tp5721801p5721873.html Sent from the Free Pascal - General mailing list .