How to debug a DYLIB in XCode? - c++

I am an experienced Visual Studio developer who has recently taken on an OSX 10.6 project (a C++ server project with no UI).
I have been successfully debugging the application using the XCode debugger (setting breakpoints, etc.) for months, including debugging the source code for various static libraries that are linked into the final executable program.
However, tonight I was required to debug (with breakpoints) a DYLIB that is also built from our source code, but that is linked dynamically at runtime with the application (the name of the DYLIB is read from an .ini file by the main application).
Unfortunately, the usual method I use of debugging the application (right-clicking the custom executable and selecting "Debug with Breakpoints"), though it does successfully run the debugger and allow me to debug the application (along with its statically linked libraries), exhibits the following undesired behavior when I attempt to hit a breakpoint in the source code for the DYLIB:
-> The XCode debugger reports that the breakpoint was hit in the sense that I see the function and line number in the status bar at the bottom of the XCode windows (along with an indication that this is a gdb message), and the application halts execution. However, there is no stack trace, no variables, nothing - just a completely empty debugger window. The buttons to to "step over", "step into", etc, are disabled. No editor window appears in the debugger (and hence no visual indication that the debugger has stopped on the line indicated). Opening the file by hand does not reveal the debugger hitting the line.
Unfortunately, this is useless for me as far as my attempts to debug the DYLIB.
I have hunted far and wide tonight researching and attempting to find a way for the XCode debugger to successfully hit breakpoints in a meaningful way in the source code for this dynamically linked DYLIB. I have of course done a number of clean/rebuilds. I have made certain that "load symbols lazily" is unchecked and then cleaned/rebuilt. I have restarted, and I have also deleted the "build" directory and rebuilt. I also deleted the user-specific files in the .xcodeproj package. (Note also that I am of course building and running all code, including the DYLIB code, in Development mode with all optimizations off, and generating debug symbols for all.) However, my attempts have been unsuccessful. Nor can I find so much as a single mention of this problem on internet forums.
Any help in instructing me how to use XCode to successfully debug a DYLIB that is linked to my application would be appreciated.
Thanks,
Dan.

Update -
This problem is resolved. It was my lack of experience with OSX that caused me to fail to see this. Despite the fact that my DYLIB project was part of the same XCode project as the executable that calls it, and despite the fact that the DYLIB was built in the same directory as the executable, at runtime the debugged application was not accessing the DYLIB from this location. Instead, it was accessing it from a (different) install location. I have not as of this moment tracked down where the install location is "cooked" into the application, but by copying the final executable/DYLIB into the expected install location and creating a new custom executable that points to the executable in this location, debugging of both the DYLIB and the executable works.
Thanks,
Dan.

Related

How to debug program crashing before main()

