Jump to content
  • Advertisement
Sign in to follow this  
Storyyeller

More std::function woes (segfault)

This topic is 2533 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I keep getting segfaults for no apparent reason.

The stacktrace goes mycode -> std::function operator () -> random hex value, often sentinals like 0xdeadbeef
Based on this, it appears that my std::function is attempting to execute random values as function pointers when called, but I'm not sure how this is even possible. Doesn't std::function have an invariant that it always points to either null or a valid callable? How would it even get an invalid state unless you deliberately pass it one?

In my case it is being initialized from a pointer to an ordinary function, so there's not even the possibilty of dangling pointers or something like that.

Share this post


Link to post
Share on other sites
Advertisement
Can you prepare a minimal example program? Can you post actual examples of these sentinel hex values? What compiler toolchain are you using?


How would it even get an invalid state unless you deliberately pass it one?
[/quote]
Your program might be corrupting memory, or you might have a bug like the object that owns the std::function is invalid.

Share this post


Link to post
Share on other sites
I'm using mingw. (With Code::Blocks 10.05 as IDE and Windows 7 as OS).
The hex values change everytime, but I did see deadbeef come up at least once. How would I go about determining if memory is being corrupted?

Also, the problems only occur while debugging. There aren't any errors normally. I guess that does suggest a dangling pointer of some sort, but I'm not really sure how it could happen as I have everything wrapped in smart pointers anyway.

Share this post


Link to post
Share on other sites

I guess that does suggest a dangling pointer of some sort, but I'm not really sure how it could happen as I have everything wrapped in smart pointers anyway.

Segfaults with smart pointers can happen in exactly the same way as cars equipped with proximity sensors can bump into obstacles.

Do you have a reproducible test case? Creating and calling a std::function should be simple.

Share this post


Link to post
Share on other sites
Well it's reproducible in the sense that the segfault happens everytime my program is run under the debugger. Unfortunately, the program is pretty big, and it would take a while to figure out what the minimal parts required for the behavior to appear is.

Share this post


