Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

[Solved] How do I find the binary package that contains a C function?

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
Aki
Global Moderator
Global Moderator
Posts: 2979
Joined: 2014-07-20 18:12
Location: Europe
Has thanked: 75 times
Been thanked: 407 times

[Solved] How do I find the binary package that contains a C function?

#1 Post by Aki »

Hello,

How do I find the Debian binary package containing a C function ?

For example, the source package named "samba" [1] generates the binary code for the C function named "remote_password_change" with the following prototype:

Code: Select all

NTSTATUS remote_password_change(const char *remote_machine,
				const char *domain, const char *user_name,
				const char *old_passwd, const char *new_passwd,
				char **err_str);
Its definition is in the source file ./source3/libsmb/passchange.c included in the Debian source package for samba binary package: How can I find the binary file containing the compiled code of function's definition and the binary Debian package that contains it ?

Is there a command to search packages for the name of C functions compiled in its binaries ?

Thanks.
Aki.

--
[1] https://tracker.debian.org/pkg/samba
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Debian - The universal operating system
⢿⡄⠘⠷⠚⠋⠀ https://www.debian.org
⠈⠳⣄⠀

lindi
Debian Developer
Debian Developer
Posts: 452
Joined: 2022-07-12 14:10
Has thanked: 1 time
Been thanked: 88 times

Re: How do I find the binary package that contains a C function?

#2 Post by lindi »

Fetch -dbgsym packages for all of the binary packages generated from the source package. Then use "nm" to list symbols in those binaries? This still won't help if the function got inlined though.

Aki
Global Moderator
Global Moderator
Posts: 2979
Joined: 2014-07-20 18:12
Location: Europe
Has thanked: 75 times
Been thanked: 407 times

Re: How do I find the binary package that contains a C function?

#3 Post by Aki »

Hello lindi,
lindi wrote: 2023-11-04 18:50
How do I find the Debian binary package containing a C function ?

For example, the source package named "samba" [1] generates the binary code for the C function named "remote_password_change" with the following prototype:

Code: Select all

NTSTATUS remote_password_change(const char *remote_machine,
				const char *domain, const char *user_name,
				const char *old_passwd, const char *new_passwd,
				char **err_str);
Fetch -dbgsym packages for all of the binary packages generated from the source package. Then use "nm" to list symbols in those binaries? This still won't help if the function got inlined though.
I followed your hint:

1) I configured /etc/apt/sources.list to add debian-debug repositories:

Code: Select all

deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian bookworm main non-free-firmware

deb http://deb.debian.org/debian bookworm-updates main non-free-firmware
deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware

deb http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware
deb-src http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware

# Debug Symbols
deb http://deb.debian.org/debian-debug/ bookworm-debug main contrib non-free non-free-firmware
deb http://deb.debian.org/debian-debug/ bookworm-proposed-updates-debug main
2) Using the Debian site at https://packages.debian.org , I searched for the Debian source package of the samba binary package: I obtained the following output:
Source Package samba

bookworm (net): 2:4.17.12+dfsg-0+deb12u1 [security]

Binary packages: [hide 26 binary packages] ctdb, ldb-tools, libldb-dev, libldb2, libnss-winbind, libpam-winbind, libsmbclient, libsmbclient-dev, libwbclient-dev, libwbclient0, python3-ldb, python3-ldb-dev, python3-samba, registry-tools, samba, samba-ad-dc, samba-ad-provision, samba-common, samba-common-bin, samba-dev, samba-dsdb-modules, samba-libs, samba-testsuite, samba-vfs-modules, smbclient, winbind
3) I copied, pasted and manually edited all the names of the binary packages built from the source package named "samba".
Then, I assembled the following command (a simulated install) replacing the ',' character from previous output with "-dbgsym" (all symbols packages created by Debian project use the "-dbgsym" suffix):

Code: Select all

