How to generate a crash dump for Windows (only for MSVC compiles)
Many of you may know that creating memory dumps under windows is a pain, as the project "Debug" is not working as intended and is bulky etc. Well this tutorial will show you how create a crash dump in "Release" settings. This will not alter the server performance, so please feel free to use it with your dedicated servers.
What is a Crash Memory Dump?
A crash memory dump is basically a way to retrace what has happened in the event of a program "crash". The dmp holds information about call stack and memory states at the time of the crash. This is extremely useful for Developers in order to identify and fix crash bugs that so many people complain about.
Requirements:
Step 1:
Open the project vc10/The Forgotten Server.sln file. If you have not set up your project for compiling, make sure you do that before continuing with this. Here is where you can find more information about initial setup under MSVC: http://otland.net/f479/compiling-msvc-compiling-forgotten-server-under-windows-easy-way-125178/
Step 2:
Now we need to make sure that the project is set to "Release"
(should be by default when you download the source, but lets make sure).
Step 3:
Next Go to The Forgotten Server project properties found here:
then set "Linker->Debugging->Generate Debug Info" to Yes (/DEBUG)
next we need to add the __EXCEPTION_TRACER__ to the definitions. Go to "C/C++->Preprocessor->Preprocessor Definitions" and click edit.
Copy & paste __EXCEPTION_TRACER__ anywhere in the box.
Step 4:
Go to "Build Solution" and wait for it to compile. Once it has finished compiling you need to make sure you copy the "Release/The Forgotten Server.pdb" file in the same file location as "Release/The Forgotten Server.exe" at all times. The .pdb file holds debugging and project state information that allows linking for debug configuration of your program. So it needs to be with the .exe file all the time if you want useful information on a crash.
Step 5:
Now when your server crashes a .mdmp file will be created, this is the useful file with the information you need!
To see the debug information just double click the file and wait for Visual Studio or Visual C++ to open. You will see a screen like this:
Click on "Debug with Native Only" then "Break" for information on the crash (it will open up files from your source code used to compile the server).
Step 6:
Crash Information! - Shows you where the fault has occurred in the source code.
The really useful information is under the "Call Stack" here:
and "Locals" (not always necessary)
and you are done! To report a crash, copy the "Call Stack" and "Locals" (if necessary). Just right click and select "Select All" then "Copy" and paste it into code tags under the project report section http://otland.net/project.php?projectid=2 be sure to give a clear description about what you were doing at the time of the crash and anything else you feel should be stated.
Report Example:
I right clicked on an NPC and the server crashed.
<NPC Lua/XML code here>
Call Stack:
Locals:
Hope this helps all the Windows users out there! These are important for the TFS Devs to help make it more stable!
So please remember to post necessary crash reports to the team!
Many of you may know that creating memory dumps under windows is a pain, as the project "Debug" is not working as intended and is bulky etc. Well this tutorial will show you how create a crash dump in "Release" settings. This will not alter the server performance, so please feel free to use it with your dedicated servers.
What is a Crash Memory Dump?
A crash memory dump is basically a way to retrace what has happened in the event of a program "crash". The dmp holds information about call stack and memory states at the time of the crash. This is extremely useful for Developers in order to identify and fix crash bugs that so many people complain about.
Requirements:
- Microsoft Visual C++ 2010 or Visual Studio 2010+
- Ability to compile Forgotten Server under MSVC (http://otland.net/f479/compiling-msvc-compiling-forgotten-server-under-windows-easy-way-125178/)
- The Forgotten Server sources
Step 1:
Open the project vc10/The Forgotten Server.sln file. If you have not set up your project for compiling, make sure you do that before continuing with this. Here is where you can find more information about initial setup under MSVC: http://otland.net/f479/compiling-msvc-compiling-forgotten-server-under-windows-easy-way-125178/
Step 2:
Now we need to make sure that the project is set to "Release"
Step 3:
Next Go to The Forgotten Server project properties found here:
then set "Linker->Debugging->Generate Debug Info" to Yes (/DEBUG)
next we need to add the __EXCEPTION_TRACER__ to the definitions. Go to "C/C++->Preprocessor->Preprocessor Definitions" and click edit.
Copy & paste __EXCEPTION_TRACER__ anywhere in the box.
Step 4:
Go to "Build Solution" and wait for it to compile. Once it has finished compiling you need to make sure you copy the "Release/The Forgotten Server.pdb" file in the same file location as "Release/The Forgotten Server.exe" at all times. The .pdb file holds debugging and project state information that allows linking for debug configuration of your program. So it needs to be with the .exe file all the time if you want useful information on a crash.
Step 5:
Now when your server crashes a .mdmp file will be created, this is the useful file with the information you need!
To see the debug information just double click the file and wait for Visual Studio or Visual C++ to open. You will see a screen like this:
Click on "Debug with Native Only" then "Break" for information on the crash (it will open up files from your source code used to compile the server).
Step 6:
Crash Information! - Shows you where the fault has occurred in the source code.
The really useful information is under the "Call Stack" here:
and "Locals" (not always necessary)
and you are done! To report a crash, copy the "Call Stack" and "Locals" (if necessary). Just right click and select "Select All" then "Copy" and paste it into code tags under the project report section http://otland.net/project.php?projectid=2 be sure to give a clear description about what you were doing at the time of the crash and anything else you feel should be stated.
Report Example:
I right clicked on an NPC and the server crashed.
<NPC Lua/XML code here>
Call Stack:
Code:
> The Forgotten Server.exe!Combat::canTargetCreature(Player * player, Creature * target) Line 378 C++
The Forgotten Server.exe!Game::playerSetAttackedCreature(unsigned int playerId, unsigned int creatureId) Line 3690 C++
The Forgotten Server.exe!boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<bool,boost::_mfi::mf2<bool,Game,enum ReloadInfo_t,unsigned int>,boost::_bi::list3<boost::_bi::value<Game *>,boost::_bi::value<enum ReloadInfo_t>,boost::_bi::value<unsigned int> > >,void>::invoke(boost::detail::function::function_buffer & function_obj_ptr) Line 154 C++
The Forgotten Server.exe!Task::operator()() Line 34 + 0x62 bytes C++
The Forgotten Server.exe!Dispatcher::dispatcherThread(void * p) Line 75 C++
The Forgotten Server.exe!boost::detail::thread_data<boost::_bi::bind_t<void,void (__cdecl*)(void *),boost::_bi::list1<boost::_bi::value<void *> > > >::run() Line 61 + 0x9 bytes C++
The Forgotten Server.exe!boost::`anonymous namespace'::thread_start_function() + 0x63 bytes C++
The Forgotten Server.exe!_callthreadstartex() Line 314 + 0x6 bytes C
The Forgotten Server.exe!_threadstartex(void * ptd) Line 292 + 0x5 bytes C
kernel32.dll!75343677()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77409f02()
ntdll.dll!77409ed5()
Locals:
Code:
- player 0x00000000 {VIPList=[...]() containerVec=[...]() invitationsList=[...]() ...} Player *
+ Creature {localMapCache=0x00000010 _tile=??? id=??? ...} Creature
+ Cylinder {...} Cylinder
playerCount 0 unsigned int
+ muteCountMap [0]() std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,unsigned int> > >
+ autoList {...} AutoList<Player>
+ VIPList [...]() std::set<unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >
+ containerVec [...]() std::vector<std::pair<unsigned int,Container *>,std::allocator<std::pair<unsigned int,Container *> > >
invitationsList [...]() std::list<unsigned int,std::allocator<unsigned int> >
storedConditionList [...]() std::list<Condition *,std::allocator<Condition *> >
+ depots [...]() std::map<unsigned int,std::pair<Depot *,bool>,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,std::pair<Depot *,bool> > > >
+ transferContainer {maxSize=??? serializationCount=??? totalWeight=??? ...} Container
marriage CXX0030: Error: expression cannot be evaluated
balance CXX0030: Error: expression cannot be evaluated
+ rates 0x000003e8 double [9]
+ talkState 0x00000430 bool [13]
+ inventoryAbilities 0x0000043d bool [11]
pzLocked CXX0030: Error: expression cannot be evaluated
saving CXX0030: Error: expression cannot be evaluated
isConnecting CXX0030: Error: expression cannot be evaluated
requestedOutfit CXX0030: Error: expression cannot be evaluated
outfitAttributes CXX0030: Error: expression cannot be evaluated
addAttackSkillPoint CXX0030: Error: expression cannot be evaluated
mounted CXX0030: Error: expression cannot be evaluated
pvpBlessing CXX0030: Error: expression cannot be evaluated
operatingSystem CXX0030: Error: expression cannot be evaluated
accountManager CXX0030: Error: expression cannot be evaluated
managerSex CXX0030: Error: expression cannot be evaluated
lastAttackBlockType CXX0030: Error: expression cannot be evaluated
chaseMode CXX0030: Error: expression cannot be evaluated
fightMode CXX0030: Error: expression cannot be evaluated
secureMode CXX0030: Error: expression cannot be evaluated
tradeState CXX0030: Error: expression cannot be evaluated
guildLevel CXX0030: Error: expression cannot be evaluated
blessings CXX0030: Error: expression cannot be evaluated
maxWriteLen CXX0030: Error: expression cannot be evaluated
sex CXX0030: Error: expression cannot be evaluated
mailAttempts CXX0030: Error: expression cannot be evaluated
premiumDays CXX0030: Error: expression cannot be evaluated
soul CXX0030: Error: expression cannot be evaluated
soulMax CXX0030: Error: expression cannot be evaluated
vocationId CXX0030: Error: expression cannot be evaluated
groupId CXX0030: Error: expression cannot be evaluated
managerNumber CXX0030: Error: expression cannot be evaluated
managerNumber2 CXX0030: Error: expression cannot be evaluated
purchaseCallback CXX0030: Error: expression cannot be evaluated
saleCallback CXX0030: Error: expression cannot be evaluated
+ varSkills 0x000004a0 int [7]
+ varStats 0x000004bc int [5]
messageBuffer CXX0030: Error: expression cannot be evaluated
bloodHitCount CXX0030: Error: expression cannot be evaluated
shieldBlockCount CXX0030: Error: expression cannot be evaluated
shootRange CXX0030: Error: expression cannot be evaluated
clientVersion CXX0030: Error: expression cannot be evaluated
messageTicks CXX0030: Error: expression cannot be evaluated
idleTime CXX0030: Error: expression cannot be evaluated
accountId CXX0030: Error: expression cannot be evaluated
lastIP CXX0030: Error: expression cannot be evaluated
level CXX0030: Error: expression cannot be evaluated
levelPercent CXX0030: Error: expression cannot be evaluated
magLevel CXX0030: Error: expression cannot be evaluated
magLevelPercent CXX0030: Error: expression cannot be evaluated
damageImmunities CXX0030: Error: expression cannot be evaluated
conditionImmunities CXX0030: Error: expression cannot be evaluated
conditionSuppressions CXX0030: Error: expression cannot be evaluated
nextStepEvent CXX0030: Error: expression cannot be evaluated
actionTaskEvent CXX0030: Error: expression cannot be evaluated
walkTaskEvent CXX0030: Error: expression cannot be evaluated
+ lossPercent 0x0000051c unsigned int [5]
guid CXX0030: Error: expression cannot be evaluated
editListId CXX0030: Error: expression cannot be evaluated
windowTextId CXX0030: Error: expression cannot be evaluated
guildId CXX0030: Error: expression cannot be evaluated
rankId CXX0030: Error: expression cannot be evaluated
promotionLevel CXX0030: Error: expression cannot be evaluated
town CXX0030: Error: expression cannot be evaluated
skullEnd CXX0030: Error: expression cannot be evaluated
lastLogin CXX0030: Error: expression cannot be evaluated
lastLogout CXX0030: Error: expression cannot be evaluated
lastLoad CXX0030: Error: expression cannot be evaluated
lastPong CXX0030: Error: expression cannot be evaluated
lastPing CXX0030: Error: expression cannot be evaluated
nextAction CXX0030: Error: expression cannot be evaluated
lastMountAction CXX0030: Error: expression cannot be evaluated
lastHitOffMount CXX0030: Error: expression cannot be evaluated
stamina CXX0030: Error: expression cannot be evaluated
experience CXX0030: Error: expression cannot be evaluated
manaSpent CXX0030: Error: expression cannot be evaluated
lastAttack CXX0030: Error: expression cannot be evaluated
lastMail CXX0030: Error: expression cannot be evaluated
+ skills 0x000005c0 unsigned __int64 [7][3]
inventoryWeight CXX0030: Error: expression cannot be evaluated
capacity CXX0030: Error: expression cannot be evaluated
+ managerChar 0x00000678 <Bad Ptr> char [100]
+ managerString {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ managerString2 {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ account {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ password {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ name {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ nameDescription {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ specialDescription {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ guildName {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ rankName {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ guildNick {...} std::basic_string<char,std::char_traits<char>,std::allocator<char> >
+ loginPosition {x=??? y=??? z=??? } Position
+ itemsLight {level=??? color=??? } LightInfo
+ backpack (..., ... std::pair<Container *,int>
vocation CXX0030: Error: expression cannot be evaluated
client CXX0030: Error: expression cannot be evaluated
walkTask CXX0030: Error: expression cannot be evaluated
party CXX0030: Error: expression cannot be evaluated
group CXX0030: Error: expression cannot be evaluated
+ inventory 0x00000820 Item * [11]
tradePartner CXX0030: Error: expression cannot be evaluated
tradeItem CXX0030: Error: expression cannot be evaluated
writeItem CXX0030: Error: expression cannot be evaluated
editHouse CXX0030: Error: expression cannot be evaluated
shopOwner CXX0030: Error: expression cannot be evaluated
weapon CXX0030: Error: expression cannot be evaluated
+ forceWalkthrough [...]() std::vector<unsigned int,std::allocator<unsigned int> >
+ revengeList [...]() std::vector<unsigned int,std::allocator<unsigned int> >
+ attackedSet [...]() std::set<unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >
shopOffer [...]() std::list<ShopInfo,std::allocator<ShopInfo> >
invitePartyList [...]() std::list<Party *,std::allocator<Party *> >
+ outfits [...]() std::map<unsigned int,Outfit,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,Outfit> > >
learnedInstantSpellList [...]() std::list<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >
+ warMap [...]() std::map<unsigned int,War_t,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,War_t> > >
- target 0x00393628 {localMapCache=0x00393638 _tile=0x00000000 id=0 ...} Creature *
+ AutoId {autoId=0 count=1000 list=[0]() ...} AutoId
Thing CXX0030: Error: expression cannot be evaluated
+ localMapCache 0x00393638 bool [23][23]
+ _tile 0x00000000 {qt_node=??? ground=??? pos={...} ...} Tile *
id 0 unsigned int
removed false bool
isMapLoaded false bool
isUpdatingPath false bool
checked false bool
+ storageMap [0]() std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >
checkVector 0 int
health 0 int
healthMax 0 int
healthMin 0 int
mana 0 int
manaMax 0 int
hideName false bool
hideHealth false bool
cannotMove false bool
speakType MSG_NONE MessageClasses
+ currentOutfit {lookType=0 lookMount=0 lookTypeEx=0 ...} Outfit_t
+ defaultOutfit {lookType=0 lookMount=0 lookTypeEx=0 ...} Outfit_t
+ masterPosition {x=0 y=0 z=0 } Position
+ lastPosition {x=0 y=0 z=0 } Position
masterRadius 0 int
lastStep 0 unsigned __int64
lastStepCost 0 unsigned int
baseSpeed 0 unsigned int
varSpeed 0 int
skillLoss false bool
lootDrop LOOT_DROP_FULL lootDrop_t
skull SKULL_NONE Skulls_t
partyShield SHIELD_NONE PartyShields_t
guildEmblem EMBLEM_NONE GuildEmblems_t
direction NORTH Direction
conditions [0]() std::list<Condition *,std::allocator<Condition *> >
+ internalLight {level=0 color=0 } LightInfo
+ master 0x00000000 {localMapCache=0x00000010 _tile=??? id=??? ...} Creature *
summons [0]() std::list<Creature *,std::allocator<Creature *> >
+ followCreature 0x00000000 {localMapCache=0x00000010 _tile=??? id=??? ...} Creature *
eventWalk 0 unsigned int
cancelNextWalk false bool
listWalkDir [0]() std::list<enum Direction,std::allocator<enum Direction> >
walkUpdateTicks 0 unsigned int
hasFollowPath false bool
forceUpdateFollowPath false bool
+ attackedCreature 0x00000000 {localMapCache=0x00000010 _tile=??? id=??? ...} Creature *
+ damageMap [0]() std::map<unsigned int,Creature::CountBlock_t,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,Creature::CountBlock_t> > >
+ healMap [0]() std::map<unsigned int,Creature::CountBlock_t,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,Creature::CountBlock_t> > >
eventsList [0]() std::list<CreatureEvent *,std::allocator<CreatureEvent *> >
blockCount 0 unsigned int
blockTicks 0 unsigned int
lastHitCreature 0 unsigned int
lastDamageSource COMBAT_NONE CombatType_t
targetEvents [0]() std::list<CreatureEvent *,std::allocator<CreatureEvent *> >
deny false bool
Hope this helps all the Windows users out there! These are important for the TFS Devs to help make it more stable!
So please remember to post necessary crash reports to the team!
Last edited: