Reputation: 5393
My program breaks and gives EXC_BAD_ACCESS here, according to the stack-trace in Xcode:
int main (int argc, const char * argv[]) {
float usd,btc,bid,ask,order_price,possible_price;
DateData * prices = load_prices(); <---
DateData * load_prices(){
FILE * file = fopen("price.dat", "rb"); <---
I determined this has nothing to do with that line of code but a later one. In a function that isn't called until later there is a line of code that seems to corrupt the program. When it returns from the function before the line is executed the program does not have this problem, but if it is supposed to return from the function after the line, there is this problem.
The line of code is a call to OpenCL. Is it somehow corrupting the program?
err = clEnqueueReadBuffer(ocl_data->commands, ocl_data->output, CL_TRUE, 0, sizeof(CombinationResult) * PPO_COMBINATIONS, (*PPO_results)[x] + PPO_COMBINATIONS*(p + 5), 0, NULL, NULL);
PPO_COMBINATIONS is defined as an integer macro and the type of PPO_results is CombinationResult (*)[3][PPO_COMBINATIONS * 11]. ocl_data->commands has type cl_command_queue and ocl_data->output has type cl_mem. err, p and x have type int.
I'm using Xcode with the "Apple LLVM Compiler 3.0". The "LLVM GCC 4.2" compiler gives "Malformed metadata record for architecture i386" for some reason.
This is the result when using the command line to compile and run with gdb:
Matthew-Mitchell:Parrallel BitCoin Trading Algorithm matt$ gcc -g cmain.c -o test -lcurl -framework OpenCL -std=c99 -arch i386
Matthew-Mitchell:Parrallel BitCoin Trading Algorithm matt$ gdb testGNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug 15 16:03:10 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .... done
(gdb) run
Starting program: /Users/matt/Programming/Bit Coin algorithm/Parrallel BitCoin Trading Algorithm/test
Reading symbols for shared libraries .+++.................................................................. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0xbea7d7cc
0x00003e9a in main (argc=0, argv=0x1000) at cmain.c:572
572 int main (int argc, const char * argv[]) {
When running directly in the command line the program exits immediately.
Upvotes: 2
Views: 1147
Reputation: 3877
Break this line of code into separate lines and assign to variables:
err = clEnqueueReadBuffer(ocl_data->commands, ocl_data->output, CL_TRUE, 0, sizeof(CombinationResult) * PPO_COMBINATIONS, (*PPO_results)[x] + PPO_COMBINATIONS*(p + 5), 0, NULL, NULL);
There is way too much going on here to safely keep as one line of code. You also need more error checking:
if (ocl_data!=null) {
//Making Assumtions here, don't expect to compile
int crCalc=sizeof(CombinationResult)*PPO_COMBINATIONS;
int ppoResult=0;
int ppoCFive=PPO_COMBINATIONS*(p + 5);
//Check size of PPO_results before assigning
if (x<sizeof((*PPO_results))
ppoResult=(*PPO_results)[x];
err = clEnqueueReadBuffer(ocl_data->commands, ocl_data->output, CL_TRUE, 0, crCalc, ppoResult + ppoCFive, 0, NULL, NULL);
} else (
//Error message
}
Upvotes: 0
Reputation: 58627
When a fault happens in some strange place in the code, like a function that isn't even being called, it could be due to an indirect jump through a corrupt code pointer. This doesn't have to be a function pointer that is visible in your program as a value. It could be a corrupt return address on the stack.
It's possible for the machine to fool itself into returning using a return address it has previously used in a previous chain of function calls (of which there are still bits and pieces on the stack).
Example. Your load_prices
called fopen
, and so it put a return address onto the stack. Then that whole business returns and the program is calling some other activation chain of functions, such that that return address is not overwritten. (Sometimes functions allocate local variables but don't completely initialize them. Or the compiler arranges for scratch areas such as register save regions, but doesn't always use them.)
Anyway, something goes haywire the stack is screwed up, and an incorrect function return is then executed such that the old return-address that was given to fopen
is re-used. Blam, you are back inside load_prices
as if returning from fopen
for a second time (similar to setjmp/longjmp).
Upvotes: 0
Reputation: 23896
I'm going to take a wild guess and say you have stack corruption when you attempt to write into (*PPO_results)[x] + PPO_COMBINATIONS*(p + 5)
through the void*
buffer pointer in clEnqueueReadBuffer
. It's easy for me to believe that the combination of your integer macro, PPO_COMBINATIONS
, and your pointer manipulation of PPO_results
combine to point back to the stack, causing you to write into the executable regions of your application unexpectedly.
If it's corrupting your stack around the region of your call into FILE * file = fopen("price.dat", "rb");
, this would reproduce the issue that you're seeing. As a bonus, this would prevent some tools like gdb
from properly unwinding your stack frames (thus inhibiting the full stack trace), because at that point, the stack is in a corrupt and flatly unrecoverable state.
The easiest check for this is to validate your writes by stepping through the write operation in a debugger or running a bounds checker over your application. Valgrind has a patch containing this functionality, and a few other tools exist in this space for OSX, as well.
Good luck with your application. Play safely with your buffers, and your programs will continue to be happy. :)
Edit: Close, but, nope.
Upvotes: 2
Reputation: 5393
Thanks to MrGomez for a good guess but the actual answer has been staring me in the face. The answer is the name of this website. The problem was that the automatic variables in the main function where too large and caused a stack overflow. The solution was to allocate the data using malloc.
For anyone seeing this from google, it's a good idea to check how big your declared variables are. You might want to allocate the memory at runtime.
Upvotes: 8