Jump to content
×
×
  • Create New...
  • 0

Core Crash - CHARACTER_MANAGER::Update


JinxTheLux

Question

The problem only happens in gcc. 
The core crashes at a certain time when cutting stone.
Thanks to everyone who helped.

//Output GDB
#0  0x080a76eb in std::__invoke_impl<void, void (CHARACTER::* const&)(unsigned int), CHARACTER* const&, unsigned int const&> (
    __f=<synthetic pointer>: <optimized out>, __t=<error reading variable>, __f=<synthetic pointer>: <optimized out>, __t=<error reading variable>)
    at /usr/local/lib/gcc10/include/c++/bits/invoke.h:70
70          __invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t,
[Current thread is 1 (LWP 100113)]
(gdb) bt full
#0  0x080a76eb in std::__invoke_impl<void, void (CHARACTER::* const&)(unsigned int), CHARACTER* const&, unsigned int const&> (
    __f=<synthetic pointer>: <optimized out>, __t=<error reading variable>, __f=<synthetic pointer>: <optimized out>, __t=<error reading variable>)
    at /usr/local/lib/gcc10/include/c++/bits/invoke.h:70
No locals.
#1  std::__invoke<void (CHARACTER::* const&)(unsigned int), CHARACTER* const&, unsigned int const&> (__fn=<synthetic pointer>: <optimized out>)
    at /usr/local/lib/gcc10/include/c++/bits/invoke.h:95
No locals.
#2  std::_Mem_fn_base<void (CHARACTER::*)(unsigned int), true>::operator()<CHARACTER* const&, unsigned int const&> (this=<synthetic pointer>)
    at /usr/local/lib/gcc10/include/c++/functional:122
No locals.
#3  std::binder2nd<std::_Mem_fn<void (CHARACTER::*)(unsigned int)> >::operator() (__x=<error reading variable>, this=<synthetic pointer>)
    at /usr/local/lib/gcc10/include/c++/backward/binders.h:158
No locals.
#4  std::for_each<std::tr1::__detail::_Hashtable_iterator<CHARACTER*, true, false>, std::binder2nd<std::_Mem_fn<void (CHARACTER::*)(unsigned int)> > > (__last=...,
    __last=..., __f=..., __first=...) at /usr/local/lib/gcc10/include/c++/bits/stl_algo.h:3844
No locals.
#5  CHARACTER_MANAGER::Update (this=0xbfbfc97c, iPulse=20608) at char_manager.cpp:649
No locals.
#6  0x08144393 in idle () at main.cpp:532
        now = {tv_sec = 1663029283, tv_usec = 267220}
        passed_pulses = <optimized out>
        t = 824307
        pta = {tv_sec = 1663029283, tv_usec = 27560}
        process_time_count = 6
        now = {tv_sec = <optimized out>, tv_usec = <optimized out>}
        passed_pulses = <optimized out>
        t = <optimized out>
#7  idle () at main.cpp:507
        now = {tv_sec = <optimized out>, tv_usec = <optimized out>}
        passed_pulses = -1
        t = <optimized out>
        pta = {tv_sec = 1663029283, tv_usec = 27560}
        process_time_count = 6
