通过指向错误函数类型的指针调用函数(未知)

2023-12-27

我有一个动态链接到库的程序。 该程序将函数指针传递给该库以执行。

但 ubsan(未定义行为清理程序)指定该指针位于不正确的函数类型上。而这种情况只会发生

  • 如果回调函数有一个类作为参数
  • 如果回调函数有一个类作为参数,但仅向前声明
  • 如果我指定编译标志:-fvisibility=hidden。

我使用 clang 来编译我的项目。

这是 clang 未定义行为清理程序中的错误吗?

以下代码简化为一个简单的测试用例。检查评论,看看我们可以在哪里采取行动来删除一些警告

应用程序的代码:

Main.cxx

#include "Caller.h"
#include "Param.h"

static void FctVoid()
{
}
static void FctInt(int _param)
{
   static_cast<void>(&_param);
}
static void FctCaller(Caller &_caller)
{
   static_cast<void>(&_caller);
}
static void FctParam(Param const &_param)
{
   static_cast<void>(&_param);
}

int main()
{
   Param param;
   Caller::CallVoid(&FctVoid);
   Caller::CallInt(&FctInt);
   Caller::CallThis(&FctCaller);
   Caller::CallParam(&FctParam, param);
   return 0;
}

库文件的代码是:

来电者.cxx:

#include "Caller.h"
// To uncomment to fix one warning
//#include "Param.h"
void Caller::CallVoid(FctVoidT _fct)
{
   _fct();
}
void Caller::CallInt(FctIntT _fct)
{
   _fct(32);
}
void Caller::CallThis(FctThisT _fct)
{
   Caller caller;
   _fct(caller);
}
void Caller::CallParam(FctParamT const &_fct, Param const &_param)
{
   _fct(_param);
}

Caller.h

#ifndef __Caller_h_
#define __Caller_h_
#include "owExport.h"

class Param;
class EXPORT_Library Caller
{
public:
   typedef void(*FctVoidT)();
   static void CallVoid(FctVoidT _fct);
   typedef void(*FctIntT)(int);
   static void CallInt(FctIntT _fct);
   typedef void(*FctThisT)(Caller &);
   static void CallThis(FctThisT _fct);
   typedef void(*FctParamT)(Param const &);
   static void CallParam(FctParamT const &_fct, Param const &_param);
};
#endif

Param.h

#ifndef __Param_h_
#define __Param_h_
#include "owExport.h"
class EXPORT_Library Param
{
public:
};
#endif

owExport.h

#ifndef __owExport_h_
#define __owExport_h_
#define OW_EXPORT __attribute__ ((visibility("default")))
#define OW_IMPORT
// Use this one to fix one warning
#define OW_IMPORT __attribute__ ((visibility("default")))
#ifdef Library_EXPORTS
#  define EXPORT_Library OW_EXPORT
#else
#  define EXPORT_Library OW_IMPORT
#endif
#endif

配置项目的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.0.0)
project(TestFunction)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fsanitize=undefined ")

# Act here to for the call of function through pointer to incorrect function type
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")

add_library(Library Caller.cxx Param.cxx)
add_executable(TestWithLib Main.cxx)
target_link_libraries(TestWithLib Library)

第一:如果您编辑问题以添加修复程序,那就不好了。这让人很难回答。