Link to post
Share on other sites
Would it be possible to build your program for Linux (even in a virtual machine if you don't have such a system)? The Valgrind tool has an excellent reputation. If you cannot, you might try some Windows-based alternative to Valgrind.


Also, the problems only occur while debugging.
[/quote]
That is common. Debugging tools often manage memory in a totally different way, prrecisely to trigger such bugs (e.g. by filling new/released memory with special patterns). In release builds, or without a debugger, what is likely happening is some subtle memory corruption. Not enough to trigger a crash, but you might find odd behaviour, e.g. an enemy or the player's statistics might be overwritten with odd values, causing some bizarre behaviour that you might not notice.


... but I'm not really sure how it could happen as I have everything wrapped in smart pointers anyway.
[/quote]
It can happen lots of ways. Perhaps you are exceeding the bounds of an array. Maybe you are accessing an invalidated iterator of a standard container. Perhaps you are storing pointers or references to objects in a standard container, and the container resizes or is otherwise structurally modified such that some pointers/references to objects become invalid. Maybe a critical class does not properly obey the rule of three, which causes some of the members to end up in an invalid state. Perhaps you are accidentally treating a non-POD class as if it were POD (e.g. using ZeroMemory, memset or memcpy/memmov). This is not an exhaustive list.

Smart pointers help, but if the code abuses the smart pointers it can corrupt the invariants, and result in such behaviour.

Share this post


Link to post
Share on other sites
Well I don't use direct memory modification functions like memcpy anywhere, but the others might be possibilities. I'll try to port it over to my linux vm and run Valgrind.

Share this post


Link to post
Share on other sites
Is your program multi-threaded? If so, such a bug could be caused by incorrect synchronisation.

Share this post


Link to post
Share on other sites
Well I don't use threads anywhere, though I guess a library I'm using (mainly SDL, Box2d and Boost Filesystem) conceivably could be.


Edit: I've finally managed to get my game ot build in my Linux VM. Here's Valgrind's output.
I'm not sure how to interpert the results, but it looks like the first error is actually inside Box2d.

==3660== Memcheck, a memory error detector
==3660== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3660== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3660== Command: ./Pickory
==3660== Parent PID: 3574
==3660==
==3660== Invalid write of size 2
==3660== at 0x8119AF3: b2FixtureDef::b2FixtureDef() (b2Fixture.h:60)
==3660== by 0x81198AB: FixtureDef::FixtureDef(b2Shape*) (physicsFixturedef.cpp:11)
==3660== by 0x811C007: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== Address 0x4cab9ec is 0 bytes after a block of size 28 alloc'd
==3660== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==3660== by 0x811BFF7: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== by 0x8186A44: GotoTitlescreen(bool) (main.cpp:166)
==3660==
==3660== Invalid write of size 2
==3660== at 0x8119AFC: b2FixtureDef::b2FixtureDef() (b2Fixture.h:61)
==3660== by 0x81198AB: FixtureDef::FixtureDef(b2Shape*) (physicsFixturedef.cpp:11)
==3660== by 0x811C007: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== Address 0x4cab9ee is 2 bytes after a block of size 28 alloc'd
==3660== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==3660== by 0x811BFF7: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== by 0x8186A44: GotoTitlescreen(bool) (main.cpp:166)
==3660==
==3660== Invalid write of size 2
==3660== at 0x8119827: FixtureDef::InitDefaultProperties() (physicsFixturedef.cpp:8)
==3660== by 0x81198ED: FixtureDef::FixtureDef(b2Shape*) (physicsFixturedef.cpp:15)
==3660== by 0x811C007: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== Address 0x4cab9ee is 2 bytes after a block of size 28 alloc'd
==3660== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==3660== by 0x811BFF7: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== by 0x8186A44: GotoTitlescreen(bool) (main.cpp:166)
==3660==
==3660== Invalid write of size 2
==3660== at 0x80555DE: FixtureDef::SetFilterGroup(short) (physicsFixturedef.h:28)
==3660== by 0x811C050: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== by 0x8186A44: GotoTitlescreen(bool) (main.cpp:166)
==3660== Address 0x4cab9ee is 2 bytes after a block of size 28 alloc'd
==3660== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==3660== by 0x811BFF7: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== by 0x8174BF6: EntityManager::EntityManager() (entitymanager.cpp:45)
==3660== by 0x8186A44: GotoTitlescreen(bool) (main.cpp:166)
==3660==
==3660== Jump to the invalid address stated on the next line
==3660== at 0xB800C708: ???
==3660== by 0x81AB886: b2Body::CreateFixture(b2FixtureDef const*) (in /home/robert/Shared_Ubuntu/Pickory (copy)/Pickory)
==3660== by 0x8118EAA: Body::AddShape(FixtureDef*) (physicsBody.cpp:54)
==3660== by 0x811C069: KidSuperclass::KidSuperclass(EntityManagerInterface*, PickoryLoadState const&, double) (kidsuper.cpp:98)
==3660== by 0x811F530: Pickory::Pickory(EntityManagerInterface*, PickoryLoadState const&, double) (pickory.cpp:43)
==3660== by 0x811F99A: CreatePickory(EntityManagerInterface*, PickoryLoadState const&) (pickoryfactory.cpp:7)
==3660== by 0x81685E3: TitleScreen::LoadEverything(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (roomdef_ts.cpp:15)
==3660== by 0x819575D: std::_Function_handler<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int), void (*)(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::_M_invoke(std::_Any_data const&, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) (functional:1668)
==3660== by 0x819571D: std::function<void ()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int)>::operator()(EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&, unsigned int) const (functional:2024)
==3660== by 0x819509C: RoomLoader::LoadEverything(unsigned int, unsigned int, EntityManagerInterface*, std::shared_ptr<BoundsInterface>&, PickoryLoadState const&) (rooms.cpp:10)
==3660== by 0x8178E17: EntityManager::DoRoomTransition(unsigned int, unsigned int, PickoryLoadState const&) (entitymanager.cpp:258)
==3660== by 0x8179141: EntityManager::CheckRoomTransition() (entitymanager.cpp:289)
==3660== Address 0xb800c708 is not stack'd, malloc'd or (recently) free'd
==3660==
==3660==
==3660== HEAP SUMMARY:
==3660== in use at exit: 269,856 bytes in 1,622 blocks
==3660== total heap usage: 13,903 allocs, 12,281 frees, 2,472,967 bytes allocated
==3660==
==3660== LEAK SUMMARY:
==3660== definitely lost: 24 bytes in 3 blocks
==3660== indirectly lost: 104 bytes in 4 blocks
==3660== possibly lost: 2,955 bytes in 94 blocks
==3660== still reachable: 266,773 bytes in 1,521 blocks
==3660== suppressed: 0 bytes in 0 blocks
==3660== Rerun with --leak-check=full to see details of leaked memory
==3660==
==3660== For counts of detected and suppressed errors, rerun with: -v
==3660== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 98 from 11)