#8  0x08057d95 in main (argc=1, argv=0xbfbfec90) at main.cpp:264
        sectree_manager = {<singleton<SECTREE_MANAGER>> = {_vptr.singleton = 0x83c6bf8 <vtable for SECTREE_MANAGER+8>, static ms_singleton = 0xbfbfbbac},
          static current_sectree_version = 768, m_map_pkSectree = {_M_t = {
              _M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<unsigned int const, SECTREE_MAP*> > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int const, SECTREE_MAP*> > >> = {<No data fields>}, <No data fields>}, <std::_Rb_tree_key_compare<std::less<unsigned int> >> = {
                  _M_key_compare = {<std::binary_function<unsigned int, unsigned int, bool>> = {<No data fields>}, <No data fields>}}, <std::_Rb_tree_header> = {
                  _M_header = {_M_color = std::_S_red, _M_parent = 0x2aaf8ec0, _M_left = 0x2aaf8ec0, _M_right = 0x2aaf8ec0}, _M_node_count = 1}, <No data fields>}}},
          m_map_pkArea = {_M_t = {
              _M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, TAreaInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std--Type <RET> for more, q to quit, c to continue without paging--

//char_manager.cpp
void CHARACTER_MANAGER::Update(int32_t iPulse)
{
	BeginPendingDestroy();

	{
		if (!m_map_pkPCChr.empty())
		{
			auto callback = !(iPulse % PASSES_PER_SEC(5));

			std::for_each(m_map_pkPCChr.begin(), m_map_pkPCChr.end(),
				[&callback, &iPulse](const NAME_MAP::value_type& v)
				{
					auto ch = v.second;
					if (ch)
					{
						if (callback)
						{
							ch->ResetChatCounter();
							ch->CFSM::Update();
						}

						ch->UpdateCharacter(iPulse);
					}
				});
		}
	}

	{
		//Code causing crash
		if (!m_set_pkChrState.empty())
		{
#ifdef __GNUC__
			std::for_each(m_set_pkChrState.begin(), m_set_pkChrState.end(),
				std::bind2nd(std::mem_fn(&CHARACTER::UpdateStateMachine), iPulse));
#else
			std::for_each(m_set_pkChrState.begin(), m_set_pkChrState.end(),
				[iPulse](LPCHARACTER ch)
				{
					ch->UpdateStateMachine(iPulse);
				});
#endif
		}
	}

	{
		auto snapshot = CHARACTER_MANAGER::Instance().GetCharactersByRaceNum(xmas::MOB_SANTA_VNUM);
		if (!snapshot.empty())
		{
#ifdef __GNUC__
			std::for_each(snapshot.begin(), snapshot.end(),
				std::bind2nd(std::mem_fn(&CHARACTER::UpdateStateMachine), iPulse));
#else
			std::for_each(snapshot.begin(), snapshot.end(),
				[iPulse](LPCHARACTER ch)
				{
					ch->UpdateStateMachine(iPulse);
				});
#endif
		}
	}

	if (0 == (iPulse % PASSES_PER_SEC(3600)))
	{
		for (const auto& it : m_map_dwMobKillCount)
			DBManager::instance().SendMoneyLog(MONEY_LOG_MONSTER_KILL, it.first, it.second);

		m_map_dwMobKillCount.clear();
	}

	if (test_server && 0 == (iPulse % PASSES_PER_SEC(60)))
#ifdef __GNUC__
		sys_log(0, "CHARACTER COUNT vid %zu pid %zu", m_map_pkChrByVID.size(), m_map_pkChrByPID.size());
#else
		sys_log(0, "CHARACTER COUNT vid %Iu pid %Iu", m_map_pkChrByVID.size(), m_map_pkChrByPID.size());
#endif

	FlushPendingDestroy();
}

//stdafx.h
#ifdef __GNUC__
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#define TR1_NS std::tr1
#else
#define TR1_NS std
#define isdigit iswdigit
#define isspace iswspace
#endif

 

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0
  • Premium

Mh, this is my update function (yes I removed the GNUC define). I also use GCC (v10 with std=c++2a) :

void CHARACTER_MANAGER::Update(int iPulse)
{
	BeginPendingDestroy();

	// PC character updates
	{
		if(!m_map_pkPCChr.empty())
		{
			// Copy container
			CHARACTER_VECTOR v;
			v.reserve(m_map_pkPCChr.size());
			transform(m_map_pkPCChr.begin(), m_map_pkPCChr.end(), back_inserter(v), boost::bind(&NAME_MAP::value_type::second, boost::placeholders::_1));

			if(0 == (iPulse % PASSES_PER_SEC(5)))
			{
				FuncUpdateAndResetChatCounter f;
				std::for_each(v.begin(), v.end(), f);
			}
			else
			{
				std::for_each(v.begin(), v.end(), [iPulse](auto&& arg) -> decltype(arg->UpdateCharacter(iPulse)) { return arg->UpdateCharacter(iPulse); });
			}
		}
	}

	// Monster Updates
	{
		if(!m_set_pkChrState.empty())
		{
			CHARACTER_VECTOR v;
			v.reserve(m_set_pkChrState.size());
			v.insert(v.end(), m_set_pkChrState.begin(), m_set_pkChrState.end());
			std::for_each(v.begin(), v.end(), [iPulse](auto&& arg) -> decltype(arg->UpdateStateMachine(iPulse)) { return arg->UpdateStateMachine(iPulse); });
		}
	}

	// Update separately Santa
	{
		CharacterVectorInteractor i;

		if(CHARACTER_MANAGER::instance().GetCharactersByRaceNum(xmas::MOB_SANTA_VNUM, i))
		{
			std::for_each(i.begin(), i.end(),
					[iPulse](auto&& arg) -> decltype(arg->UpdateStateMachine(iPulse)) { return arg->UpdateStateMachine(iPulse); });
		}
	}

	// Number of records once an hour hunt monsters
	if(0 == (iPulse % PASSES_PER_SEC(3600)))
	{
		for (auto it = m_map_dwMobKillCount.begin(); it != m_map_dwMobKillCount.end(); ++it)
			DBManager::instance().SendMoneyLog(MONEY_LOG_MONSTER_KILL, it->first, it->second);

		m_map_dwMobKillCount.clear();
	}

	// The test server every 60 seconds to count the number of characters
	if(g_bIsTestServer && 0 == (iPulse % PASSES_PER_SEC(60)))
		sys_log(0, "CHARACTER COUNT vid %zu pid %zu", m_map_pkChrByVID.size(), m_map_pkChrByPID.size());

	// Delayed DestroyCharacter to
	FlushPendingDestroy();
}

 

Edited by xXIntelXx
  • Love 1
Link to comment
Share on other sites

  • 0
2 hours ago, xXIntelXx said:

Mh, this is my update function (yes I removed the GNUC define). I also use GCC (v10 with std=c++2a) :

void CHARACTER_MANAGER::Update(int iPulse)
{
	BeginPendingDestroy();

	// PC character updates
	{
		if(!m_map_pkPCChr.empty())
		{
			// Copy container
			CHARACTER_VECTOR v;
			v.reserve(m_map_pkPCChr.size());
			transform(m_map_pkPCChr.begin(), m_map_pkPCChr.end(), back_inserter(v), boost::bind(&NAME_MAP::value_type::second, boost::placeholders::_1));

			if(0 == (iPulse % PASSES_PER_SEC(5)))
			{
				FuncUpdateAndResetChatCounter f;
				std::for_each(v.begin(), v.end(), f);
			}
			else
			{
				std::for_each(v.begin(), v.end(), [iPulse](auto&& arg) -> decltype(arg->UpdateCharacter(iPulse)) { return arg->UpdateCharacter(iPulse); });
			}
		}
	}

	// Monster Updates
	{
		if(!m_set_pkChrState.empty())
		{
			CHARACTER_VECTOR v;
			v.reserve(m_set_pkChrState.size());
			v.insert(v.end(), m_set_pkChrState.begin(), m_set_pkChrState.end());
			std::for_each(v.begin(), v.end(), [iPulse](auto&& arg) -> decltype(arg->UpdateStateMachine(iPulse)) { return arg->UpdateStateMachine(iPulse); });
		}
	}

	// Update separately Santa
	{
		CharacterVectorInteractor i;

		if(CHARACTER_MANAGER::instance().GetCharactersByRaceNum(xmas::MOB_SANTA_VNUM, i))
		{
			std::for_each(i.begin(), i.end(),
					[iPulse](auto&& arg) -> decltype(arg->UpdateStateMachine(iPulse)) { return arg->UpdateStateMachine(iPulse); });
		}
	}

	// Number of records once an hour hunt monsters
	if(0 == (iPulse % PASSES_PER_SEC(3600)))
	{
		for (auto it = m_map_dwMobKillCount.begin(); it != m_map_dwMobKillCount.end(); ++it)
			DBManager::instance().SendMoneyLog(MONEY_LOG_MONSTER_KILL, it->first, it->second);

		m_map_dwMobKillCount.clear();
	}

	// The test server every 60 seconds to count the number of characters
	if(g_bIsTestServer && 0 == (iPulse % PASSES_PER_SEC(60)))
		sys_log(0, "CHARACTER COUNT vid %zu pid %zu", m_map_pkChrByVID.size(), m_map_pkChrByPID.size());

	// Delayed DestroyCharacter to
	FlushPendingDestroy();
}

 

Thank you. I asked a private question, I would appreciate it if you reply.

Link to comment
Share on other sites

  • 0
  • Premium
4 minutes ago, JinxTheLux said:

Thank you. I asked a private question, I would appreciate it if you reply.

I saw, and I thought to have replied to the DM, but oh well :kekw:

 

Anyway, you worry about the container's copy but as I explained, your line is the same as the line in the original function (which is optimized anyway by the compiler, unless you ship a debug version for the live server). Therefore I don't see the need for the new snapshot class created.

Link to comment
Share on other sites

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.


  • Metin2 Dev Github
  • Activity

    1. 0

      max level exp

    2. 8

      Quest States Core Crash Item Dupe Bug Fix

    3. 23

      Umbra / Soft4Win / SNap! scammer exposed!

    4. 46

      Ship Defense (Hydra Dungeon)

    5. 10

      Rodnia Glory | A REAL SPEED SERVER | Start 02.09.2022

    6. 0

      Avery seeks an experienced team manager

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.