# apt -s install ctdb-dbgsym  ldb-tools-dbgsym  libldb-dev-dbgsym  libldb2-dbgsym  libnss-winbind-dbgsym  libpam-winbind-dbgsym  libsmbclient-dbgsym  libsmbclient-dev-dbgsym  libwbclient-dev-dbgsym  libwbclient0-dbgsym  python3-ldb-dbgsym  python3-ldb-dev-dbgsym  python3-samba-dbgsym  registry-tools-dbgsym  samba-dbgsym  samba-ad-dc-dbgsym  samba-ad-provision-dbgsym  samba-common-dbgsym  samba-common-bin-dbgsym  samba-dev-dbgsym  samba-dsdb-modules-dbgsym  samba-libs-dbgsym  samba-testsuite-dbgsym  samba-vfs-modules-dbgsym  smbclient-dbgsym  winbind
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package libldb-dev-dbgsym
E: Unable to locate package libsmbclient-dev-dbgsym
E: Unable to locate package libwbclient-dev-dbgsym
E: Unable to locate package python3-ldb-dev-dbgsym
E: Unable to locate package samba-ad-dc-dbgsym
E: Unable to locate package samba-ad-provision-dbgsym
E: Unable to locate package samba-common-dbgsym
E: Unable to locate package samba-dev-dbgsym
As you can see, some binary packages have no debug symbol packages. They are "-dev" packages, while the others packages I suppose don't contain libraries or executable code, therefore I suppose they could not supply debug symbols.

4) I modified the previous simulated command, removing references to not existing "-dbgsym" packages:

Code: Select all

# apt install ctdb-dbgsym  ldb-tools-dbgsym   \
    libldb2-dbgsym  libnss-winbind-dbgsym  libpam-winbind-dbgsym \
    libsmbclient-dbgsym libwbclient0-dbgsym  python3-ldb-dbgsym  \
    python3-samba-dbgsym  registry-tools-dbgsym  samba-dbgsym  \
    samba-common-bin-dbgsym  samba-dsdb-modules-dbgsym  \
    samba-libs-dbgsym  samba-testsuite-dbgsym  samba-vfs-modules-dbgsym \
    smbclient-dbgsym  winbind
5) I searched for the name of the C function named "remote_password_change" (using the nm package you advised to me) in debug symbols (note: "-dbgsym" packages store their "*.debug" files in the directory named /usr/lib/debug/ )

Code: Select all

# find /usr/lib/debug -name "*.debug" -exec nm --print-file-name --line-numbers {} 2>&1 \; | grep "remote_password_change" 
It took about 6 minutes; the output was:

Code: Select all

# find /usr/lib/debug -name "*.debug" -exec nm --print-file-name --line-numbers {} 2>&1 \; | grep "remote_password_change" 
/usr/lib/debug/.build-id/db/feab433239b8e04dcce44968d70346ac03571a.debug:0000000000005830 T remote_password_change      ./bin/default/../../source3/libsmb/passchange.c:37
Now I missing the last step: how can I tell which Debian binary package and binary executable (program) the following file refers to?

Code: Select all

/usr/lib/debug/.build-id/db/feab433239b8e04dcce44968d70346ac03571a.debug
Is there a smarter way to do all this?
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Debian - The universal operating system
⢿⡄⠘⠷⠚⠋⠀ https://www.debian.org
⠈⠳⣄⠀

lindi
Debian Developer
Debian Developer
Posts: 452
Joined: 2022-07-12 14:10
Has thanked: 1 time
Been thanked: 88 times

Re: How do I find the binary package that contains a C function?

#4 Post by lindi »

You can get build id of a binary using

Code: Select all

readelf -n BINARY
. Now you just need to find the binary with build id dbfeab433239b8e04dcce44968d70346ac03571a.

peter_irich
Posts: 1406
Joined: 2009-09-10 20:15
Location: Saint-Petersburg, Russian Federation
Been thanked: 11 times

