找到 Visual Studio 2015 调试器在源不可用时读取符号 defs 的位置



我想看看从项目中从哪里读取函数定义,因为它既不是我期望的位置,也不是VS2015中"转到定义"声称的位置。

我有一个调用静态库的应用程序,该应用程序调用第二个静态库,所有静态库都作为 Visual Studio 中的解决方案包含在内,并且这两个库都作为应用程序的项目依赖项包含在内。当我转到从第一个库到代码中第二个库中定义的函数的任何调用并右键单击>"转到定义"时,它会将我带到第二个库中的正确位置。

但是,它在运行时绝对不会从该源获取函数,因为它返回了错误的答案,并且没有提供我为调试此问题而添加的控制台输出。我编写的另一个(玩具)应用程序用于检查代码,并且位于包含库的不同解决方案中,可以正确获取定义。

如果在调试时单击这些功能,则被告知源代码不可用。显然,它正在从某个地方阅读定义,我可以查看反汇编。在查看了所有项目的属性,并在我的计算机上搜索了第二个库的其他版本后,我仍然不知道它可能从哪里获得不同的定义。因此,了解调试器/编译器从何处读取编译的代码会很有用,它可以从中生成反汇编(并执行函数)。

我期望的位置执行的最后一行代码是:

dgstrf(opPt, column_permuted, relax, panel_size, etree, NULL, 0, col_perm_pt, row_perm_pt, lower, upper, glu, stats, status);

根据"转到定义",它应该调用一个开始的函数:

void
dgstrf (superlu_options_t *options, SuperMatrix *A,
    int relax, int panel_size, int *etree, void *work, int lwork,
    int *perm_c, int *perm_r, SuperMatrix *L, SuperMatrix *U,
    GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */
    SuperLUStat_t *stat, int *info)
{
    printf("doing dgstrfn");
 ...

过了一会儿,它叫:

*info = dLUMemInit(fact, work, lwork, m, n, Astore->nnz,
                   panel_size, fill_ratio, L, U, Glu, &iwork, &dwork);

它开始:

int
 dLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
      int panel_size, double fill_ratio, SuperMatrix *L, SuperMatrix *U,
          GlobalLU_t *Glu, int **iwork, double **dwork)
{
   printf("doing dLUMemInitn");...

依次调用 dLUWorkInit -> intCalloc,然后在真实应用程序中运行的版本中调用(但不是在工作的玩具应用程序中)->superlu_abort_and_exit -> fprintf

fprintf(在stdio.h中)是自从我的包装函数到DGSTRF以来的第一件事,调用堆栈说它有源代码。

它会在行上抛出异常"访问违规写入位置0x0000000000000024"。

__crt_va_start(_ArgList, _Format);
_Result = _vfprintf_l(_Stream, _Format, NULL, _ArgList);
__crt_va_end(_ArgList);
return _Result;

到目前为止,我已经完成了应该是源代码的内容,并用断点填充了它。它们没有被击中,我设置它产生的控制台输出都没有被击中。

对于我的具体情况,我能够通过询问同事是否可以想到任何其他可能干扰的依赖项来找出替代定义的来源。不是最令人满意的解决方案,但它会做的。

最新更新