TraceStack的构造和析构不平衡,导致TS_Len异常,从而出现野指针非法修改堆地址。

TS_Len不平衡变成了-1,_TS位于0x2000023c,赋值就变成了向0x20000238赋值,而g_Heap是0x20000228,238正是它的_First字段。故导致_First字段被错误修改。
This commit is contained in:
大石头 2017-03-14 15:56:24 +08:00
parent 8cf4912a49
commit 63b75a307c
3 changed files with 36 additions and 42 deletions

View File

@ -7,7 +7,7 @@
#define MEMORY_ALIGN 4 #define MEMORY_ALIGN 4
// 当前堆 // 当前堆
Heap* Heap::Current = nullptr; const Heap* Heap::Current = nullptr;
/* /*
@ -75,6 +75,7 @@ void* Heap::Alloc(int size)
#if DEBUG #if DEBUG
// 检查头部完整性 // 检查头部完整性
auto head = (MemoryBlock*)Address; auto head = (MemoryBlock*)Address;
//assert(_First >= head && head->Used <= Size && (byte*)head + head->Used <= (byte*)head->Next, "堆头被破坏!");
assert(head->Used <= Size && (byte*)head + head->Used <= (byte*)head->Next, "堆头被破坏!"); assert(head->Used <= Size && (byte*)head + head->Used <= (byte*)head->Next, "堆头被破坏!");
assert(_Used <= Size, "Heap::Used异常"); assert(_Used <= Size, "Heap::Used异常");
#endif #endif

View File

@ -18,7 +18,7 @@ public:
void Free(void* ptr); void Free(void* ptr);
// 当前堆 // 当前堆
static Heap* Current; static const Heap* Current;
private: private:
int _Used; int _Used;

View File

@ -9,42 +9,42 @@ TInterrupt Interrupt;
void TInterrupt::Init() const void TInterrupt::Init() const
{ {
OnInit(); OnInit();
} }
bool TInterrupt::Activate(short irq, InterruptCallback isr, void* param) bool TInterrupt::Activate(short irq, InterruptCallback isr, void* param)
{ {
short irq2 = irq + 16; // exception = irq + 16 short irq2 = irq + 16; // exception = irq + 16
Vectors[irq2] = isr; Vectors[irq2] = isr;
VectorParams[irq2] = param; VectorParams[irq2] = param;
return OnActivate(irq); return OnActivate(irq);
} }
bool TInterrupt::Deactivate(short irq) bool TInterrupt::Deactivate(short irq)
{ {
short irq2 = irq + 16; // exception = irq + 16 short irq2 = irq + 16; // exception = irq + 16
Vectors[irq2] = 0; Vectors[irq2] = 0;
VectorParams[irq2] = 0; VectorParams[irq2] = 0;
return OnDeactivate(irq); return OnDeactivate(irq);
} }
// 关键性代码,放到开头 // 关键性代码,放到开头
INROOT void TInterrupt::Process(uint num) const INROOT void TInterrupt::Process(uint num) const
{ {
//auto& inter = Interrupt; //auto& inter = Interrupt;
if(!Vectors[num]) return; if (!Vectors[num]) return;
// 内存检查 // 内存检查
#if DEBUG #if DEBUG
Sys.CheckMemory(); Sys.CheckMemory();
#endif #endif
// 找到应用层中断委托并调用 // 找到应用层中断委托并调用
auto isr = (InterruptCallback)Vectors[num]; auto isr = (InterruptCallback)Vectors[num];
void* param = (void*)VectorParams[num]; void* param = (void*)VectorParams[num];
isr(num - 16, param); isr(num - 16, param);
} }
// 系统挂起 // 系统挂起
@ -56,7 +56,7 @@ void TInterrupt::Halt()
//auto sp = SerialPort::GetMessagePort(); //auto sp = SerialPort::GetMessagePort();
//if(sp) sp->Flush(); //if(sp) sp->Flush();
#endif #endif
while(true); while (true);
} }
/******************************** SmartIRQ ********************************/ /******************************** SmartIRQ ********************************/
@ -65,7 +65,7 @@ void TInterrupt::Halt()
INROOT SmartIRQ::SmartIRQ(bool enable) INROOT SmartIRQ::SmartIRQ(bool enable)
{ {
_state = TInterrupt::GlobalState(); _state = TInterrupt::GlobalState();
if(enable) if (enable)
TInterrupt::GlobalEnable(); TInterrupt::GlobalEnable();
else else
TInterrupt::GlobalDisable(); TInterrupt::GlobalDisable();
@ -74,7 +74,7 @@ INROOT SmartIRQ::SmartIRQ(bool enable)
INROOT SmartIRQ::~SmartIRQ() INROOT SmartIRQ::~SmartIRQ()
{ {
//__set_PRIMASK(_state); //__set_PRIMASK(_state);
if(_state) if (_state)
TInterrupt::GlobalDisable(); TInterrupt::GlobalDisable();
else else
TInterrupt::GlobalEnable(); TInterrupt::GlobalEnable();
@ -88,12 +88,12 @@ INROOT SmartIRQ::~SmartIRQ()
Lock::Lock(int& ref) Lock::Lock(int& ref)
{ {
Success = false; Success = false;
if(ref > 0) return; if (ref > 0) return;
// 加全局锁以后再修改引用 // 加全局锁以后再修改引用
SmartIRQ irq; SmartIRQ irq;
// 再次判断DoubleLock双锁结构避免小概率冲突 // 再次判断DoubleLock双锁结构避免小概率冲突
if(ref > 0) return; if (ref > 0) return;
_ref = &ref; _ref = &ref;
ref++; ref++;
@ -102,7 +102,7 @@ Lock::Lock(int& ref)
Lock::~Lock() Lock::~Lock()
{ {
if(Success) if (Success)
{ {
SmartIRQ irq; SmartIRQ irq;
(*_ref)--; (*_ref)--;
@ -112,23 +112,23 @@ Lock::~Lock()
bool Lock::Wait(int ms) bool Lock::Wait(int ms)
{ {
// 可能已经进入成功 // 可能已经进入成功
if(Success) return true; if (Success) return true;
int& ref = *_ref; int& ref = *_ref;
// 等待超时时间 // 等待超时时间
TimeWheel tw(ms); TimeWheel tw(ms);
tw.Sleep = 1; tw.Sleep = 1;
while(ref > 0) while (ref > 0)
{ {
// 延迟一下释放CPU使用权 // 延迟一下释放CPU使用权
//Sys.Sleep(1); //Sys.Sleep(1);
if(tw.Expired()) return false; if (tw.Expired()) return false;
} }
// 加全局锁以后再修改引用 // 加全局锁以后再修改引用
SmartIRQ irq; SmartIRQ irq;
// 再次判断DoubleLock双锁结构避免小概率冲突 // 再次判断DoubleLock双锁结构避免小概率冲突
if(ref > 0) return false; if (ref > 0) return false;
ref++; ref++;
Success = true; Success = true;
@ -141,35 +141,28 @@ bool Lock::Wait(int ms)
#if DEBUG #if DEBUG
// 使用字符串指针的指针,因为引用的都是字符串常量,不需要拷贝和分配空间 // 使用字符串指针的指针,因为引用的都是字符串常量,不需要拷贝和分配空间
static cstring* _TS = nullptr; static cstring _TS[16];
static int _TS_Len = 0; static int _TS_Len = 0;
TraceStack::TraceStack(cstring name) TraceStack::TraceStack(cstring name)
{ {
// 字符串指针的数组 if (_TS_Len < 16) _TS[_TS_Len++] = name;
static cstring __ts[16];
_TS = __ts;
//_TS->Push(name);
if(_TS_Len < 16) _TS[_TS_Len++] = name;
} }
TraceStack::~TraceStack() TraceStack::~TraceStack()
{ {
// 清空最后一个项目,避免误判 if (_TS_Len > 0)
//if(_TS_Len > 0) _TS[--_TS_Len] = ""; _TS_Len--;
_TS_Len--; else
debug_printf("_TS_Len \r\n");
} }
void TraceStack::Show() void TraceStack::Show()
{ {
debug_printf("TraceStack::Show:\r\n"); debug_printf("TraceStack::Show:\r\n");
if(_TS) for (int i = _TS_Len - 1; i >= 0; i--)
{ {
for(int i=_TS_Len - 1; i>=0; i--) debug_printf("\t<=%s \r\n", _TS[i]);
{
debug_printf("\t<=%s \r\n", _TS[i]);
}
} }
} }