2012-04-05 2 views
2

내 프로그램 나누기 완전히 무관 한 줄에 세그먼트 오류가 발생하고 여기에 EXC_BAD_ACCESS를 제공합니다 해당 코드 행은 나중에 표시됩니다. 나중까지 호출되지 않는 함수에는 프로그램을 손상시키는 코드 행이 있습니다. 행이 실행되기 전에 함수에서 리턴 할 때 프로그램에는이. 제 점이 없지만 행 뒤의 함수에서 리턴해야한다면이. 제 점이 있습니다.라인은 엑스 코드에서 스택 트레이스에 따라, 코드

코드 줄은 OpenCL 호출입니다. 어떻게 든 프로그램을 망가 뜨리고 있습니까?

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 정수 매크로로서 정의되고 PPO_results의 유형 CombinationResult (*) [3] [PPO_COMBINATIONS * 11]이다. ocl_data-> 명령에는 cl_command_queue 유형이 있고 ocl_data-> 출력에는 cl_mem 유형이 있습니다. err, p 및 x는 int 유형입니다.

"Apple LLVM Compiler 3.0"에서 Xcode를 사용하고 있습니다. "LLVM GCC 4.2"컴파일러는 어떤 이유로 "아키텍처 i386에 대한 잘못된 메타 데이터 레코드"를 제공합니다.

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[]) { 

명령 줄에서 직접 실행하면 프로그램이 즉시 종료 : 컴파일하고 gdb를 실행 명령 줄을 사용하는 경우

은 결과입니다.

+3

'gdb'에서 프로그램이 충돌 한 후 'bt'의 결과를 게시 할 수 있습니까? –

+1

예를 들면 다음과 같이 실행하십시오. Valgrind? –

+2

'main'의 두 번째 매개 변수에'const'없이 시도 했습니까? [C99 표준] (http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf)은이를 'char **'일반 ... – pmg

답변

8

좋은 추측을 위해 MrGomez에게 감사 드려요. 그러나 실제 답변은 저를 응시했습니다. 대답은이 웹 사이트의 이름입니다. 문제는 주 함수의 자동 변수가 너무 커서 스택 오버플로가 발생한다는 것입니다. 해결책은 malloc을 사용하여 데이터를 할당하는 것이 었습니다.

Google에서 보는 사람에게 선언 된 변수가 얼마나 큰지 확인하는 것이 좋습니다.런타임에 메모리를 할당 할 수 있습니다.

+0

+1로 정의합니다. 예,이 경우 할당량을 늘리면 문제가 해결됩니다. 분명히 스택 문제 였지만, 그것은 저보다 더 컸습니다. :) – MrGomez

+0

(현상금 기간 동안 그렇게 할 수 있다면 받아 들인 대답을 표시하는 것이 현명 할 수도 있습니다.) 문제의 해결책을 알지 못하는 것 같은 답변을 얻을 수 있습니다. – MrGomez

+0

예, 그렇습니다. 부끄러운 일이 있으면 즉시 자신의 대답을 받아 들일 수 없습니다. –

2

clEnqueueReadBuffervoid* 버퍼 포인터를 통해 (*PPO_results)[x] + PPO_COMBINATIONS*(p + 5)에 글을 쓸 때 스택 손상이 있다고 가정합니다. 정수 매크로 PPO_COMBINATIONS과 포인터 조작 PPO_results의 조합이 결합하여 스택을 다시 가리키고 응용 프로그램의 실행 가능 영역에 예기치 않게 쓸 수 있다고 생각하는 것이 쉽습니다.

통화 지역 주변에 스택이 손상되어 FILE * file = fopen("price.dat", "rb"); 인 경우보고있는 문제가 재현됩니다. 보너스로 이것은 gdb과 같은 일부 도구가 스택 프레임을 제대로 풀어 내지 못하므로 (전체 스택 추적을 금지합니다), 그 시점에서 스택이 손상되어 있고 정상적으로 복구 할 수없는 상태이기 때문입니다.

가장 쉬운 방법은 디버거에서 쓰기 작업을 단계별로 실행하거나 응용 프로그램에서 bounds checker을 실행하는 것입니다. Valgrind has a patch containing this functionality 및 일부는 other tools이이 공간에 OSX 용으로 존재합니다.

신청서를 작성해 주셔서 감사합니다. 버퍼로 안전하게 재생하면 프로그램이 계속 행복해집니다. :)

편집 : 닫기, 그러나 nope.

0

불완전한 코드 포인터를 통한 간접적 인 점프로 인해 호출되지 않는 함수와 같이 코드의 이상한 부분에서 오류가 발생했을 수 있습니다. 이것은 프로그램에서 값으로 볼 수있는 함수 포인터 일 필요는 없습니다. 스택의 손상된 리턴 주소 일 수 있습니다.

이전에 함수 호출 체인에서 사용했던 리턴 주소를 사용하여 시스템이 스스로를 속일 수 있습니다 (스택의 비트와 조각이 여전히 있음).

예. load_pricesfopen이므로 반환 주소를 스택에 넣습니다. 그런 다음 해당 전체 비즈니스가 반환되고 프로그램은 반환 주소가 덮어 쓰이지 않도록 함수의 다른 활성화 체인을 호출합니다. (때로는 함수가 지역 변수를 할당하지만 완전히 초기화하지 않거나 컴파일러가 레지스터 저장 영역과 같은 스크래치 영역을 정렬하지만 항상 사용하지는 않습니다.)

어쨌든 무언가가 엉망이되어 스택이 엉망이됩니다. , 그리고 fopen에 주어진 이전 리턴 주소가 재사용되도록 잘못된 함수 리턴이 실행됩니다. Blam, 두 번째로 fopen에서 돌아 오는 것처럼 load_prices 안에 있습니다 (setjmp/longjmp와 유사).

0

브레이크 변수이 별도의 줄에 코드의 라인과 지정이 : 너무 많은 안전하게 한 줄의 코드로 유지하는 일이 일어나고있다

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); 

.

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 
}