Share this post


Link to post
Share on other sites
And here is the offending file. It appears that for some reason, the write to filter.maskbits is going past the end of the struct. Does anyone know how this could happen?

[source lang=çpp']/*
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef B2_FIXTURE_H
#define B2_FIXTURE_H

#include <Box2D/Dynamics/b2Body.h>
#include <Box2D/Collision/b2Collision.h>
#include <Box2D/Collision/Shapes/b2Shape.h>

class b2BlockAllocator;
class b2Body;
class b2BroadPhase;
class b2Fixture;

/// This holds contact filtering data.
struct b2Filter
{
/// The collision category bits. Normally you would just set one bit.
uint16 categoryBits;

/// The collision mask bits. This states the categories that this
/// shape would accept for collision.
uint16 maskBits;

/// Collision groups allow a certain group of objects to never collide (negative)
/// or always collide (positive). Zero means no collision group. Non-zero group
/// filtering always wins against the mask bits.
int16 groupIndex;
};

/// A fixture definition is used to create a fixture. This class defines an
/// abstract fixture definition. You can reuse fixture definitions safely.
struct b2FixtureDef
{
/// The constructor sets the default fixture definition values.
b2FixtureDef()
{
shape = NULL;
userData = NULL;
friction = 0.2f;
restitution = 0.0f;
density = 0.0f;
filter.categoryBits = 0x0001;
filter.maskBits = 0xFFFF;
filter.groupIndex = 0;
isSensor = false;
}

/// The shape, this must be set. The shape will be cloned, so you
/// can create the shape on the stack.
const b2Shape* shape;

/// Use this to store application specific fixture data.
void* userData;

/// The friction coefficient, usually in the range [0,1].
float32 friction;

/// The restitution (elasticity) usually in the range [0,1].
float32 restitution;

/// The density, usually in kg/m^2.
float32 density;

/// A sensor shape collects contact information but never generates a collision
/// response.
bool isSensor;

/// Contact filtering data.
b2Filter filter;
};

/// This proxy is used internally to connect fixtures to the broad-phase.
struct b2FixtureProxy
{
b2AABB aabb;
b2Fixture* fixture;
int32 childIndex;
int32 proxyId;
};

/// A fixture is used to attach a shape to a body for collision detection. A fixture
/// inherits its transform from its parent. Fixtures hold additional non-geometric data
/// such as friction, collision filters, etc.
/// Fixtures are created via b2Body::CreateFixture.
/// @warning you cannot reuse fixtures.
class b2Fixture
{
public:
/// Get the type of the child shape. You can use this to down cast to the concrete shape.
/// @return the shape type.
b2Shape::Type GetType() const;

/// Get the child shape. You can modify the child shape, however you should not change the
/// number of vertices because this will crash some collision caching mechanisms.
/// Manipulating the shape may lead to non-physical behavior.
b2Shape* GetShape();
const b2Shape* GetShape() const;

/// Set if this fixture is a sensor.
void SetSensor(bool sensor);

/// Is this fixture a sensor (non-solid)?
/// @return the true if the shape is a sensor.
bool IsSensor() const;

/// Set the contact filtering data. This will not update contacts until the next time
/// step when either parent body is active and awake.
/// This automatically calls Refilter.
void SetFilterData(const b2Filter& filter);

/// Get the contact filtering data.
const b2Filter& GetFilterData() const;

/// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
void Refilter();

/// Get the parent body of this fixture. This is NULL if the fixture is not attached.
/// @return the parent body.
b2Body* GetBody();
const b2Body* GetBody() const;

/// Get the next fixture in the parent body's fixture list.
/// @return the next shape.
b2Fixture* GetNext();
const b2Fixture* GetNext() const;

/// Get the user data that was assigned in the fixture definition. Use this to
/// store your application specific data.
void* GetUserData() const;

/// Set the user data. Use this to store your application specific data.
void SetUserData(void* data);

/// Test a point for containment in this fixture.
/// @param p a point in world coordinates.
bool TestPoint(const b2Vec2& p) const;

/// Cast a ray against this shape.
/// @param output the ray-cast results.
/// @param input the ray-cast input parameters.
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const;

/// Get the mass data for this fixture. The mass data is based on the density and
/// the shape. The rotational inertia is about the shape's origin. This operation
/// may be expensive.
void GetMassData(b2MassData* massData) const;

/// Set the density of this fixture. This will _not_ automatically adjust the mass
/// of the body. You must call b2Body::ResetMassData to update the body's mass.
void SetDensity(float32 density);

/// Get the density of this fixture.
float32 GetDensity() const;

/// Get the coefficient of friction.
float32 GetFriction() const;

/// Set the coefficient of friction. This will _not_ change the friction of
/// existing contacts.
void SetFriction(float32 friction);

/// Get the coefficient of restitution.
float32 GetRestitution() const;

/// Set the coefficient of restitution. This will _not_ change the restitution of
/// existing contacts.
void SetRestitution(float32 restitution);

/// Get the fixture's AABB. This AABB may be enlarge and/or stale.
/// If you need a more accurate AABB, compute it using the shape and
/// the body transform.
const b2AABB& GetAABB(int32 childIndex) const;

protected:

friend class b2Body;
friend class b2World;
friend class b2Contact;
friend class b2ContactManager;

b2Fixture();

// We need separation create/destroy functions from the constructor/destructor because
// the destructor cannot access the allocator (no destructor arguments allowed by C++).
void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def);
void Destroy(b2BlockAllocator* allocator);

// These support body activation/deactivation.
void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf);
void DestroyProxies(b2BroadPhase* broadPhase);

