gpt4 book ai didi

future.get 上的 C++ bad_alloc 异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:51 25 4
gpt4 key购买 nike

我的 C++ 程序退出时出现 bad_alloc 异常。我正在尝试查找原因,但不太了解如何调试此类异常。

到目前为止,我在 Debug模式下编译程序,使用 gdb 运行它并在抛出异常之前设置断点 ( b 'std::bad_alloc::bad_alloc()' )。

抛出异常后,我检查了堆栈(bt),显示如下:

(gdb) bt
#0 0x00007ffff752f1f7 in raise () from /lib64/libc.so.6
#1 0x00007ffff75308e8 in abort () from /lib64/libc.so.6
#2 0x00007ffff7f0a7fd in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3 0x00007ffff7f08876 in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:47
#4 0x00007ffff7f088c1 in std::terminate () at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:57
#5 0x00007ffff7f0886a in std::rethrow_exception (ep=...) at ../../../../libstdc++-v3/libsupc++/eh_ptr.cc:259
#6 0x0000000000419001 in std::__basic_future<void>::_M_get_result (this=0x55b9a0)
at /soft/EB_repo/devel/programs/foss/2016b/GCCcore/5.4.0/include/c++/5.4.0/future:683
#7 0x0000000000416da6 in std::future<void>::get (this=0x55b9a0) at /soft/EB_repo/devel/programs/foss/2016b/GCCcore/5.4.0/include/c++/5.4.0/future:846
#8 0x00000000004d152f in cluster_reads (reads=..., kmer_size=14, t_s=0.10000000000000001, t_v=500, bv_threshold=0.40000000000000002,
min_bv_threshold=0.20000000000000001, bv_falloff=0.050000000000000003, min_reads_cluster=0, n_threads=8) at cluster.cpp:81
#9 0x000000000040910b in main (argc=8, argv=0x7fffffffc028) at main.cpp:106

正如您在#7 中所见,获取 std::future 时会抛出异常?这是来自 cluster_reads (#8) 的一段代码正在崩溃(我用箭头标记了第 81 行)。

    std::vector<std::vector<kmer_t>> kmers(reads.size());
std::vector<std::vector<kmer_t>> rev_kmers(reads.size());

std::vector<kmer_bv_t> bv_kmers(reads.size());
std::vector<kmer_bv_t> rev_bv_kmers(reads.size());

std::vector<std::future<void>> tasks;
for (int t = 0; t < n_threads; ++t) {
tasks.emplace_back(std::async(std::launch::async, [t, &reads, n_threads, kmer_size, &kmers, &rev_kmers, &bv_kmers, &rev_bv_kmers] {
for (int i = t; i < reads.size(); i+=n_threads) {
read_kmers_t k1 = extract_kmers_from_read(reads[i].seq, kmer_size);

kmers[i] = k1.list_forward;
rev_kmers[i] = k1.list_reverse;
bv_kmers[i] = k1.bv_forward;
rev_bv_kmers[i] = k1.bv_reverse;
}
}));
}

for (auto &&task : tasks) {
task.get(); <------------------- line 81
}

如何进一步调试这个问题?我对 gdb 很陌生。知道什么可能导致 bad_alloc 异常吗?

最佳答案

这似乎是一个 std::bad_alloc被抛入其中一个线程,后来被 task.get() 重新抛出(您错误地认为这是异常的来源)。这是来自 future::get() cppreference 的引述

Exceptions If an exception was stored in the shared state referenced by the future (e.g. via a call to std::promise::set_exception()) then that exception will be thrown.

这可能是由于分配了 std::vector<kmer_t> 而发生的在:

read_kmers_t k1 = extract_kmers_from_read(reads[i].seq, kmer_size);

及之后:

kmers[i] = k1.list_forward;

从变量的名称来看,我假设您正在阅读基因组数据库,如果您不小心,它可能会很大并且会耗尽您的内存。

要捕捉到抛出异常的确切时刻,您应该告诉 gdb:

 (gdb) catch throw

这将在抛出原始异常的地方停止执行。

关于future.get 上的 C++ bad_alloc 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54425674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com