未知的警告来源:“找不到虚拟表的链接器符号...”

Posted

技术标签:

【中文标题】未知的警告来源:“找不到虚拟表的链接器符号...”【英文标题】:Unknown source of warning: "can't find linker symbol for virtual table for..." 【发布时间】:2011-01-18 07:50:20 【问题描述】:

几天以来,我在调试时收到一条警告消息。我找不到它来自哪里。我已经在谷歌搜索并发现了类似的东西,因为我有一个静态变量。但是取出它并不会改变任何事情。

这是main 方法:

int main(int argc, char* argv[]) 
    if (argc != 2) 
        cout << "ERROR: Wrong amount of arguments!...\n"
             << endl;
        cout << "\n" << "Programm closed...\n\n" << endl;
    cin.ignore();
    exit(1);
    return 0;
    

    cout << "argv[1] " << argv[1] << endl;

    GenericCommandConverter a(argv[1]);
    a.getCommandsFromCSV();

    cout << "\n" << "Programm finished...\n\n" << endl;

    return 0;

第一次出现的代码:

void GenericCommandConverter::getATCommandsFromCSV() 

    cout << "+++++++++++getCommandsFromCSV) started++++++++++++++" << endl;

    string filename_csv = "test.csv";
    string commands = "";
   int pos_start = 0;
    int pos_end = 0;
    int substrLength = 0;
    int separator_count = 0;

    char c;

    vector<string> lines;
    vector<string> commandList;
    vector<unsigned int> parameterPositionList;
    vector<vector<string> > linesSeparated;
    vector<vector<string> > part1_input;
    vector<vector<string> > part2_output;
    vector<map<vector<string> , vector<string> > > listedParameterMap;

    ifstream csvFile;
    csvFile.open(filename_csv.c_str(), ios_base::in);

    cout << "i'm starting getCommandsFromCSV()...\n" << endl;

    /**
     * STEP 1
     * Putting input text file into a string
     */
    if (csvFile.is_open()) 
        while (!csvFile.eof())  // <------- warning occurs here!
                csvFile.get(c);
            commands += c;
    

...

警告:

[New Thread 2000.0x11bc]
warning: can't find linker symbol for virtual table for
`std::less<std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char, 
std::char_traits<char>,     std::allocator<char> > > > >' value

有人知道为什么会这样吗?它伴随着每一行,直到它开始。它填满了控制台,以至于无法调试。 关于独立模式的另一个可能重要的信息,此错误不会显示。

我真的很感激一些帮助!

编辑:头文件

#ifndef CommandConverter_H_
#define CommandConverter_H_

#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <iosfwd>
#include <map>
#include <vector>
#include <cstdio>

using namespace std;

class CommandConverter 
public:
    CommandConverter(char* file);
    virtual ~CommandConverter();

    void printConvertedTraceByPage(vector<string> lines);

    map<string, vector<map<vector<string> , vector<string> > > > csvMap;
    static const int MAX_SIZE = 5;

    void getATCommandsFromCSV();
    string readTxtFile();
    vector<string> splitIntoLines(const char* trace);
    vector<string> convert(vector<string> fileInLines);

    bool commandAvailable(const char* l, int pos, const char* s);
    void error(const char* p, const char* p2);
    void printCSV();

    // opened in constructor; closed in destructor
    ifstream myfile;
    string filename;
    string trace_raw;
;

#endif /* CommandConverter_H_ */

【问题讨论】:

包含、定义和完整源代码的完整列表在这种情况下以及控制台输出中确实会有所帮助。 这实际上是完整的输出,其他的东西消失了。我将添加头文件... 我什至尝试创建一个新项目并插入代码以避免项目设置中有一些有趣的东西。但它一直在做同样的事情...... 您可以尝试在谷歌上搜索gdb can't find linker symbol for virtual table for,因为 gdb 是 Eclipse 中使用的调试器 我已经在做...但到目前为止没有任何帮助... :( 【参考方案1】:

消息来自gdb/gnu-v3-abi.c中的这段代码:

static struct type *
gnuv3_rtti_type (struct value *value,
                 int *full_p, int *top_p, int *using_enc_p)

...
  /* The symbol's demangled name should be something like "vtable for
     CLASS", where CLASS is the name of the run-time type of VALUE.
     If we didn't like this approach, we could instead look in the
     type_info object itself to get the class name.  But this way
     should work just as well, and doesn't read target memory.  */
  vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol);
  if (vtable_symbol_name == NULL
      || strncmp (vtable_symbol_name, "vtable for ", 11))
    
      warning (_("can't find linker symbol for virtual table for `%s' value"),
               TYPE_NAME (values_type));
      if (vtable_symbol_name)
        warning (_("  found `%s' instead"), vtable_symbol_name);
      return NULL;
    

现在,我很确定 std::less 首先不应该有一个虚拟表,所以 GDB 很可能会感到困惑。

您需要验证最新的 GDB 是否存在问题,并提交错误。

由于这只是最近才开始,您是否升级了 GCC、GDB 或更改了编译标志?

【讨论】:

嘿,谢谢!有了 MinGW 上的更新版本,它现在可以工作了。我在有 4.5.1 之前更新到 4.5.2 我认为它不会影响它,因为 eclipse 使用它自己的调试器......不过谢谢! 我认为 Eclipse 的调试器只是解析 gdb 输出。【参考方案2】:

回答问题标题,而不是 OP 的问题(因为网络搜索将我带到这里):同一消息的另一个来源是 gdb 可能会被尚未初始化的变量混淆。

当然,您不应该有未初始化的变量,但在我的例子中,gdb 甚至在声明/初始化之前尝试显示函数局部变量。

今天我正在逐步检查另一个开发人员的 gtest 案例,每次调试器停止时,这条消息都会被转储到输出中。在这种情况下,有问题的变量是在 ~line 245 声明的,但函数是在 ~line 202 开始的。每次我在这两行之间停止调试器时,都会收到消息。

我通过将变量声明移到函数顶部解决了这个问题。

作为参考,我在 QtCreator 4.1.0 中使用 gdb 版本 7.11.1 进行测试,并使用 g++ 版本 5.4.1 进行编译

【讨论】:

以上是关于未知的警告来源:“找不到虚拟表的链接器符号...”的主要内容,如果未能解决你的问题,请参考以下文章

如何杀死“未知属性'扁平'被忽略”警告?

警告:未知的事件处理程序属性“onHeaderClick”。会被忽略

DataTables 警告:从数据源请求未知参数 '4' 用于行 ''

Vue警告:未知的自定义元素

收到内存警告的未知原因

[Vue 警告]:未知的自定义元素