Re: How do I find the binary package that contains a C function?

#5 Post by peter_irich »

When I needed to find the so-library with some symbols, I run this script in the suspected directory with libraries:

Code: Select all

#!/bin/bash

/bin/rm -f ~/lib_s-lst ~/lib_s.lst
for bn in [ `/bin/ls *.so*` ]
do
if [ ! -h $bn ] && [ -f $bn ] ; then
echo $bn
echo $bn >> ~/lib.lst
#readelf -s $bn > ~/lst 2>&1
/usr/bin/nm -C -D $bn > ~/lst   2>&1
#objdump -t $fn > lst
#fn=`grep -e "[[:print:]]" < ~/lst| grep -cE " ${1}"`
fn=`/usr/bin/grep -e "[[:print:]]" < ~/lst| /usr/bin/grep -cE "${1}"`
if [ $fn -gt 0 ] ; then
echo $bn $1 $fn
echo $bn $1 $fn >> ~/lib_s.lst 2>&1
#exit
fi
fi
done
/bin/rm -f ~/lst
Argument is a symbol name. If such library will be found, its name will be in the file in $HOME.
Then you can the packge with this library by command

Code: Select all

dpkg -S pull_path/library_name

Aki
Global Moderator
Global Moderator
Posts: 2979
Joined: 2014-07-20 18:12
Location: Europe
Has thanked: 75 times
Been thanked: 407 times

Re: How do I find the binary package that contains a C function?

#6 Post by Aki »

Hello,
lindi wrote: 2023-11-05 22:10 You can get build id of a binary using

Code: Select all

readelf -n BINARY
. Now you just need to find the binary with build id dbfeab433239b8e04dcce44968d70346ac03571a.
@lindi:
Thanks. :D Inspired by your tip, I searched the build id using the grep-dctrl [1] command (with the -F parameter, I selected the "Build-Ids" field as the package to search for; with the -s parameter, I selected the "Depends" field as the package to print):

Code: Select all

# apt-cache dumpavail |  grep-dctrl -F Build-Ids  feab433239b8e04dcce44968d70346ac03571a -s Depends
Depends: samba-common-bin (= 2:4.17.12+dfsg-0+deb12u1)
The previous command reports that the search build-Id is computed on a binary file from samba-common-bin package.

Then I identified the binary file with the following command:

Code: Select all

# apt-file list samba-common-bin | 
   cut -d ":" -f 2 | 
   LANG=C xargs readelf -n BINARY 2> /dev/null | 
   grep -e 'File\|Build ID' |  
   grep -B1 -e feab433239b8e04dcce44968d70346ac03571a

File: /usr/bin/smbpasswd
    Build ID: dbfeab433239b8e04dcce44968d70346ac03571a
Therefore, the build-Id is computed of the file /usr/bin/smbpasswd.

@peter_irich:
Thanks. :D Inspired by your tip, I used it to speed up the whole search (knowing the name of the binary):

Code: Select all

# apt-file list samba-common-bin | 
   cut -d ":" -f 2 | 
   xargs nm -A -C -D  2>/dev/null  | 
   grep -e "remote_password_change"

/usr/bin/smbpasswd:0000000000005830 T remote_password_change
The nm options [2] used are:

Code: Select all

-A
-o
--print-file-name
    Precede each symbol by the name of the input file (or archive member) in which it was found, rather than identifying the input file once only, before all of its symbols.

-C
--demangle[=style]
    Decode (demangle) low-level symbol names into user-level names. Besides removing any initial underscore prepended by the system, this makes C++ function names readable. Different compilers have different mangling styles. The optional demangling style argument can be used to choose an appropriate demangling style for your compiler.
     
-D
--dynamic
    Display the dynamic symbols rather than the normal symbols. This is only meaningful for dynamic objects, such as certain types of shared libraries.
It would be nice to compact all this in fewer commands.