void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2);

float32 m_density;

b2Fixture* m_next;
b2Body* m_body;

b2Shape* m_shape;

float32 m_friction;
float32 m_restitution;

b2FixtureProxy* m_proxies;
int32 m_proxyCount;

b2Filter m_filter;

bool m_isSensor;

void* m_userData;
};

inline b2Shape::Type b2Fixture::GetType() const
{
return m_shape->GetType();
}

inline b2Shape* b2Fixture::GetShape()
{
return m_shape;
}

inline const b2Shape* b2Fixture::GetShape() const
{
return m_shape;
}

inline bool b2Fixture::IsSensor() const
{
return m_isSensor;
}

inline const b2Filter& b2Fixture::GetFilterData() const
{
return m_filter;
}

inline void* b2Fixture::GetUserData() const
{
return m_userData;
}

inline void b2Fixture::SetUserData(void* data)
{
m_userData = data;
}

inline b2Body* b2Fixture::GetBody()
{
return m_body;
}

inline const b2Body* b2Fixture::GetBody() const
{
return m_body;
}

inline b2Fixture* b2Fixture::GetNext()
{
return m_next;
}

inline const b2Fixture* b2Fixture::GetNext() const
{
return m_next;
}

inline void b2Fixture::SetDensity(float32 density)
{
b2Assert(b2IsValid(density) && density >= 0.0f);
m_density = density;
}

inline float32 b2Fixture::GetDensity() const
{
return m_density;
}

inline float32 b2Fixture::GetFriction() const
{
return m_friction;
}

inline void b2Fixture::SetFriction(float32 friction)
{
m_friction = friction;
}

inline float32 b2Fixture::GetRestitution() const
{
return m_restitution;
}

inline void b2Fixture::SetRestitution(float32 restitution)
{
m_restitution = restitution;
}

inline bool b2Fixture::TestPoint(const b2Vec2& p) const
{
return m_shape->TestPoint(m_body->GetTransform(), p);
}

inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const
{
return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex);
}

inline void b2Fixture::GetMassData(b2MassData* massData) const
{
m_shape->ComputeMass(massData, m_density);
}

inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const
{
b2Assert(0 <= childIndex && childIndex < m_proxyCount);
return m_proxies[childIndex].aabb;
}

#endif

[/source]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!