进入函数调用堆栈时,此指针设置为空 - 在 gdb 下发生 Google 测试
this pointer gets set to null when entering function call stack - happening with Google Test under gdb
(gdb) list 95, 195
95 int BishopArranger::FillAndRecurse(int cursor)
96 {
97 if (cursor == _solutionVec.size())
98 {
99 return 1;
100 }
101
102 unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
103 if (candidates.empty())
104 {
105 return 0;
106 }
107
108 int sum = 0;
109 for (unordered_set<tuple<int, int>>::iterator it = candidates.begin(); it != candidates.end(); it++) //n^2
110 {
111 _solutionVec[cursor] = *it;
112 sum += FillAndRecurse(cursor+1); //k recursions, each being kn
113 }
114 //kn^3
115 return sum;
116 }
117
118 void ConstructBoard(int k, int n)
119 {
120 BOARD = unordered_set<tuple<int, int>>();
121 for (int i=0; i<n; i++)
122 {
123 for (int j=0; j<n; j++)
124 {
125 BOARD.insert(tuple<int, int>(i, j));
126 }
127 }
128 }
129
130 int BishopArranger::Solution(int k, int n)
131 {
132 if (n == 0)
133 {
134 return 0;
135 }
136
137 ConstructBoard(k, n);
138 _solutionVec = vector<tuple<int, int>>(k);
139 return FillAndRecurse(0);
140 }
(gdb) next
102 unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
(gdb) print this
= (BishopArranger * const) 0x22a5f0
(gdb) step
Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
at ./src/bishop_arranger/BishopArranger.cc:84
84 {
我写了一些代码并 运行 对其进行了一些 (Google) 测试,结果发现它失败了:程序完成并给出了错误的输出。所以我很自然地启动了 gdb 并尝试调试我的测试。
有趣的是,就在我进入 GetCandidates(int cursor) 函数之前,在第 102 行,'this' 指针是好的:
(gdb) print this
= (BishopArranger * const) 0x22a5f0
然后我在函数中做了一个 'step' ,它立即给了我一个异常抱怨 'this' was null(this=0x0):
(gdb) step
Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
at ./src/bishop_arranger/BishopArranger.cc:84
84 {
这有多荒谬? 我确信这只发生在我调试用 [=45= 编写的测试用例时] 测试,不是当我运行他们:
[ RUN ] Solution.TinyBoardTinyK
./test/bishop_arranger/UnitTests.cc:14: Failure
Value of: bishopArranger.Solution(2, 2)
Actual: 12
Expected: 4
[ FAILED ] Solution.TinyBoardTinyK (0 ms)
如您所见,当我 运行 测试 Google 时,产生了错误的输出 12。程序虽然断言没有通过,但无一例外地结束了。
您可能感兴趣的一些信息:
1,我的程序中只有一个线程,尽管 Google 测试利用 pthreads 来并行执行测试,根据他们的文档(它说没有 gua运行tee 某些测试在其他人之前完成)。
不确定这是否与我的情况相关,因为我的每个测试都有自己的对象并且没有共同的 setup/teardown 部分,因此一个测试中的对象不太可能被另一个测试破坏。它们看起来像:
TEST(Solution, BoundaryCondition)
{
BishopArranger bishopArranger;
EXPECT_EQ(0, bishopArranger.Solution(0, 0));
}
TEST(Solution, TinyBoardTinyK)
{
BishopArranger bishopArranger;
EXPECT_EQ(4, bishopArranger.Solution(2, 2));
}
TEST(Solution, SmallBoardSmallK)
{
BishopArranger bishopArranger;
EXPECT_EQ(260, bishopArranger.Solution(4, 4));
}
2、平台:CYGWIN_NT-6.1; g++ 用于编译 Google 测试和此程序:4.8.3(是的,我遵循 Google 测试的文档并使用与我的 c++ 程序相同版本的编译器从源代码编译以避免潜在问题) ; gdb 版本:7.8
在此先感谢您的投入!
我相信这是一个隐藏在 cygwin 某处的错误,因为我后来用真正的 Linux 系统尝试了同样的事情,并且它按预期工作得很好。我得到的教训:如果你想做认真的开发,请远离Cygwin。
BishopArranger::GetCandidates (this=0x0, ...)
在尚未构造的静态C++对象中也会发生这种情况。但不清楚您是否遇到该问题。
对于那一团糟,请参阅 "static initialization order fiasco"。在 GCC 下,使用 init_priority
来构造它们。在 Windows 下,使用 init_seg
创建它们。
(gdb) list 95, 195
95 int BishopArranger::FillAndRecurse(int cursor)
96 {
97 if (cursor == _solutionVec.size())
98 {
99 return 1;
100 }
101
102 unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
103 if (candidates.empty())
104 {
105 return 0;
106 }
107
108 int sum = 0;
109 for (unordered_set<tuple<int, int>>::iterator it = candidates.begin(); it != candidates.end(); it++) //n^2
110 {
111 _solutionVec[cursor] = *it;
112 sum += FillAndRecurse(cursor+1); //k recursions, each being kn
113 }
114 //kn^3
115 return sum;
116 }
117
118 void ConstructBoard(int k, int n)
119 {
120 BOARD = unordered_set<tuple<int, int>>();
121 for (int i=0; i<n; i++)
122 {
123 for (int j=0; j<n; j++)
124 {
125 BOARD.insert(tuple<int, int>(i, j));
126 }
127 }
128 }
129
130 int BishopArranger::Solution(int k, int n)
131 {
132 if (n == 0)
133 {
134 return 0;
135 }
136
137 ConstructBoard(k, n);
138 _solutionVec = vector<tuple<int, int>>(k);
139 return FillAndRecurse(0);
140 }
(gdb) next
102 unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
(gdb) print this
= (BishopArranger * const) 0x22a5f0
(gdb) step
Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
at ./src/bishop_arranger/BishopArranger.cc:84
84 {
我写了一些代码并 运行 对其进行了一些 (Google) 测试,结果发现它失败了:程序完成并给出了错误的输出。所以我很自然地启动了 gdb 并尝试调试我的测试。
有趣的是,就在我进入 GetCandidates(int cursor) 函数之前,在第 102 行,'this' 指针是好的:
(gdb) print this
= (BishopArranger * const) 0x22a5f0
然后我在函数中做了一个 'step' ,它立即给了我一个异常抱怨 'this' was null(this=0x0):
(gdb) step
Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
at ./src/bishop_arranger/BishopArranger.cc:84
84 {
这有多荒谬? 我确信这只发生在我调试用 [=45= 编写的测试用例时] 测试,不是当我运行他们:
[ RUN ] Solution.TinyBoardTinyK
./test/bishop_arranger/UnitTests.cc:14: Failure
Value of: bishopArranger.Solution(2, 2)
Actual: 12
Expected: 4
[ FAILED ] Solution.TinyBoardTinyK (0 ms)
如您所见,当我 运行 测试 Google 时,产生了错误的输出 12。程序虽然断言没有通过,但无一例外地结束了。
您可能感兴趣的一些信息:
1,我的程序中只有一个线程,尽管 Google 测试利用 pthreads 来并行执行测试,根据他们的文档(它说没有 gua运行tee 某些测试在其他人之前完成)。
不确定这是否与我的情况相关,因为我的每个测试都有自己的对象并且没有共同的 setup/teardown 部分,因此一个测试中的对象不太可能被另一个测试破坏。它们看起来像:
TEST(Solution, BoundaryCondition)
{
BishopArranger bishopArranger;
EXPECT_EQ(0, bishopArranger.Solution(0, 0));
}
TEST(Solution, TinyBoardTinyK)
{
BishopArranger bishopArranger;
EXPECT_EQ(4, bishopArranger.Solution(2, 2));
}
TEST(Solution, SmallBoardSmallK)
{
BishopArranger bishopArranger;
EXPECT_EQ(260, bishopArranger.Solution(4, 4));
}
2、平台:CYGWIN_NT-6.1; g++ 用于编译 Google 测试和此程序:4.8.3(是的,我遵循 Google 测试的文档并使用与我的 c++ 程序相同版本的编译器从源代码编译以避免潜在问题) ; gdb 版本:7.8
在此先感谢您的投入!
我相信这是一个隐藏在 cygwin 某处的错误,因为我后来用真正的 Linux 系统尝试了同样的事情,并且它按预期工作得很好。我得到的教训:如果你想做认真的开发,请远离Cygwin。
BishopArranger::GetCandidates (this=0x0, ...)
在尚未构造的静态C++对象中也会发生这种情况。但不清楚您是否遇到该问题。
对于那一团糟,请参阅 "static initialization order fiasco"。在 GCC 下,使用 init_priority
来构造它们。在 Windows 下,使用 init_seg
创建它们。