---
[1] https://manpages.debian.org/bookworm/dctrl-tools/grep-dctrl.1.en.html
[2] https://manpages.debian.org/bookworm/binutils-common/nm.1.en.html
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Debian - The universal operating system
⢿⡄⠘⠷⠚⠋⠀ https://www.debian.org
⠈⠳⣄⠀

Aki
Global Moderator
Global Moderator
Posts: 2979
Joined: 2014-07-20 18:12
Location: Europe
Has thanked: 75 times
Been thanked: 407 times

Re: How do I find the binary package that contains a C function?

#7 Post by Aki »

Hello,

I reworked the commands from previous posts replacing:

Code: Select all

apt-cache dumpavail | grep-dctrl ...
with

Code: Select all

grep-aptavail ...
as per manual [1].

These are the command sequences I found useful:

1) install all binary packages generated by a source package (it queries local apt cache for "samba" source package in the example):

Code: Select all

# TMP=$(mktemp)
   grep-aptavail -n -S samba --and --not -F Section debug -s Package > "$TMP"
   xargs -a $TMP apt install
   rm "$TMP"
2) install all both binary and dbgsym packages generated by a source package (it queries local apt cache for "samba" source package in the example):

Code: Select all

# TMP=$(mktemp) 
   grep-aptavail -n -S samba --and -s Package > "$TMP"
   xargs -a $TMP apt install
   rm "$TMP"
3) list all files in binary package (not necessarily installed) generated by source package (it queries local apt cache for "samba" source package in the example, slow):

Code: Select all

$ grep-aptavail -n -S samba --and --not -F Section debug -s Package | 
   xargs -I DEB apt-file list DEB |
   cut -d ':' -f 2
4) list all binary files of installed binary packages generated by source package (it queries binary installed packages from "samba" source package in the example, faster):

Code: Select all

$ grep-aptavail -n -S samba --and --not -F Section debug -s Package | 
   xargs -I DEB   dpkg-query -L DEB   2> /dev/null | 
   while read -r FNAME; do [ -f $FNAME ] && [ -x $FNAME ] && echo $FNAME; done
5) search symbol “remote_password_change” in installed binary packages generated by source package (it queries binary installed packages from "samba" source package in the example):

Code: Select all

$ grep-aptavail -n -S samba --and --not -F Section debug -s Package |     
    xargs -I DEB   dpkg-query -L DEB   2> /dev/null |     
    while read -r FNAME; do [ -f $FNAME ] && [ -x $FNAME ] && nm -CAD $FNAME 2> /dev/null | grep remote_password_change ; done
Hope this might help other Debian users and forum readers.

Thanks again to @lindi and @peter_irich.

Marked as "Solved".

---
[1] https://manpages.debian.org/bookworm/dctrl-tools/grep-dctrl.1.en.html
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Debian - The universal operating system
⢿⡄⠘⠷⠚⠋⠀ https://www.debian.org
⠈⠳⣄⠀

Aki
Global Moderator
Global Moderator
Posts: 2979
Joined: 2014-07-20 18:12
Location: Europe
Has thanked: 75 times
Been thanked: 407 times

Re: [Solved] How do I find the binary package that contains a C function?

#8 Post by Aki »

Hello,

I'm following up on my previous post after receiving suggestions and observations from @fabien about a flaw in the scripts.
fabien wrote:2023-11-11 11:49
Aki wrote: 2023-11-10 15:09 1) install all binary packages generated by a source package (it queries local apt cache for "samba" source package in the example):

Code: Select all

# TMP=$(mktemp)
   grep-aptavail -n -S samba --and --not -F Section debug -s Package > "$TMP"
   xargs -a $TMP apt install
   rm "$TMP"
grep-aptavail works with regexes, so 'grep-aptavail -n -S samba' catches all sources that mach samba

Code: Select all

$> grep-aptavail -n -S "samba" -s Source -s Package
samba
ctdb

[...]

samba
winbind

