2016-09-08 5 views
0

이 질문에 대한 접근법은 이미 있습니다. ¹² ³std :: flush가 없으면 분할 오류가 발생합니다.

하지만 이것은 완전히 다릅니다! std::flush 행을 주석 처리하면 Segfault가 발생하지만이 행을 추가하면 Segmentation 오류가 발생하지 않습니다!

int Stm32Serial::writeToSerial() 
{ 
    /// TODO Write handle for writing if necessary 
    /// int serial_write_ret; 
    if (USE_USB) 
    { 
     usb_port.writeBytes (stm_buf_t, stm_buf_t[LENGTH_INDEX]); 
     return SERIAL_RET; 
    } 
    else 
    { 
     std::cout << std::flush; // TODO HACK Remove it! 
     serial_port.sendBuff (stm_buf_t, stm_buf_t[LENGTH_INDEX]); 
     return SERIAL_RET; 
    } 
} 

도 시도했습니다 gdb; 내가 this 디버그 기술과 compiling with -g optionROS에서이 기능을 사용하고 있지만 LENGTH_INDEXstm_buf_t[]에 대한 보았다 함수 이름

Program received signal SIGSEGV, Segmentation fault. 
__mempcpy_sse2() at ../sysdeps/x86_64/memcpy.S:142 
142 ../sysdeps/x86_64/memcpy.S: No such file or directory. 
(gdb) bt 
#0 __mempcpy_sse2() at ../sysdeps/x86_64/memcpy.S:142 
#1 0x6564656563786520 in ??() 
#2 0x20726f7272652064 in ??() 
#3 0x6c6f687365726874 in ??() 
#4 0x2e30203a79622064 in ??() 
#5 0x202c323537373431 in ??() 
#6 0x697420656c637963 in ??() 
#7 0x36312e30203a656d in ??() 
#8 0x2c31343936373632 in ??() 
#9 0x6f68736572687420 in ??() 
#10 0x32302e30203a646c in ??() 
#11 0x742064616572202c in ??() 
#12 0x312e30203a656d69 in ??() 
#13 0x3530333430353233 in ??() 
#14 0x657461647075202c in ??() 
#15 0x30203a656d697420 in ??() 
#16 0x373430353233312e in ??() 
#17 0x74697277202c3234 in ??() 
#18 0x203a656d69742065 in ??() 
#19 0x3637363236312e30 in ??() 
#20 0x006d305b1b333637 in ??() 
#21 0x00007fffffffbbf0 in ??() 
#22 0x00000000ffffbbd8 in ??() 
---Type <return> to continue, or q <return> to quit--- 
#23 0x00007fff00000000 in ??() 
#24 0x0000000000000000 in ??() 
(gdb) 
  • 를 인쇄하지 않고, 확인이 있습니다.

그리고 또한; 이 함수를 호출 한 다른 곳에서 std::cout << std::flush;을 호출하면 Segfault도 처리됩니다!

... 
genSum (stm_buf_t); 
writeToSerial(); 
std::cout << std::flush; 
... 

내 다음 접근 방법은 무엇입니까?

+2

안녕하세요 @Orhan G. Hafif, 메모리 디버거 (예 : valgrind)를 사용해 보셨습니까? – vadikrobot

+0

안녕하세요 @vadikrobot, 난 그냥 시도하고 몇 가지 귀중한 출력을 보았다. 나는 나중에 그것에 관해 쓸 것이다. 감사! 나는 –

답변

3

숙련 된 괴짜는 스택이 ASCII로 가득하다는 것을 알게됩니다. 이것은 거의 항상 strcpy 나 로컬 변수의 버퍼 오버 플로우를 나타내는 기호입니다.

스택 주소 중 일부를 16 진수에서 ASCII로 변환했습니다. 거꾸로 읽는 것 같습니다.

rorre dedeecxe rorre dlohserht.0 : YB D의 257741it elcyc61.0 : EM, 1496762ohserht 20.0 : DLT의 daer 1.0 : emi50340523etadpu 0 : 첫 번째 비트가 '임계 오류가 오류를 초과 "라고하는 표시

출사 . 이 텍스트의 코드 또는 입력 파일을 살펴보고 코드에서이 텍스트가 사용 된 위치를 확인하십시오. 로컬 버퍼를 덮어 쓰는 메모리 복사본이 거의 확실합니다.

의견에 언급했듯이 Valgrind는 종종 이런 종류의 문제를 발견하게됩니다.

관련 문제