glGetFloatv导致堆栈粉碎
glGetFloatv causes stack smash
本文关键字:堆栈 glGetFloatv 更新时间:2023-10-16
使用GCC编译时,这会导致堆栈崩溃。
void MyOpenGLLineClass::set_width (float x)
{
float max = 1;
glGetFloatv (GL_ALIASED_LINE_WIDTH_RANGE, &max);
if (false == (x > 0 && x <= max))
throw std::invalid_argument (__PRETTY_FUNCTION__);
m_width = x;
}
它发生在一个程序中,而该程序在其他方面的行为与预期的一样。如果我评论掉glGetFloatv
,堆栈粉碎就会消失。
这是机器代码:
0x00005555556503be <+0>: push %rbp
0x00005555556503bf <+1>: mov %rsp,%rbp
0x00005555556503c2 <+4>: push %r12
0x00005555556503c4 <+6>: push %rbx
0x00005555556503c5 <+7>: sub $0x20,%rsp
0x00005555556503c9 <+11>: callq *0x2e2bf9(%rip) # 0x555555932fc8
0x00005555556503cf <+17>: mov %rdi,-0x28(%rbp)
0x00005555556503d3 <+21>: movss %xmm0,-0x2c(%rbp)
0x00005555556503d8 <+26>: mov %fs:0x28,%rax
0x00005555556503e1 <+35>: mov %rax,-0x18(%rbp)
0x00005555556503e5 <+39>: xor %eax,%eax
0x00005555556503e7 <+41>: pxor %xmm0,%xmm0
0x00005555556503eb <+45>: movss %xmm0,-0x1c(%rbp)
0x00005555556503f0 <+50>: lea -0x1c(%rbp),%rax
0x00005555556503f4 <+54>: mov %rax,%rsi
0x00005555556503f7 <+57>: mov $0x846e,%edi
0x00005555556503fc <+62>: callq 0x5555556262d0 <glGetFloatv@plt>
0x0000555555650401 <+67>: movss -0x2c(%rbp),%xmm0
0x0000555555650406 <+72>: pxor %xmm1,%xmm1
0x000055555565040a <+76>: comiss %xmm1,%xmm0
0x000055555565040d <+79>: seta %al
0x0000555555650410 <+82>: xor $0x1,%eax
0x0000555555650413 <+85>: test %al,%al
0x0000555555650415 <+87>: jne 0x55555565042a <MyOpenGLLineClass::set_width(float)+108>
0x0000555555650417 <+89>: movss -0x1c(%rbp),%xmm0
0x000055555565041c <+94>: comiss -0x2c(%rbp),%xmm0
0x0000555555650420 <+98>: setae %al
0x0000555555650423 <+101>: xor $0x1,%eax
0x0000555555650426 <+104>: test %al,%al
0x0000555555650428 <+106>: je 0x55555565045f <MyOpenGLLineClass::set_width(float)+161>
0x000055555565042a <+108>: mov $0x10,%edi
0x000055555565042f <+113>: callq 0x555555626130 <__cxa_allocate_exception@plt>
0x0000555555650434 <+118>: mov %rax,%rbx
0x0000555555650437 <+121>: lea 0x8ee42(%rip),%rsi # 0x5555556df280 <_ZZN3CMyOpenGLLineClass9set_widthEfE19__PRETTY_FUNCTION__>
0x000055555565043e <+128>: mov %rbx,%rdi
0x0000555555650441 <+131>: callq 0x555555625f80 <_ZNSt16invalid_argumentC1EPKc@plt>
0x0000555555650446 <+136>: mov 0x2e2b5b(%rip),%rax # 0x555555932fa8
0x000055555565044d <+143>: mov %rax,%rdx
0x0000555555650450 <+146>: lea 0x2de9f1(%rip),%rsi # 0x55555592ee48 <_ZTISt16invalid_argument@@GLIBCXX_3.4>
0x0000555555650457 <+153>: mov %rbx,%rdi
0x000055555565045a <+156>: callq 0x555555625a80 <__cxa_throw@plt>
0x000055555565045f <+161>: mov -0x28(%rbp),%rax
0x0000555555650463 <+165>: movss -0x2c(%rbp),%xmm0
0x0000555555650468 <+170>: movss %xmm0,0x58(%rax)
0x000055555565046d <+175>: nop
0x000055555565046e <+176>: mov -0x18(%rbp),%rax
0x0000555555650472 <+180>: xor %fs:0x28,%rax
0x000055555565047b <+189>: je 0x55555565049a <MyOpenGLLineClass::set_width(float)+220>
0x000055555565047d <+191>: jmp 0x555555650495 <MyOpenGLLineClass::set_width(float)+215>
0x000055555565047f <+193>: mov %rax,%r12
0x0000555555650482 <+196>: mov %rbx,%rdi
0x0000555555650485 <+199>: callq 0x5555556263c0 <__cxa_free_exception@plt>
0x000055555565048a <+204>: mov %r12,%rax
0x000055555565048d <+207>: mov %rax,%rdi
0x0000555555650490 <+210>: callq 0x555555625b00 <_Unwind_Resume@plt>
0x0000555555650495 <+215>: callq 0x5555556258a0 <__stack_chk_fail@plt>
=> 0x000055555565049a <+220>: add $0x20,%rsp
0x000055555565049e <+224>: pop %rbx
0x000055555565049f <+225>: pop %r12
0x00005555556504a1 <+227>: pop %rbp
0x00005555556504a2 <+228>: retq
为什么会发生这种堆砸?
根据Khronos参考,glGetFloatv
和GL_ALIASED_LINE_WIDTH_RANGE
返回两个值:
GL_ALIASED_LINE_WIDTH_RANGE
params返回两个值,即别名行支持的最小和最大宽度。
所以第二个值调用UB并破坏堆栈。
固定:
void MyOpenGLLineClass::set_width (float x)
{
float range[] = {0,0};
glGetFloatv (GL_ALIASED_LINE_WIDTH_RANGE, range);
if (false == (x >= range[0] && x <= range[1]))
throw std::invalid_argument (__PRETTY_FUNCTION__);
m_width = x;
}
相关文章:
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 堆栈和队列是否像C++中的数组一样传递?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 堆栈中大小变量输入错误 (C++)
- 堆栈问题(平衡表达式问题集)
- C++ 在堆栈中包含多态属性的类对象存储
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 在 C++ 中使用链表进行堆栈
- 变量周围的堆栈'...'已损坏
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- glGetFloatv导致堆栈粉碎