c++调试遇到奇怪问题

206 天前
 hwdq0012
struct DV_COMMON_EXPORT product_config {


    int detect_delay_ms = 0;


    int reject_delay_ms = 0;

    int detect_count_oneshot = 1;
    int detect_count = 0;

    int detect_count_interval = 100;
    std::string ref_image_path = "1";

    int cam_x =2;
    int cam_y =3;


    // yuv420p",rgb888
    std::string rpicam_pixel_type = "yuv420p";

    int tmp =44;
};

调试时发现从第一个字符串往后,字段都没有正常初始化

(gdb) info line
Line 1021 of "/repos/dv_app_solution/prism_all/prism/include/prism/prismJson.hpp"
   starts at address 0x7fffeb60f470 <prism::json::fromJsonString<dv_common_config>(std::string const&&)+28>
   and ends at 0x7fffeb60f478 <prism::json::fromJsonString<dv_common_config>(std::string const&&)+36>.
(gdb) list
1016	
1017	template <class T>
1018	static inline std::unique_ptr<T> fromJsonString(const std::string&& str)
1019	{
1020	    std::unique_ptr<T> model = std::make_unique<T>();
1021	    privates::jsonType<T>::type::from_jsonStr(std::move(*model), std::move(str), 0, static_cast<int>(str.length() - 1));
1022	
1023	    return model;
1024	}
1025	template <class T>
(gdb) print *model
$9 = {detect_delay_ms = 0, reject_delay_ms = 0, detect_count_oneshot = 1, detect_count = 0, detect_count_interval = 100, ref_image_path = "", cam_x = 0, 
  cam_y = 0, rpicam_pixel_type = <error reading variable: Cannot create a lazy string with address 0x0, and a non-zero length.>, tmp = 796092265}
(gdb) 

程序会在后面的逻辑中,崩溃在使用 rpicam_pixel_type 这个字段的时候,用 asan 看了是由于这个错误的字符串被认为超过 10 个 T 导致崩溃 随便把它赋值给其他变量就会崩溃

没有思路,有什么方式进一进定位吗

3738 次点击
所在节点    C++
31 条回复
exch4nge
206 天前
gdb 显示的信息里 address 是 prism::json::fromJsonString<dv_common_config>
所以 dv_common_config 是什么?是 product_config 吗?
hwdq0012
206 天前
@exch4nge dv_common_config 是 product_config 的父类
有个字段 std::shared_ptr<product_config> productConfig = std::make_shared<product_config>();



@yanlx 周末再,我一般周末才用 mac ,mac 在 godbolt 的 vim 模式下 ctrl+w 不会关掉 web 标签,windows 老忘记就关掉了
hwdq0012
206 天前
@ysc3839 #6 还没执行到 from_jsonStr ,make_unique 出来就有问题了
geelaw
206 天前
@hwdq0012 #22 代码里 product_config 没有基类。

楼主的代码疑点很多,比如 const && 是无法被移走的,几乎所有代码里 const && 都是错误。

@GeruzoniAnsasu #14 std::move 并不会导致对象变化,因为只是 static_cast 到 rvalue reference 而已。
被移动过的 std::string 依然处于有效状态,调试器显示 rpicam_pixel_type 是 address 0 length positive 所以那个位置是无效状态,因此必然存在 bug ,而且并不是由正常的移动构造引起的。
cxiaobao
206 天前
template <class T>
1018 static inline std::unique_ptr<T> fromJsonString(const std::string&& str)
1019 {
1020 std::unique_ptr<T> model = std::make_unique<T>();
1021 privates::jsonType<T>::type::from_jsonStr(std::move(*model), std::move(str), 0, static_cast<int>(str.length() - 1));
1022 ~~~~~~~~~~~~~~ model 是移动语义进入 from_jsonStr 方法的,如果 from_jsonStr 取走了数据所有权,model 会被清空
1023 return model;
~~~~~~~~~ 这里不应该返回 model ,因为 model 可能已经被清空了,
通常,from_jsonStr 应该返回一个对象,这个对象取得了原本 model 中的数据,应该考虑返回这个对象
1024 }
liberize
206 天前
检查一下这个头文件是不是有 2 个不同的版本
hwdq0012
205 天前
@liberize 检查过了,全盘 find |grep 只有一个源码目录和一个安装目录,vimdiff 看了是一样的


@cxiaobao 应该不是这个问题,这里只是 make_unique 一个局部变量,还没执行到 Move 那一行


@geelaw 是的,我怀疑是链接之类的 bug ,但我已经把 Build 目录铲掉重编译了还是这样


@bfjm 局部变量 make_unique 后构建后就初始化有问题,应该和多线程没关系,和 move 也没关系
hwdq0012
205 天前
lixile
202 天前
`dv_tools 里有一个通讯用类也用元数据头文件进行 dv_common_config 的配置类 json 序列化了`
我不知道我有没有理解错 居然没有用 cmake 之类的 对这个配置文件 作为 dv_tools 的依赖项么 这样只要配置文件发生变更 就会自动增量重新编译
还是说这几个项目没有关联在一起 而是独立的 repo 且没有用一个 cmake 工程整体管理?
@hwdq0012
hwdq0012
202 天前
@lixile 有个 cmake option ,我之前设置为 off 了,
我设计的这个框架每个模块都有一个 option 控制编译,安装,部署到 app 目录,都是动态 库,app 只是一个壳
hwdq0012
202 天前
@lixile 即是独立的 cmake 模块,也是独立的 git repo

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1124436

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX