여기 내 로프 끝에 있습니다. 단일 스레드 C++ 프로그램이 있습니다. 다음은 경험적 데이터와 배경 정보입니다. 가장 중요한 키워드를 강조했습니다.단일 스레드 C++ 함수 호출에서 undebuggable non-deterministic heisenbug
- 제가 이야기 전체 섹션 는 (탈) 할당은 표준 C를 호출 ++ 라이브러리가 수행 할 수 메모리 이외의 콜 (
std::set
의 참여입니다)를 가지고 있지 않습니다. 순전히 논리적 인 알고리즘입니다. - 이 의 동작은 입력에 따라 결정적이어야하며, 나는 변하지 않습니다.
- 버그가있는 경우 프로그램은 무한 루프처럼 보이는 데, 바운드를 초과하여 메모리를 할당하는 것 같습니다. .
- 버그 하지 매니페스트 자체가 예측, 나는 때때로 명령 줄에서 프로그램을 실행할 수 있습니다 않습니다 (아마 30 % -50 %) 버그가 자체 명단 그렇지 않으면, 모든 I로까지 원활하고 제대로 실행 말할 수있다.
- 일단 프롬프트에서 직접 실행하지 않고 gdb 또는 valgrind에서 프로그램을 실행하면 버그가 사라집니다., 프로그램이 종료되지 않습니다.
- 이제는 가장 중요한 부분이 있습니다.이 문제는 (템플릿으로 된) 비회원 멤버 함수 호출으로 추적되었습니다. 전화 전에 으로 전화하면
std::cout
으로 메시지가 출력됩니다.이 메시지는 입니다. 터미널에이 있습니다. 첫 번째 라인의에는 디버그 메시지가 있습니다. 을 표시하지 않았습니다.
나는 더 이상 합당한 설명을 볼 수 없다. 어쩌면 진행 방법을 생각해 낼 수 있습니다.
편집 : 우리는 그들과 생략 관련이없는 부분 참조 할 수 있도록 코드의 중요한 라인, 정말 모든 것이 최고의 이해하는 것, 줄 번호를 변경했습니다.
a.cpp
10 std::set<Array const*>* symbols;
11 std::set<Array const*> allSymbols;
12 symbols = &allSymbols;
// ... allSymbols are populated with std::inserter
15 std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
16 senderConstraints = cd.cg.eval(*symbols);
b.cpp
31 template <typename ArrayContainer>
32 ConstraintList eval(ArrayContainer const request) {
33 std::cout << "inside eval ... going to update graph now" << std::endl;
출력의 마지막 줄은 다음과 같습니다
eval; cd = 0x2e6ebb0, cg = 0x2e6ebc0
는 그 다음이 무한 루프에 갇혀.
이것이 정말로 경쟁 조건이 아니라고 확신하는 경우 (효과는 사용자가 묘사 한 것과 똑같이 보입니다), 내 상태를 덤프하여 어떤 상태가 버그 상태가되는지 확인합니다. 일부 잘못된 초기화 순서로 인해 이러한 동작이 발생할 수도 있습니다. –
코드가 도움이됩니다. 그렇지 않으면 아무 것도 말하기가 불가능합니다. 그러나 "버그는 마술처럼 디버거에서 사라졌습니다"는 보통'if (ptr! = NULL) do_something();의 별자리를 가리 킵니다. '및 초기화되지 않은 변수를 포함합니다. 실수로 메모리 위치가 0이면 버그가 발생하지 않으며 그렇지 않은 경우 버그가 발생합니다. 디버거는 ** 모든 ** 변수를 초기화합니다 (그렇지 않은 경우라도). 따라서 버그는 "마술처럼 사라졌습니다". – Damon
['strace'] (http://linux.die.net/man/1/strace)를 사용하여 시스템 호출을 추적 할 수 있습니다 (일부는 시스템 라이브러리 내부에 숨겨져있을 수 있습니다). 또한 디버그 인쇄 ** lot ** **을 추가하는 것이 좋습니다. –