I'm using QtCreator with the visual studio 2015 kit on windows 8.1 to build a program I developed and tested on Linux, on linux it works correctly, but on windows it's just crashing immediately, and I have no idea what to look for.
The only external libraries, aside from QT I'm using are opengl and glew, so I don't think it's those.
Is there anything that's known to work in GNU C++ but crash immediately in MSVC?
Usually this kind of crashes have absolutely nothing to do with your program. It's an external library linking issue. I had this issue recently with the OpenSplice DDS library. I linked to a library that caused a segmentation fault before anything started. I resolved the issue by linking the pre-compiled libraries 1-by-1, and check each if that fixes the program.
What I recommend you to do is: Remove the libraries and resources you're linking to gradually, until your program starts and prints "Hello world" from the first line of main().
Another way to go is, make a new empty program, and link the same resources you're using in your program. This is easier, as it doesn't involve modifying your program.
This is what I would do.
Start by rebuilding the entire solution or project from a clean state. Just in case this is just some weird dependency issue that resulted in something not getting recompiled. Never hurts.
As Neil said in the comments for the question, the crash is possibly coming from a global variable who's constructor runs before main or WinMain. Are you sure you don't have something declared as "static" or at global scope that might have a constructor?
Now do the following:
Open Visual Studio.
From the menu, select File->Open->Project/Solution...
When the file open dialog pops up, select the EXE produced by Qt
Creator. (That's right - you are opening the EXE as a project). This directory is typically one folder level above the Qt project (..\build-yourapp-Desktop_Qt_5_7_0_MSVC2015_32bit-Debug\debug)
Now press the green arrow to start debugging (menu->Debug->Start
Debugging). If all goes well, your program will fail early and
Now chances are high that the program is not going to run at all under Visual Studio because Qt Creator doesn't copy all the Qt*.dll binaries to your build directory. You'll get a bunch of dialogs popping up saying that "The program can't start because Qt5-XYZ.dll can't be found". This is easily fixed by updating your PATH environment in any of the following way to include your Qt5.x.0\5.x\msvc2015\bin folder to your PATH.
You add it from the command linke and then re-launch devenv.exe from the command line.
You can add it globally from Control Panel->System->Advanced. Then restart Visual Studio from the Windows desktop.
With the EXE debug project open from within Visual Studio, just right click on the project name (not parent solution) and a dialog will popup that allows you to edit startup settings. One of which is the Environment.
And that should do it. From there you can start the debugger on your EXE, set breakpoints as needed, and analyze the call stack on crash.
It's really easy: build all the libraries you use, including Qt, with debug information (those can be release builds as long as the PDB files are generated). Then run your application under a debugger (e.g. F5 under Qt Creator), and it will stop at the point of the crash.
The code that runs before main and is known to cause trouble will be the global object initialization: you're likely running into the static initialization order fiasco.
Another cause for the problem could be stackoverflow. In Linux, the stack size by default is usually 8 MB whereas in Windows it's just 1 MB.
Try to link with /STACK:8388608 switch. If it works, you might consider allocating more data on the heap and stay with the default stack size of 1 MB.

VS2008 C++ breakpoint becomes permanently inactive after access violation error (no executable code associated with line)

I am reproducing the following behavior in VS2008 (native C++):
attach to an executable that consumes a custom dll (for which I have the source)
debug the code from the dynamic lib
encounter an access violation error (probably caused by the code in the executable - closed source)
break on access violation error with the attached debugger
After this, no matter how many times I reattach, rebuild, restart the application, computer, any breakpoint I will set in the .dll source code becomes inactive (No executable code associated with this line is the alleged cause, according to VS).
I suspect this is an issue with VS2008, as I did the same on a different machine and now I have two machines where debugging is no longer possible.
Are there any recorded solutions of this issue? What can be done to overcome it?
What I have done:
deleting everything (the entire solution, pdbs, binaries, etc.) and starting with the code from scratch (cloning the latest version from the repository)
restarting the machine
changing the machine (it worked once, until the error occurred, then the other computer exhibited the same behavior)
What I cannot do:
change compiler/VS version
debug the executable (sadly no source code available and lack of assembly skills)
The root of the issue was more subtle. Although the project was intended to be native C++, I have found that on the configuration I was testing the code, the entire project was built with CLR support.
When attaching to the application the first time on any machine, in native debugging mode, the breakpoints would trigger. However, when encountering the native access violation error, these breakpoints became permanently inactive thereafter. After deciding to check what happens if I let the debugger attach in auto mode, I have discovered that the breakpoints became active and hence found out that all code had been compiled with the /clr flag except for the entrypoint in the consumed dll, which had no CLR support.
The question here is why VS2008 behaves like this and does not directly disable breakpoints whenever one attempts to debug a managed context using native debug settings.
TL;DR: check if your C++ project is built with CLR support and attach either as native or managed, depending on your needs. Alternatively, if only some of your files require C++-CLI usage, enable the /clr flag only for those. It is more often a better choice since C++-CLI often clashes with certain native libraries (e.g. not std::mutex support, linking against native static libs Linking unmanaged C++ DLL with managed C++ class library DLL, etc.).

Dumping a stack trace from C++ (Windows) - fails to find symbols

I'm a developer of Windows desktop software, and from time to time our app crashes. In rare cases I'd like to get a customer to run a debug version of the app to send me a stack trace so I know where it crashed. I followed the instructions in here:
Windows C++ stack trace from a running app
...but while it works on my development machine, it doesn't work on any client machine or those of my colleagues, who don't have Visual Studio installed. So I presume that there's some .dll or something they need before it'll work. They're using the same .exe I'm using, i.e. the one I compiled in VC++ in debug mode.
After some painstaking "message window" debugging, I learnt it's failing in SymGetSymFromAddr64() - this returns FALSE. But when I walk the stack, this always returns FALSE or it returns garbage that doesn't make sense (random unrelated method names), as if it's the PC values which are invalid, not the mapping process. To reiterate, it's a debug mode .exe that produces a perfect symbolic stack trace on my development machine.
I did some research and found some mentions of "dbghelp.dll" and "imagehlp.dll" but I just ended up confused. "dbghelp.dll" ships with all versions of Windows, but with reduced functionality. There's some other things I could install, but it's a little scary to be installing some Windows "WDK" or "debug kits" which might overwrite important system .dll's or do god-knows-what to your computer.
So what I need to know is: "what's the simplest set of instructions I can give to these helper customers e.g. the minimum set of .dll's and where to stick them so that we can get proper symbolic information out of the stack traces when our program crashes?"
The most likely reason for failing to find the symbols is that the .pdb file cannot be found. Even if you generate a .exe in debug mode, the symbols are not in the .exe, they are in the .pdb file. Through a lot of empirical testing, it seems that the process has the pathname of the .pdb hardcoded in it, so if your clients don't have that file at that location, they won't necessarily find it. However, you can supply a "search path" to the SymInitialize() function - a folder or set of folders to use to search for the .pdb file.
In my configuration, I had an exe called "Edval.exe" and a .pdb called "DebugEdval.pdb". The process searches for "DebugEdval.pdb" in the search folders. This corresponds to what you've configured in "Properties > Linker > Debugging > Generate Program Database File".

How to build standalone SDL project with visual C++?

I'm getting ready to enter Ludum Dare this evening, and I'm getting really frustrated because I'm unable to build my project into a standalone .exe.
I feel like this question has been asked at least 100 times but none of the answers I'm finding are helping me out at all... I don't really understand what static linking is or how to do it, and that doesn't even seem like the solution to my problem; I don't mind if I'm shipping out a bunch of .dll files with my program, I just want the program to run on its own so I can submit it at the end of the competition.
Basically, my visual studio (2010 express) configuration follows exactly LazyFoo's tutorial on setting it up. Everything runs fine on both debug and release configurations when I start the program from visual studio, but when I navigate into the Debug or Release folders of the project and try to run the .exe, the programs break with an error about abort() being called, or they give me the error "X program has stopped working."
I'm including all of my DLLs in the same folder as the executables are being placed, and the game runs perfectly fine from inside VS, but I just can't seem how to figure out how to compile it as a standalone .exe (or even including a folder full of dlls) without it falling apart.
Can someone give me a pretty precise way to get this working? Any help would be great.
If you have an EXE, then your program is compiling. Most likely in debug mode, the program is running using a specific directory as the current working directory (CWD), but when you run it as standalone, the CWD is different.
The CWD affects both the DLL that can be loaded as well as the search of any file that uses a relative path (that is, not starting with a [back]slash). That is probably your problem: textures, graphics, configuration files, fonts...
My advise is to set the CWD in the debugging runs (there is an option for that) to be exactly the same than that of the EXE, that is the default when you run the EXE. Then you will be able to debug your crash.

Program crashes when outside test environment - C++

I have a program that runs fantastically when run from inside Visual Studio 2010 Express but when built and taken out, it has problems. I have set up the external test environment the same as when it is run from within Visual Studio so that shouldn't be the problem. I want to attach it to the .exe to see where the crash is but I don't have the non-Express versions.
Any suggestions? Why would a program crash outside of the the VSC++ 2010 Express environment but run perfectly inside.
I would post code but it's a huge project, not a line that would cause an error.
Thank you so much for your time.
It's very difficult to know for certain without knowing what the crash is, but a couple of common issues that may cause this:
Environment variables not the same. Perhaps you are relying on something in vcvars32.bat in your test environment.
The PATH environment variable is not the same and your picking up some bad or incompatible DLL.
Your code is somehow dependant on the current working directory being the one when run from Visual Studio.
Wikipedia to the rescue?
Time can also be a factor in heisenbugs. Executing a program under control of a debugger can change the execution timing of the program as compared to normal execution. Time-sensitive bugs such as race conditions may not reproduce when the program is slowed down by single-stepping source lines in the debugger. This is particularly true when the behavior involves interaction with an entity not under the control of a debugger, such as when debugging network packet processing between two machines and only one is under debugger control.
Also, note that User32.dll slightly changes its behavior when under a debugger, in order to make debugging easier for you. That shouldn't change anything, though.
You could debug this using the freely available Debugger Tools for Windows. There's plenty of documentation and quick start guides available, especially the chm included in the install. In your case, you may want to try the following:
Make sure you have the PDBs for your app available somewhere on a share.
Attach to the running instance of the app: windbg -p <PID>. Note that you can also start the program under the context of the debugger by doing windbg -g foo.exe.
Repro the crash.
Change the symbol path to your symbols and the Microsoft public symbol server to get proper symbols for components: .sympath x:\YourPathToPDBs; SRV*x:\symbols*http://msdl.microsoft.com/download/symbols
Tell the debugger to reload symbols using your path: .reload
Get a callstack by hitting k in the debugger.
That's the barebones you need to figure out where it's crashing. You can then go deeper and try to analyze exactly why it's crashing by looking at the debugger chm or other resources on MSDN or Tess's blog. One useful command is dv to dump local variables for a particular frame. If the callstack doesn't give line numbers, type .lines and then hit k or kb.
You could surround all code in your Main function with a try catch block. When you catch an excepcion, write to a log file the stack trace.
Then run your exe and check the log file to know where your program is crashing.
PS: Don't forget to place the *.pdb file together with the exe file, otherwise you won't be able to get the stacktrace information.
I realise this question is a couple of years old, but I have been experiencing the same thing and came upon a possible culprit (the actual culprit in my case), which may help others who have this issue.
One important difference when running an application within Visual Studio and running it outside is the Current Working Directory ("CWD").
A typical directory structure for a Visual C++ Solution/Project is along these lines:
Solution <- the location of your solution file
Debug <- where the Debug executables end up
Release <- where the Release executables end up
Project <- the location of your project file
Debug <- where Debug intermediate files end up
Release <- where Release intermediate files end up
When you execute the application from within Studio, either with "Start Debugging" or "Start Without Debugging", the default CWD is the Project directory, so in this case Solution\Project.
However, when you execute outside by simply double-clicking the application, the CWD is the application directory (Solution\Debug for example).
If you are attempting to open a file from the current directory (which is what happens when you do std::ifstream ifstr("myfile.txt")), whether it succeeds depends on where you were when you started the application.