侧边栏壁纸
博主头像
翠南山 博主等级

行动起来,活在当下

  • 累计撰写 11 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

全志平台中Avahi在使用glibc工具链时编译问题排查

居不正
2023-05-06 / 0 评论 / 0 点赞 / 26 阅读 / 0 字

前奏

最近在做项目时,碰到个问题,在编译avahi模块时出现了报错。如下图:

AVAHI编译报错

当时我就特别奇怪,之前使用muslc的时候都没啥问题,为啥现在使用glibc就有问题了。难不成,之前编译的dbus就有这个函数定义,使用glibc之后就没有了?为了搞清楚这个问题,我决定使用谷歌!!!然而,悲伤的事是:

google-avahi-link-error

没有想象的美好,so,只能靠自己了。(面向谷歌编程的我好难过。)

分析问题

是啥子问题

既然要解决问题,首先我们要搞清楚问题是什么。从图中可以很清晰的看到,是编译器在链接文件时无法查找到dbus_connection_disconnect。既然是链接问题,很显然主要从两个方面入手:

  1. 检查编译时是否有指定dbus库的位置;
  2. 如果指定了,那么dbus中是否包含该函数;

找到dbus

既然是查找文件,在linux中我们当然是使用find咯,结果如下:

Find-dbus

再对比一下第一张图中的编译命令,发现其中-L中包含了dbus的目录,而-l则包含了dbus-1,由此可见,编译命令没有问题。

检查dbus库函数

既然编译命令没有问题没有问题,那么需要检查下libdbus中是否包含该函数,如果包含结果显示有,那么很可能我们的dbus库存在问题,如果不包含,则需要检查源码中为什么会使用该函数。其结果如下:

Check-DBUS

从上图看到,很显然,libdbus中不包含这个函数。因此,我们的思路就需要转变到avahi中是否自己定义了该函数,但是链接的时候文件没有被定义到。

检查avahi中关于该函数的源码

为了明确找到avahi中是否定义了该函数,我们使用了grep进行查找,结果如下:

Avahi-check-func-declare

从图中我们可以看到,并没有dbus_connection_disconnect的函数定义,所有的函数都是调用。为此,我们随便打开一个文件检查下代码调用的内容,如下图:

Avahi-check-func-call

打开文件,查找该函数后发现,我去,好家伙,居然有个宏定义。如果是存在HAVE_DBUS_CONNECTION_CLOSE则使用dbus_connection_close,否则就使用dbus_connection_disconnect

那么时候该咋办?很简单,check一下dbus库中是否包含dbus_connection_close函数,如果包含的话,就是宏定义存在问题。那么我们的方向就会转变为为什么宏定义存在问题。

检查dbus中是否包含dbus_connection_close

老方法,nmgrep

DBUS-check-close

好家伙,这下石锤了,宏定义出了问题。方向明确,找宏定义出问题的原因。

HAVE_DBUS_CONNECTION_CLOSE为啥没有定义?

既然要找为啥该宏出问题,那么得先找到在哪里定义了该宏。从编译的角度来说,有两种方式可以传递宏定义:

  1. 使用gcc等编译器时使用-D赋值;
  2. 另外一种时在文件中定义。

由于是该宏定义没有定义,第一种的命令行肯定不包含该定义。所以,我们转向查找文件中(makefile或者源文件)查找。这时候,grep大法再次出击:

CHECK-MACRO

检查了一遍,的确没有很明确的#define HAVE_DBUS_CONNECTION_CLOSE XXX的内容,说明代码中的确没有定义该宏。再仔细检查发现,该宏是包含是包含在autom4te.cache中的。至于这个文件夹的含义,我也不是特别清楚。但是,这个线索告诉我们,这个宏是通过configure命令生成的。于是,我又重新clean并编译了该包,并输出了编译日志以方便我查看configure生成内容。(命令是make package/libs/avahi/clean;make package/libs/avahi/install,当然也可以进入到该pacakge目录然后执行mm -B)。其结果如下:

CHECK-CONFIGURE-OUTPUT

从内容中看到,dbus_connection_close的确没有被检查到。那么,这里一定是存在一些问题的。这时候,我的想法是搞清楚,autoconf查找函数的原理。为此,我做了以下事情:

  1. 谷歌autoconf如何检查函数的原理;
  2. 根据日志输出上下文查找代码;

其中,由于第二步后来发现是无用功,我在这里就不赘述,我们主要看第一个结果。其实,我在谷歌的时候并没有找到实际答案,但是找到了一个很关键的信息:configure的输出都会被存储在config.log中。于是,下一步就是自然而然的检查config.log文件。

检查config.log文件

多的就不说了,关键信息如下:

AVAHI-CONFIG-LOG

从上图可以看到,居然是使用编译器链接来检查该函数是否存在,而由于pthread库没有指定而导致宏定义失败。

解决问题

好了,通过上面的步骤,问题基本找到了。接下来就是解决问题了,由于我之前做产品时就是在全志平台,因此积累过一定经验,我的最后修改如下(至于为什么这么修改,不在这个博文的主题中,如果有兴趣,我可以单独再写博文讨论):

AVAHI-ERROR-SOLUTION

重新编译,成功!

后记

实际上,类似的问题在工作中其实经常碰到,我之所以写这个博文有两个原因:

  1. 之前不爱记录,我想改变一下,也分享给需要的人;
  2. 工作中难免碰到问题,想提供一些思路给大家。

这次博文呢,算是我想对我相对完整的记录,希望大家指教。

历史

VersionDateDescription
0.12020-10-11第一次记录
0

评论区