2

I have a program I've been working on for a number of weeks, and I made some big changes over the past few days and I now can't figure out why the program doesn't work outside of the VC++2010 environment.

The program runs flawlessly when I open up the project, select Release or Debug from the Solution Configurations dropdown, and hit F5. But when I grab the executable from the Release/Debug folder, drop it in a location where it can access the assets I am using, and then run it, it loads for a few seconds and then shows this lovely error "Project.exe has stopped working - Windows is checking for a solution for the problem..." Of course, like always, Windows can't find a solution to the problem.

Quick disclaimer before you read through all this code: While the error has been caused by a change in code, it is doubtful as to which change caused it because I have changed a few things at once - which I know is stupid, but it happened. I've posted code from the most likely source of the error. Scroll to "My second idea:" if you trust in my coding habits.


The biggest recent change I have made involves my input handler, and integrating keybinds via function pointers (with which I have no experience whatsoever). I defined an array of function pointers in a RawInput class like so:

typedef  void (Application::*AppFunc)(void);
typedef  void (Application::*AppFuncDelta)(int delta);

AppFunc onKeyPress[256];
AppFunc onKeyRelease[256];
AppFunc onMouseButtonPress[5];
AppFunc onMouseButtonRelease[5];

AppFuncDelta onMouseMove[3];

I have alerted the RawInput class to the Application class by declaring a prototype directly above its own class definition like so:

class Application;

and I fill these arrays like so in Application::Initialize() (I have many keys defined, so here is an excerpt):

m_RawInput->onMouseMove[0] = &Application::mouseMoveX;
m_RawInput->onMouseMove[1] = &Application::mouseMoveY;

where Application::mouseMoveX and Application::mouseMoveY function that take an int argument and do not return a value.

These functions are called inside of RawInput::Interpret(LPARAM lParam) like so:

if (raw->data.keyboard.Flags & RI_KEY_BREAK) //key released
{
    if (onKeyRelease[raw->data.keyboard.VKey] && g_app) (g_app->*onKeyRelease[raw->data.keyboard.VKey])();
    return;
}
else //key pressed down
{
    if (onKeyPress[raw->data.keyboard.VKey] && g_app) (g_app->*onKeyPress[raw->data.keyboard.VKey])();
    return;
}

g_app is defined in input.cpp as extern Application *g_app. I've used g_app since the program's conception, and it is definitely not a problem.

The first problem I had with this update lay in a null function pointer, but now I run a check the validity of the specified function and the validity of g_app before calling any function. And at any rate, this error would occur inside as well as outside of the VC++ environment and I suspect it is not the problem.


I searched around for a while prior to asking on my own and found this nearly identical question also on Stack Overflow. Sadly for me, it remains unanswered.


I also discovered this tool(called dependency walker), which goes through all dependencies of an executable and lets you know if some of them are not found. It could not find (and I could not find a definitive version of) these DLLs:

API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-SHCORE-SCALING-L1-1-1.DLL
DCOMP.DLL
GPSVC.DLL
IESHIMS.DLL

One of my two ideas is that RawInput can't call a function that it doesn't know about - and it doesn't know about any of the functions in Application. But my current #include hierarchy makes it very difficult for RawInput to know about these functions.

My second idea:

There are only 3 things (according to Vivian De Smedt) that change when a program is run inside or outside of an IDE:

1.) The arguments that are passed to the program. //perhaps

2.) The working directory of the application. //has not changed

3.) The environment variables if you changed them after you started Visual Studio (or after you started the launcher if you use such launcher: e.g.: Explorer++) //I suspect this to be the problem. Ideas?


I'm thoroughly lost on this issue, and I've spent a significant amount of time composing this question. Any suggestions are greatly appreciated. I'll be around for 15 minutes, so please request clarification if I lost you anywhere :)

Community
  • 1
  • 1
Proxy
  • 1,824
  • 1
  • 16
  • 27
  • 2
    Unless you explicitly set the working directory, running your application from Visual Studio and running your application from outside Visual Studio **will** have different working directories. – IInspectable Jan 01 '14 at 19:06
  • Stupid man debugging: WHERE does it stop working? During loading? Do you have any log (if not...add it)? What if you put a MessageBox as earliest as possible and you attach VS (to debug it)? Nothing in Windows Events Log? – Adriano Repetti Jan 01 '14 at 19:09
  • Use a debugger. At least you can use Tools + Attach to Process when the crash dialog is showing. You'll see from the Call Stack window what code you wrote triggered the bomb. Or use __debugbreak() in your main() function to get it attached early. – Hans Passant Jan 01 '14 at 19:12
  • @Adriano From the Event viewer: Faulting application name: Project.exe, version: 0.0.0.0, time stamp: 0x52c45fb3 Faulting module name: Project.exe, version: 0.0.0.0, time stamp: 0x52c45fb3 Exception code: 0xc0000094 Fault offset: 0x0000559b Faulting process id: 0x172c Faulting application start time: 0x01cf07202329389d Faulting application path: \Project.exe Faulting module path: \Project.exe Report Id: 6303b7d2-7313-11e3-867c-685d4322ad75 – Proxy Jan 01 '14 at 19:12
  • Divide by zero, that's pretty easy to debug. – Hans Passant Jan 01 '14 at 19:13
  • http://support.microsoft.com/kb/2756614 -- Looks like integer / 0... The only time I could possibly do that is with my framerate... I'll have to look at that – Proxy Jan 01 '14 at 19:14

2 Answers2

2

xP Sorry for wasting your time, guys. I totally led you in the wrong direction. The divide-by-0 was due to a % operator in the middle of two uninitialized variables.

Just something kind of interesting for anyone who reads this:

uninitialized_variable1 % uninitialized_variable2 is an error without a debugger attached while it evaluates to zero in a debugger's environment.

Proxy
  • 1,824
  • 1
  • 16
  • 27
0

Do this. Let's pretend you EXE is named Foo.exe.

  1. Do a full clean build of your project and make a new Debug build.

  2. Copy your the Debug build of Foo.exe and Foo.pdb to this other directory that you are having trouble running from.

  3. Start Visual Studio, but with no project open.

  4. From the File menu, select File -> Open Project/Solution.

  5. Navigate the Open Project director to this directory you copied the binary to.

  6. Select Foo.exe as the project. This will start a debugging project for your compiled binary.

  7. Now start debugging as you normally would (e.g. Press F11 - Step Into). If all goes well you have a debugging session broken into the first line of main or WinMain. You might get prompted for the location of the source directory, but otherwise you should be able to debug your project in the same way as if it was running out of the project drop directory. (Set breakpoints as appropriate, Continue, Step Into, Watch variables, etc..)

selbie
  • 100,020
  • 15
  • 103
  • 173
  • 1
    When I do it like that, it works fine. No problems at all. The problem arises when I run the executable alone. – Proxy Jan 02 '14 at 00:39
  • You know you can attach the debugger after the process crashes right (while the exception dialog is still visible)? You can usually see the call stack and find the offending line of code. From the Debug menu, click "Attach to Process". – selbie Jan 02 '14 at 01:56