对于您的问题:您基本上有两个问题:首先是符号Caller, second withParam`,两者基本相同。

对于问题的根源:UBSAN 将指针的类型信息与预期的类型信息进行比较。如果类型信息不同,则会显示错误。typeinfo比较是通过指针比较来完成的。这对于速度来说非常有用,但引入了一个微妙的问题:即使实际类型实际上相同,它们也可能不会共享相同的内容typeinfo。当您从共享库中抛出类型并希望在可执行文件中捕获它时(反之亦然),这一点也很重要:捕获是通过类型信息比较来完成的,并且如果两种类型不完全相同(共享相同的类型信息)你不会抓住它的。

所以你的第一个问题是class EXPORT_Library Caller: 你有条件地定义EXPORT_Library要么被“导出”,要么不被“导出”。如果它是从多个 DSO 导出的,则类型信息将被合并。在您的情况下,您将其导出到共享库中,而不是导出到可执行文件中,这会阻止合并它们。您可以使用BOOST_SYMBOL_EXPORT or OW_EXPORT为了这。

第二个问题是相反的(假设EXPORT_Library==OW_EXPORT): Param当包含 Param.h 标头时导出,这仅由可执行文件完成,而不是由共享库完成。同样,类型信息未合并 -> RTTI 系统的不同类型。

底线:导出您想要在 DSO 边界上使用的所有类。

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

通过指向错误函数类型的指针调用函数(未知) 的相关文章

  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 以编程方式检查页面是否需要基于 web.config 设置进行身份验证

    我想知道是否有一种方法可以检查页面是否需要基于 web config 设置进行身份验证 基本上如果有这样的节点
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 显示异常时的自定义错误消息:从客户端检测到潜在危险的 Request.Form 值

    我在我的 Web 应用程序中使用 ASP NET 的登录控件 当发生此异常时 我想在标签上显示一种有趣的错误类型System Web HttpRequestValidationException A potentially dangerou
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 在非活动联合成员上使用“std::addressof”是否定义明确[重复]

    这个问题在这里已经有答案了 下面的代码是尝试实现constexpr的版本offsetof在 C 11 中 它可以在 gcc 7 2 0 和 clang 5 0 0 中编译 这取决于申请std addressof工会非活跃成员的成员 这是明确
  • 当“int”处于最大值并使用 postfix ++ 进行测试时,代码定义良好吗?

    示例 未定义行为的一个示例是整数溢出的行为 C11dr 3 4 3 3 int溢出是未定义的行为 但这是否适用于存在循环的以下内容 并且不使用现在超出范围的副作用i 特别是 这是否后缀增量规格帮助 结果的值计算在副作用之前排序 更新操作数的
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐

  • 为什么 Python 的 mmap 不能处理大文件?

    编辑 此问题仅适用于 32 位系统 如果您的计算机 操作系统和 python 实现都是 64 位的 那么 mmap ing 大文件可以可靠地工作并且非常高效 我正在编写一个模块 除其他外 它允许对文件进行按位读取访问 这些文件可能很大 数百
  • 在 onClick 中传递单个值(不使用表单提交)

    理想情况下 我不想创建多个 putPriority 获取 而是希望传递一个奇异值 但该值不会通过用户输入 即不是输入字段 我想通过 onClick 传递这个值 在我的示例中 我希望 onClick 将单个数字传递给获取中的 status t
  • 'git diff':仅显示两个提交中存在的文件的差异

    有没有办法使用git diff获取两次提交之间的差异 但只显示两次提交中存在的文件的差异 我几周前创建了一个分支 现在我们的主要代码已经与它有很大的分歧 因此 如果我在当前的 HEAD 和旧分支的尖端之间进行比较 我会得到数十个已更改的文件
  • Cocoapods - Flurry 和 TestFlight - 未定义的架构符号

    我正在升级我的项目以使用 Cocoapods 当我尝试为 iOS 设备或模拟器构建我的项目时 我得到 Undefined symbols for architecture armv7 OBJC CLASS TestFlight refere
  • Hangfire 重试后发送电子邮件

    我们有几个作业设置为 10 次重试 由于性质或外部服务 有时在第一次或第二次过程中会失败 我们会收到失败电子邮件 但第三次或第四次工作就会成功 现在我想以协调的方式向早期的失败电子邮件发送电子邮件 因此 如果我们连续收到成功的电子邮件 我们
  • 自动调整 li 的宽度以适应文本?

    是否有可能使用 CSS 自动调整 标签的宽度以适应其包含的文本的宽度 我正在设计一个使用自定义 CMS 的网站 并且我无权访问代码 因此就设计而言 我的选择有限 无需直接编辑任何列表属性即可在 标记上工作的 Javascript 解决方案也
  • 重力形式添加显示无

    我正在我的 WordPress 主题中创建一个自定义模板 因为我的模板的布局与我的活动主题完全不同 该模板有自己的页眉和页脚 并且在两者的内部我都已正确声明wp head and wp footer 分别 在我的模板代码中 我尝试使用 do
  • setuptools:数据文件包含在“bdist”中,但不包含在“sdist”中

    我有一个setup py文件看起来像这样 usr bin env python from setuptools import setup find packages setup name foo version 1 0 packages f
  • SSL 读取和 SSL 写入同时进行

    我有两个线程 mainThread and recvThread On recvThread 我打电话SSL read ssl readBuffer sizeof readBuffer 这会阻塞线程 直到收到数据 然后 于mainThrea
  • 为什么 Yocto rootfs 中包含软件包?

    我正在从 Yocto Sumo 升级到 Yocto Dunfell 在此过程中 有相当多的软件包被添加到 rootfs 中 这些软件包以前不存在 而且我也没有使用过 我想知道为什么要添加它们 哪个依赖项会触发它们被添加 在 Yocto 的早
  • 从父子 JSON 数据中获取所有子级

    我有父子 JSON 数据 我想从选定的父级获取所有子级 嵌套子级 例如 我有 JSON 数据 id 1 parent 0 name Parent id 2 parent 1 name Child 1 id 3 parent 2 name G
  • 强制 JVM 使用某些 Cipher 进行 https 连接

    我有 Java 客户端 它使用 https 连接到某些 Web 服务 客户端的要求之一是 我们应该能够从支持的密码套件列表中进行选择 然后强制客户端使用它们 从以下page https docs oracle com javase 7 do
  • Libwebsocket 客户端示例

    我试图找到一个示例来解释如何使用 libwebsocket 实现客户端 但我没有得到任何令人信服的代码 有什么链接可以参考吗 更正了代码示例罗仁伟跟 共事libwebsockets 1 6 在 Ubuntu 14 04 上测试 示例服务器
  • SCNText - 背景“语音气泡”

    如何将背景 例如 语音气泡 或矩形 插入到 SCNtext 中 具体来说 如果我插入 Hello World 作为 SCNText 显然作为场景中的 SCNNode 那么如何仅为该文本添加背景 它会是一个 UIimage 它将作为 SCNN
  • 强制转换中的中间指针必须是“const 限定的” - 为什么?

    在下面的代码中 include
  • 从 OpenCV 文件中读取算法参数

    我正在尝试从 XML 文件中读取经过训练的期望最大化模型的参数以供以后使用 为了存储我调用的模型 cv FileStorage fs model xml cv FileStorage WRITE classifier write fs cl
  • 有没有办法滚动到锚点而不是用javascript跳转(比如平滑滚动)

    我有一个带有编号锚标记的大文档 如下所示 还有一个文本框 用于输入数字以转到使用的锚点window location hash 我还使用箭头键转到下一个或上一个锚点 我想滚动到锚点以便给出一些方向感 a some text a some t
  • 使用nodejs + Express处理服务器端和客户端错误的最佳方法是什么

    我想知道处理响应请求中的错误的最佳方法 我有这条接收请求的路线 app get getInfo function req res next let obj try obj date lastUpdatedDate utils appVers
  • 如何获取动态查询结果的行数?

    我创建了一个动态查询 一切运行良好 我使用以下命令执行查询 EXEC sp executesql SQLQuery 其中 SQLQuery 是一种动态查询 我唯一的问题是如何返回执行此查询后存在的行数 我希望我的问题很清楚 提前致谢 您可以
  • 通过指向错误函数类型的指针调用函数(未知)

    我有一个动态链接到库的程序 该程序将函数指针传递给该库以执行 但 ubsan 未定义行为清理程序 指定该指针位于不正确的函数类型上 而这种情况只会发生 如果回调函数有一个类作为参数 如果回调函数有一个类作为参数 但仅向前声明 如果我指定编译