> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/gen/dladdr.3.md).

# dladdr(3)

`dladdr` — 查找包含给定地址的共享对象

## 名称

`dladdr`

## 库

Lb libc

## 概要

`#include <dlfcn.h>`

```c
int
dladdr(const void *addr, Dl_info *info);
```

## 描述

`dladdr` 函数向动态链接器查询有关包含地址 `addr` 的共享对象的信息。信息在 `info` 所指定的结构中返回。该结构至少包含以下成员：

**`const char *dli_fname`** 包含该地址的共享对象的路径名。

**`void *dli_fbase`** 共享对象映射到调用进程地址空间的基地址。

**`const char *dli_sname`** 值小于或等于 `addr` 的最近的运行时符号的名称。在可能的情况下，符号名称以 C 源代码中出现的形式返回。如果未找到具有合适值的符号，此字段和 `dli_saddr` 都被设置为 `NULL`。

**`void *dli_saddr`** 在 `dli_sname` 中返回的符号的值。

`dladdr` 函数仅在动态链接的程序中可用。

## 错误

如果找不到包含 `addr` 的已映射共享对象，`dladdr` 返回 0。在这种情况下，可以通过调用 `dlerror` 获取详细说明失败的消息。

成功时返回非零值。

## 参见

rtld(1), [dlopen(3)](/gen/dlopen.3.md)

## 历史

`dladdr` 函数首次出现于 Solaris 操作系统。

## 缺陷

此实现与 Solaris 实现错误兼容。具体而言，存在以下缺陷：

* 如果 `addr` 位于主可执行文件中而非共享库中，`dli_fname` 中返回的路径名可能不正确。该路径名直接取自调用进程的 `argv[0]`。当通过完整路径名执行程序时，大多数 shell 将 `argv[0]` 设置为该路径名。但这并非 shell 的必须要求，操作系统也不保证如此。
* 如果 `addr` 的形式为 `&func`，其中 `func` 是全局函数，其值可能令人意外。在动态链接的程序中，全局函数的地址被认为指向其程序链接表条目，而非函数本身的入口点。这导致大多数全局函数看似定义在主可执行文件中，而非实际代码所在的共享库中。
* 返回 0 作为失败的指示违背了 Unix 的悠久传统。
