Điều gì có thể gây ra lỗi phân đoạn khi chỉ cần nhập hàm?SIGSEGV khi nhập hàm
Chức năng bước vào trông giống như:
21: void eesu3(Matrix & iQ)
22: {
nơi Matrix
là một struct
. Khi chạy với GDB, backtrace sẽ tạo ra:
(gdb) backtrace
#0 eesu3 (iQ=...) at /home/.../eesu3.cc:22
#1 ...
GDB không nói gì iQ
là. ...
có nghĩa đen ở đó. Điều gì có thể gây ra điều này?
GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Chương trình được xây dựng với -O3 -g
Người gọi đi như thế:
Matrix q;
// do some stuff with q
eesu3(q);
Không có gì đặc biệt ở đây
Tôi đọc lại chương trình với valgrind:
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes <prgname>
Output:
==2240== Warning: client switching stacks? SP change: 0x7fef7ef68 --> 0x7fe5e3000
==2240== to suppress, use: --max-stackframe=10076008 or greater
==2240== Invalid write of size 8
==2240== at 0x14C765B: eesu3(Matrix &) (eesu3.cc:22)
...
==2240== Address 0x7fe5e3fd8 is on thread 1's stack
==2240==
==2240== Can't extend stack to 0x7fe5e2420 during signal delivery for thread 1:
==2240== no stack segment
==2240==
==2240== Process terminating with default action of signal 11 (SIGSEGV)
==2240== Access not within mapped region at address 0x7FE5E2420
==2240== at 0x14C765B: eesu3(Matrix&) (eesu3.cc:22)
==2240== If you believe this happened as a result of a stack
==2240== overflow in your program's main thread (unlikely but
==2240== possible), you can try to increase the size of the
==2240== main thread stack using the --main-stacksize= flag.
==2240== The main thread stack size used in this run was 8388608.
Trông giống như một đống bị hỏng của mình.
Dump of assembler code for function eesu3(Matrix &):
0x00000000014c7640 <+0>: push %rbp
0x00000000014c7641 <+1>: mov %rsp,%rbp
0x00000000014c7644 <+4>: push %r15
0x00000000014c7646 <+6>: push %r14
0x00000000014c7648 <+8>: push %r13
0x00000000014c764a <+10>: push %r12
0x00000000014c764c <+12>: push %rbx
0x00000000014c764d <+13>: and $0xfffffffffffff000,%rsp
0x00000000014c7654 <+20>: sub $0x99b000,%rsp
=> 0x00000000014c765b <+27>: mov %rdi,0xfd8(%rsp)
Được rồi, để làm rõ: Dữ liệu của ma trận sống trên heap. Về cơ bản nó nắm giữ một con trỏ đến dữ liệu. Cấu trúc nhỏ, 32 byte. (Chỉ cần kiểm tra)
Bây giờ, tôi xây dựng lại chương trình với các tùy chọn tối ưu hóa khác nhau:
-O0
: lỗi không hiển thị.
-O1
: lỗi hiển thị.
-O3
: lỗi hiển thị.
--update
-O3 -fno-inline -fno-inline-functions
: lỗi không hiển thị.
Điều đó giải thích điều đó. Quá nhiều nội tuyến vào hàm dẫn đến việc sử dụng chồng quá mức.
Vấn đề là do một stack overflow
Để xem các biến của bạn, v.v. không tối ưu hóa. Biên dịch với '-O0 -g' – RageD
Tham nhũng ngăn xếp? – Benj
Ok, sẽ xây dựng lại bằng '-O0 -g'. Mất một thời gian – ritter