【Linux】symbol lookup error: undefined symbol + nm指令定位错误

2023-05-16

一、undefined symbol错误

今天在运行模块执行文件时,出现了如下报错 "symbol lookup error""undefined symbol",提示 cos_getfile_mcd 可执行文件在加载 .so 文件时,出现了无法找到符号的错误,并给出了具体错误:_ZN20CCosGetfileTimerInfoC2Ev 符号未定义。

那么如何定位该错误呢?一般可以先使用 ldd指令 去查看一下可执行文件的链接库,但是我的可执行文件是在加载调用.so文件的过程中出现报错,ldd指令并没有解决我的问题,因此要用的nm指令来定位错误源。那么接着请往下看看 nm指令 介绍。

二、nm指令

1、nm指令的作用

nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等),后端程序员一般需要掌握该指令。

2、nm指令的参数

nm指令的参数如下:

# 指令使用格式
nm -xx [objfile...]
# 指令中的-xx即为如下参数列表
[-a|--debug-syms]
[-g|--extern-only] //只显示外部符号.
[-B] 
[-C|--demangle[=style]] 
[-D|--dynamic] 
[-S|--print-size] 
[-s|--print-armap] 
[-A|-o|--print-file-name] 
[-n|-v|--numeric-sort] 
[-p|--no-sort] 
[-r|--reverse-sort] [--size-sort] 
[-u|--undefined-only]    //只显示未定义的符号.
[-t radix|--radix=radix] //符号值得进制。d 十进制, o 八进制, x 十六进制.
[-P|--portability] 
[--target=bfdname] 
[-fformat|--format=format] //输出的格式,有"bsd","sysv" 或"posix"可选。默认是“bsd”
[--defined-only]    //只显示已定义的符号.
[-l|--line-numbers] //对每一个符号,使用调试信息去查找文件名和行号
[--no-demangle] 
[-V|--version] 
[-X 32_64] 
[--help]  //显示帮助

3、nm指令输出

nm命令的输出包含三个部分:1)符号值,默认显示十六进制,也可以指定; 2 )符号类型,小写表示本地符号,大写表示全局符号(external),符号类型介绍如下所示;3)符号名称,符号名称前后分别会加上一段拓展名,代表不同的符号类型,例如后面的扩展名D1EV是指的C++析构函数。

输出示例如下。

  • A:符号值是绝对的。在进一步的连接中,不会被改变
  • B:符号位于未初始化数据段(BSS)
  • C:共用(common)符号. 共用符号是未初始化的数据。在连接时,多个共用符号可能采用一个同样的名字,如果这个符号在某个地方被定义,共用符号被认为是未定义的引用
  • D:已初始化数据段的符号
  • G:已初始化数据段中的小目标(small objective)符号. 一些目标文件格式允许更有效的访问小目标数据,比如一个全局的int变量相对于一个大的全局数组
  • I:其他符号的直接应用,这是GNU扩展的,很少用
  • N:调试符号
  • R:只读数据段符号
  • S:未初始化数据段中的小目标(small object)符号
  • T:代码段的符号
  • U:未定义符号
  • V:弱对象(weak object)符号. 当一个已定义的弱符号被连接到一个普通定义符号,普通定义符号可以正常使用,当一个未定义的弱对象被连接到一个未定义的符号,弱符号的值为0
  • W:一个没有被指定一个弱对象符号的弱符号(weak symbol)
  • -:a.out目标文件中的刺符号(stabs symbol). 这种情况下,打印的下一个值是其他字段,描述字段,和类型。刺符号用于保留调试信息
  • ?:未知符号类型,或者目标文件特有的符号类型

三、问题定位及解决步骤

1、使用nm指令定位未定义的符号

定位指令如下所示,可以看到结果中红框标注的符号,其类型即为未定义的 U。那么这里就可以确定代码中未定义的符号即为CCosGetfileTimerInfo。

nm -g ../../bin/cos_getfile.so | grep CCosGetfileTime

 2、使用grep命令在源码中定位符号

使用grep指令定位源码中CCosGetfileTimerInfo符号的位置,并定位到cos_getfile_mcd中的位置,之后去源码中查看相关定义使用的具体位置,并进行输出测试(在使用处前后加上测试输出,定位是否在此处出错),接着就可以确定出未定义符号的位置。