sambamba
sambamba is not generated by the samba source package.
The -r switch allows arguments to be interpreted as regexes, achieving what you really wanted to

Code: Select all

$> grep-aptavail -nr -S "^samba$" -s Source -s Package
Therefore, the grep-aptavail in previous scripts can be rewritten reformulating the filter on the name of the source package (argument of the -S switch):
  • using a regex expression (as suggested by @fabien), eg:

    Code: Select all

    grep-aptavail -nr -S "^samba$" -s Source -s Package
or
  • using the -X switch for an exact literal match, es:

    Code: Select all

    grep-aptavail -n -XS "samba" -s Source -s Package
    GREP-DCTRL(1) Debian user's manual GREP-DCTRL(1)
    NAME
    grep-dctrl, grep-status, grep-available, grep-aptavail, grep-debtags - grep Debian control files
    SYNOPSIS
    command --copying|-C | --help|-h | --version|-V
    [..]
    -X, --exact-matchhttps://forums.debian.net/viewtopic.php?p=753027#p753027
    Do an exact match (as opposed to a substring match) in the current simple filter.
Here are the previous scripts modified:

1) install all binary packages generated by a source package (it queries local apt cache for "samba" source package in the example):

Code: Select all

TMP=$(mktemp)
grep-aptavail -n -XS samba --and --not -F Section debug -s Package > "$TMP"
xargs -a $TMP apt install
rm "$TMP"
2) install all both binary and dbgsym packages generated by a source package (it queries local apt cache for "samba" source package in the example):

Code: Select all

TMP=$(mktemp) 
grep-aptavail -n -XS samba -s Package > "$TMP"
xargs -a $TMP apt install
rm "$TMP"
3) list all files in binary package (not necessarily installed) generated by source package (it queries local apt cache for "samba" source package in the example, slow):

Code: Select all

$ grep-aptavail -n -XS samba --and --not -F Section debug -s Package | 
   xargs -I DEB apt-file list DEB |
   cut -d ':' -f 2
4) list all binary files of installed binary packages generated by source package (it queries binary installed packages from "samba" source package in the example, faster):

Code: Select all

$ grep-aptavail -n -XS samba --and --not -F Section debug -s Package | 
   xargs -I DEB   dpkg-query -L DEB   2> /dev/null | 
   while read -r FNAME; do [ -f $FNAME ] && [ -x $FNAME ] && echo $FNAME; done
5) search symbol “remote_password_change” in installed binary packages generated by source package (it queries binary installed packages from "samba" source package in the example):

Code: Select all

$ grep-aptavail -n -XS samba --and --not -F Section debug -s Package |     
    xargs -I DEB   dpkg-query -L DEB   2> /dev/null |     
    while read -r FNAME; do [ -f $FNAME ] && [ -x $FNAME ] && nm -CAD $FNAME 2> /dev/null | grep remote_password_change ; done
And:
fabien wrote:2023-11-11 11:49
Aki wrote: 2023-11-10 15:09 3) list all files in binary package (not necessarily installed) generated by source package (it queries local apt cache for "samba" source package in the example, slow):

Code: Select all

$ grep-aptavail -n -S samba --and --not -F Section debug -s Package | 
   xargs -I DEB apt-file list DEB |
   cut -d ':' -f 2
grep-aptavail is handy but slow. I remember I started to use it but soon discarded it for that reason in why-pkg.
However, it is apt-file that is slow here. That's because apt-file does not allow multiple arguments when used with 'list' (or its alias 'show'). If you are going to use your script often and that speed matters, have a look at my script apt-fly, the f_getaptfile function mimics apt-file but allows multiple arguments (with getconf "ARG_MAX" as a limit).
I'm going to explore the why-pkg and apt-fly by fabien.

Thanks again to @fabien .
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Debian - The universal operating system
⢿⡄⠘⠷⠚⠋⠀ https://www.debian.org
⠈⠳⣄⠀

Post Reply