コード例 #1
0
ファイル: wxldebug.cpp プロジェクト: oeuftete/wx-xword
int wxLuaDebugData::EnumerateStackEntry(lua_State* L, int stack_frame, wxArrayInt& references)
{
    wxCHECK_MSG(L, 0, wxT("Invalid lua_State"));
    wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data"));

    lua_Debug luaDebug = INIT_LUA_DEBUG;
    int count = 0;

    if (lua_getstack(L, stack_frame, &luaDebug) != 0)
    {
        int stack_idx  = 1;
        wxString name(lua2wx(lua_getlocal(L, &luaDebug, stack_idx)));

        while (!name.IsEmpty())
        {
            //wxPrintf(wxT("%s lua_getlocal :%s\n"), lua_Debug_to_wxString(luaDebug).c_str(), name.c_str());

            int wxl_valuetype = WXLUA_TNONE;
            wxString value;
            wxString source(lua2wx(luaDebug.source));

            int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value);

            int val_flag_type = 0;
            int val_ref = LUA_NOREF;

            if (lua_value_type == LUA_TTABLE)
            {
                val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
            }
            else if (lua_value_type == LUA_TUSERDATA)
            {
                if (lua_getmetatable(L, -1)) // doesn't push anything if nil
                {
                    val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
                    lua_pop(L, 1);
                }
            }

            Add(new wxLuaDebugItem(name, WXLUA_TNONE, value, wxl_valuetype, source, val_ref, 0, val_flag_type));
            ++count;

            lua_pop(L, 1); // remove variable value

            name = lua2wx(lua_getlocal(L, &luaDebug, ++stack_idx));
        }
    }

    return count;
}
コード例 #2
0
//获取数组类型变量的值
//只获取最多32个元素的值
std::wstring GetArrayTypeValue(int typeID, DWORD modBase, DWORD address, const BYTE* pData) {

	//获取元素个数,如果元素个数大于32,则设置为32
	DWORD elemCount;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		typeID,
		TI_GET_COUNT,
		&elemCount);

	elemCount = elemCount > 32 ? 32 : elemCount;

	//获取数组元素的TypeID
	DWORD innerTypeID;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		typeID,
		TI_GET_TYPEID,
		&innerTypeID);

	//获取数组元素的长度
	ULONG64 elemLen;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		innerTypeID,
		TI_GET_LENGTH,
		&elemLen);

	std::wostringstream valueBuilder;

	for (int index = 0; index != elemCount; ++index) {

		DWORD elemOffset = DWORD(index * elemLen);

		valueBuilder << TEXT("  [") << index << TEXT("]  ")
					 << GetTypeValue(innerTypeID, modBase, address + elemOffset, pData + index * elemLen);

		if (index != elemCount - 1) {
			valueBuilder << std::endl;
		}
	}

	return valueBuilder.str();
}
コード例 #3
0
//将指定地址处的内存,并以相应类型的形式表现出来
std::wstring GetTypeValue(int typeID, DWORD modBase, DWORD address, const BYTE* pData) {

	DWORD typeTag;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		typeID,
		TI_GET_SYMTAG,
		&typeTag);

	switch (typeTag) {
		
		case SymTagBaseType:
			return GetBaseTypeValue(typeID, modBase, pData);

		case SymTagPointerType:
			return GetPointerTypeValue(typeID, modBase, pData);

		case SymTagEnum:
			return GetEnumTypeValue(typeID, modBase, pData);

		case SymTagArrayType:
			return GetArrayTypeValue(typeID, modBase, address, pData);

		case SymTagUDT:
			return GetUDTTypeValue(typeID, modBase, address, pData);

		case SymTagTypedef:

			//获取真正类型的ID
			DWORD actTypeID;
			SymGetTypeInfo(
				GetDebuggeeHandle(),
				modBase,
				typeID,
				TI_GET_TYPEID,
				&actTypeID);

			return GetTypeValue(actTypeID, modBase, address, pData);

		default:
			return L"??";
	}
}
コード例 #4
0
ファイル: wxldebug.cpp プロジェクト: oeuftete/wx-xword
int wxLuaDebugData::EnumerateTable(lua_State* L, int tableRef, int nIndex, wxArrayInt& references)
{
    wxCHECK_MSG(L, 0, wxT("Invalid lua_State"));
    wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data"));

    int count = 0;

    int wxl_keytype   = WXLUA_TNONE;
    int wxl_valuetype = WXLUA_TNONE;
    wxString value;
    wxString name;

    if (tableRef == LUA_GLOBALSINDEX)
    {
        lua_pushglobaltable(L);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop globals table

        Add(new wxLuaDebugItem(wxT("Globals"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
#if LUA_VERSION_NUM < 502
    // LUA_ENVIRONINDEX is no longer in 5.2
    else if (tableRef == LUA_ENVIRONINDEX)
    {
        lua_pushvalue(L, LUA_ENVIRONINDEX);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop environment table

        Add(new wxLuaDebugItem(wxT("Environment"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
#endif // LUA_VERSION_NUM < 502
    else if (tableRef == LUA_REGISTRYINDEX)
    {
        lua_pushvalue(L, LUA_REGISTRYINDEX);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop registry table

        Add(new wxLuaDebugItem(wxT("Registry"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
    else
    {
        // push the table onto the stack to iterate through
        if (wxluaR_getref(L, tableRef, &wxlua_lreg_debug_refs_key))
        {
            if (lua_isnil(L, -1))
            {
                // assert so we don't crash mysteriously inside Lua on nil
                lua_pop(L, 1); // pop nil
                wxFAIL_MSG(wxT("Invalid wxLua debug reference"));
                return count;
            }

            // Check to see if this is a wxLua LUA_REGISTRYINDEX table
            void *lightuserdata_reg_key = NULL;
            lua_pushlightuserdata(L, &wxlua_lreg_regtable_key); // push key
            lua_rawget(L, LUA_REGISTRYINDEX);
            lua_pushvalue(L, -2); // push value (table we're iterating)
            lua_rawget(L, -2);
            lightuserdata_reg_key = lua_touserdata(L, -1); // returns NULL for nil
            lua_pop(L, 2); // pop wxlua_lreg_regtable_key table and (nil or lightuserdata)

            // Check if this table/userdata has a metatable
            if (lua_getmetatable(L, -1)) // if no metatable then nothing is pushed
            {
                // get the type and value
                GetTypeValue(L, -1, &wxl_valuetype, value);

                int flag_type = 0;
                int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);

                // leading space so it's first when sorted
                Add(new wxLuaDebugItem(wxT(" __metatable"), WXLUA_TTABLE, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, flag_type));
                ++count;

                lua_pop(L, 1); // pop metatable
            }

            // start iterating
            if (lua_istable(L, -1))
            {
            lua_pushnil(L);
            while (lua_next(L, -2) != 0)
            {
                // value at -1, key at -2, table at -3

                // get the key type and value
                int lua_key_type = GetTypeValue(L, -2, &wxl_keytype, name);
                // get the value type and value
                int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value);

                // Handle items within the wxLua LUA_REGISTRYINDEX tables to give more information
                if (lightuserdata_reg_key != NULL)
                {
                    if (lightuserdata_reg_key == &wxlua_lreg_types_key)
                    {
                        value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -2)).c_str());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_classes_key)
                    {
                        wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1);
                        value += wxLuaBindClassString(wxlClass);
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_wxluabindings_key)
                    {
                        wxLuaBinding* binding = (wxLuaBinding*)lua_touserdata(L, -2);
                        name = wxString::Format(wxT("wxLuaBinding(%s) -> %s"), name.c_str(), binding->GetBindingName().c_str());
                        value += wxT(" = ") + binding->GetLuaNamespace();
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_evtcallbacks_key)
                    {
                        wxLuaEventCallback* wxlCallback = (wxLuaEventCallback*)lua_touserdata(L, -2);
                        wxCHECK_MSG(wxlCallback, count, wxT("Invalid wxLuaEventCallback"));

                        wxString s(wxlCallback->GetInfo());
                        name  = s.BeforeFirst(wxT('|'));
                        value = s.AfterFirst(wxT('|'));
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_windestroycallbacks_key)
                    {
                        // only handle t[wxWindow*] = wxLuaWinDestroyCallback*
                        wxLuaWinDestroyCallback* wxlDestroyCallBack = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1);
                        wxCHECK_MSG(wxlDestroyCallBack, count, wxT("Invalid wxLuaWinDestroyCallback"));

                        wxString s(wxlDestroyCallBack->GetInfo());
                        name  = s.BeforeFirst(wxT('|'));
                        value = s.AfterFirst(wxT('|'));
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_topwindows_key)
                    {
                        wxWindow* win = (wxWindow*)lua_touserdata(L, -2);
                        name += wxT(" ") + wxString(win->GetClassInfo()->GetClassName());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_gcobjects_key)
                    {
                        int wxl_type_ = (int)lua_tonumber(L, -1);
                        name = wxString::Format(wxT("%s(%s)"), wxluaT_typename(L, wxl_type_).c_str(), name.c_str());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_weakobjects_key)
                    {
                        wxString names_weak;

                        // iterate the table of userdata
                        lua_pushnil(L);
                        while (lua_next(L, -2) != 0)
                        {
                            // value = -1, key = -2, table = -3
                            int wxl_type_weak = (int)lua_tonumber(L, -2);
                            if (!names_weak.IsEmpty()) names_weak += wxT(", ");
                            names_weak += wxString::Format(wxT("%s(%d)"), wxluaT_typename(L, wxl_type_weak).c_str(), wxl_type_weak);
                            lua_pop(L, 1); // pop value, lua_next will pop key at end
                        }

                        name = wxString::Format(wxT("%s (%s)"), names_weak.c_str(), name.c_str());
                    }
                }

                // For these keys we know what is in the value to give more information
                if (lua_key_type == LUA_TLIGHTUSERDATA)
                {
                    void* key = lua_touserdata(L, -2);

                    if (key == &wxlua_lreg_wxeventtype_key)
                    {
                        wxEventType eventType = (wxEventType)lua_tonumber(L, -1);
                        const wxLuaBindEvent* wxlEvent = wxLuaBinding::FindBindEvent(eventType);

                        if (wxlEvent != NULL)
                        {
                            value = wxString::Format(wxT("%d = %s : %s"), eventType, lua2wx(wxlEvent->name).c_str(), wxluaT_typename(L, *wxlEvent->wxluatype).c_str());
                        }
                    }
                    else if (key == &wxlua_metatable_type_key)
                    {
                        value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -1)).c_str());
                    }
                    else if (key == &wxlua_metatable_wxluabindclass_key)
                    {
                        wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1);
                        value += wxLuaBindClassString(wxlClass);
                    }
                    else if (key == &wxlua_lreg_debug_refs_key)
                    {
                        value += wxT(" Note: You cannot traverse refed tables");
                    }
                }

                // ----------------------------------------------------------
                // Handle the key

                int key_flag_type = 0;
                int key_ref = LUA_NOREF;

                // don't ref anything in this table since it's already refed
                if ((lua_key_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key))
                {
                    key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references);
                }
                else if (lua_key_type == LUA_TUSERDATA)
                {
                    if (lua_getmetatable(L, -2)) // doesn't push anything if nil
                    {
                        key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references);
                        lua_pop(L, 1);
                    }
                }

                // only add the key if we refed it so it can be viewed in the stack dialog
                if (key_flag_type != 0)
                {
                    Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, key_ref, nIndex, key_flag_type));
                    ++count;
                }

                // ----------------------------------------------------------
                // Handle the value

                int val_flag_type = 0;
                int val_ref = LUA_NOREF;

                // don't ref anything in this table since it's already refed
                if ((lua_value_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key))
                {
                    val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
                }
                else if (lua_value_type == LUA_TUSERDATA)
                {
                    if (lua_getmetatable(L, -1)) // doesn't push anything if nil
                    {
                        val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
                        lua_pop(L, 1);
                    }
                }

                // Add the value, but not if the value doesn't expand and the key was already added
                if ((key_flag_type == 0) || ((key_flag_type != 0) && (val_flag_type != 0)))
                {
                    Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, val_flag_type));
                    ++count;
                }

                lua_pop(L, 1); // pop value, leave key
            }
            }

            lua_pop(L, 1); // remove reference
        }
    }

    return count;
}
コード例 #5
0
//获取数据成员的信息
//如果成员是数据成员,返回TRUE
//否则返回FALSE
BOOL GetDataMemberInfo(DWORD memberID, DWORD modBase, DWORD address, const BYTE* pData, std::wostringstream& valueBuilder) {

	DWORD memberTag;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		memberID,
		TI_GET_SYMTAG,
		&memberTag);

	if (memberTag != SymTagData && memberTag != SymTagBaseClass) {
		return FALSE;
	}

	valueBuilder << TEXT("  ");

	DWORD memberTypeID;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		memberID,
		TI_GET_TYPEID,
		&memberTypeID);

	//输出类型
	valueBuilder << GetTypeName(memberTypeID, modBase);

	//输出名称
	if (memberTag == SymTagData) {

		WCHAR* name;
		SymGetTypeInfo(
			GetDebuggeeHandle(),
			modBase,
			memberID,
			TI_GET_SYMNAME,
			&name);

		valueBuilder << TEXT("  ") << name;

		LocalFree(name);
	}
	else {

		valueBuilder << TEXT("  <base-class>");
	}

	//输出长度
	ULONG64 length;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		memberTypeID,
		TI_GET_LENGTH,
		&length);

	valueBuilder << TEXT("  ") << length;

	//输出地址
	DWORD offset;
	SymGetTypeInfo(
		GetDebuggeeHandle(),
		modBase,
		memberID,
		TI_GET_OFFSET,
		&offset);

	DWORD childAddress = address + offset;

	valueBuilder << TEXT("  ") << std::hex << std::uppercase << std::setfill(TEXT('0')) << std::setw(8) << childAddress << std::dec;

	//输出值
	if (IsSimpleType(memberTypeID, modBase) == TRUE) {

		valueBuilder << TEXT("  ") 
						<< GetTypeValue(
							memberTypeID,
							modBase,
							childAddress, 
							pData + offset);
	}

	return TRUE;
}