grep CCosGetfileTimerInfo *

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】symbol lookup error: undefined symbol + nm指令定位错误 的相关文章

  • 使用端口 80 (Ubuntu / Linode) 运行 Node.js 的最佳实践 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在设置我的第一个Node js服务器上的cloud Linux node我对以下细节还很陌生Linux admin 顺便说一句 我并没有尝试
  • 在C中获取终端宽度?

    我一直在寻找一种从 C 程序中获取终端宽度的方法 我不断想出的是这样的东西 include
  • 如何在 Linux 中检测通过 GUI 登录的用户

    我想在我的程序中捕获通过 GUI 登录的用户名 我的程序作为守护进程从 root 登录运行 如果非 root 用户通过 GUI 登录 我的程序应该会收到通知 我正在粘贴我当前的程序 该程序调用一个 perl 脚本 利用系统调用来检查当前登录
  • 获取后台进程的退出代码

    我有一个从我的主 bourne shell 脚本中调用的命令 CMD 该命令需要很长时间 我想修改脚本如下 作为后台进程并行运行命令 CMD CMD 在主脚本中 有一个循环每隔几秒监视生成的命令 该循环还向标准输出回显一些消息 指示脚本的进
  • Bash:更新文件中的变量

    我知道这是一个简单的答案 在找到答案之前我可能可以继续在谷歌上进行挖掘 但我的日程很紧 我希望能得到一个轻松的答复 我需要在安装时更新 ifcfg eth0 中的变量 换句话说 这就是需要发生的事情 以下变量需要更改 ONBOOT no B
  • 在 docker windows 上运行 linux 容器

    我在 Windows 10 机器上安装了 Docker for Windows 它要求我启用 HyperV 功能 一切都安装正确并且运行良好 虽然有一件事让我大吃一惊 我实际上能够在 docker windows 上运行 Linux 容器
  • 为什么我的 Linux 应用程序引入了错误的 .so 库?

    我正在构建一个使用 NetCDF C 库的应用程序 并且 NetCDF 正在引入 HDF 4 库 然而 它正在拉动wrongHDF 4 库 我的应用程序的链接方式如下 apps1 intel bin icpc gxx name apps1
  • 即使退出命令后,Shell 脚本仍继续运行

    我的shell脚本如下所示 bin bash Make sure only root can run our script EUID ne 0 echo This script must be run as root 1 gt 2 exit
  • “排序文件名 | uniq”不适用于大文件

    我可以从小文本文件中删除重复条目 但不能从大文本文件中删除重复条目 我有一个 4MB 的文件 文件的开头如下所示 aa aah aahed aahed aahing aahing aahs aahs aal aalii aalii aali
  • Linux 缓冲区溢出环境变量

    我一直在审查不同类型的缓冲区溢出 并遇到了一个我不记得为什么会发生的问题 下面的代码是我尝试执行缓冲区溢出的程序 include
  • PyGTK+3(PyGObject)创建屏幕截图?

    我过去 3 天在 google 上搜索 如何使用 PyGTK 3 创建屏幕截图 有关于 pyqt pygtk 2 wx 和 PIL 的 gallizion 教程 顺便说一句 我不需要 scrot imlib2 imagemagick 等外部
  • 从命令输出中设置 GDB 中的环境变量

    我试图在挑战中利用缓冲区溢出 缓冲区从环境变量中获取其值 在 GDB 中 我知道您可以使用以下命令设置环境变量 set environment username test 但是我需要传递用户名变量特殊字符 所以我需要执行以下操作 set e
  • 保护一个保存 MySQL 数据库的简单 Linux 服务器?

    这是一个初学者问题 但我浏览了该网站上的许多问题 但没有找到简单直接的答案 我正在设置一个运行 Ubuntu 的 Linux 服务器来存储 MySQL 数据库 该服务器尽可能安全非常重要 据我所知 我主要担心的是传入的 DoS DDoS 攻
  • 在 Ubuntu 上运行独立的 ASP.NET Core 应用程序

    我已经发布了一个 ASP NET Core 应用程序作为针对 Ubuntu 的独立应用程序 发布似乎工作正常 我已将这些文件复制到一台漂亮的 Ubuntu 机器上 现在 我如何运行我的应用程序 我的理解是 因为它是一个独立的 NET Cor
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • 更改 Amazon RDS MYSQL Linux 服务器的 innodb_log_file_size 变量值

    我们正在使用 Amazon RDS linux 服务器作为 MYSQL 更改 my cnf 文件变量值的方法是什么 我正在尝试更改 innodb log file size 变量 您能告诉我哪一个是最好的改变方式吗 所以请帮我解决这个问题
  • Linux 中如何获取内存修改通知

    在Linux的用户空间程序中 我通过从堆中分配来获取一块内存 然后将指针分发给在其他线程中运行的许多其他组件来使用 当上述内存被修改时我想收到通知 我当然可以开发一个自定义用户空间解决方案 供其他组件在尝试修改内存时使用 我的情况的问题是这
  • 在 Linux 中使用仅限 CLI 的工具生成磁盘使用情况图/图表

    在这个问题中 https stackoverflow com questions 32230 tracking down where disk space has gone on linux有人询问如何在 Linux 中显示磁盘使用情况 我
  • 如何在 Linux 上调用 Python 中的内联机器代码?

    我正在尝试从 Linux 上的纯 Python 代码调用内联机器代码 为此 我将代码嵌入到字节文字中 code b x55 x89 xe5 x5d xc3 然后打电话mprotect http www kernel org doc man
  • 使用请求和多处理时的奇怪问题

    请检查这个Python代码 usr bin env python import requests import multiprocessing from time import sleep time from requests import

随机推荐