2012-11-16 37 views
8

Tôi gặp sự cố với mã của mình có một số triệu chứng rất lạ.Cùng một mã chương trình với cùng một trình biên dịch dẫn đến các tệp nhị phân khác nhau

  1. Mã này được biên soạn trên máy tính của tôi với các phiên bản sau:

    a. GCC Phiên bản: 4.4.2

    b. CMAKE verson: 2.8.7

    c. QNX (hệ điều hành) phiên bản: 6.5.0

Và mã có segfault trong khi giải phóng một số bộ nhớ và thoát khỏi một chức năng (không chết trên bất kỳ mã, chỉ cần trên lối ra từ một chức năng).

Những điều kỳ lạ về vấn đề này là:

  1. Mã này hiện nó trong chế độ phát hành nhưng không phải chế độ gỡ lỗi:

    a. Mã này được tạo luồng nên điều này cho biết tình trạng chủng tộc.

    b. Tôi không thể gỡ lỗi bằng cách đặt nó trong chế độ gỡ lỗi.

  2. Mã khi được biên dịch trên một máy tính cùng loại với cùng phiên bản của mọi thứ, không gặp sự cố này.

    a. Những điều kỳ lạ về điều này là mã workmates hoạt động, nhưng cũng là nhị phân được tạo ra từ việc biên dịch trên máy tính của anh ta, giống nhau, lớn hơn khoảng 6mB.

Hiện tại, tôi không thể đăng mã vì nó quá lớn và cũng có thể hoạt động. Nhưng bất cứ ai có thể chỉ cho tôi một con đường để sửa lỗi này.

Vì tôi đang sử dụng QNX tôi bị giới hạn cho các công cụ gỡ lỗi của mình, tôi không thể sử dụng Valgrind và vì nó không được hỗ trợ trong QNX, GDB không thực sự hữu ích.

Tôi đang tìm kiếm bất kỳ ai đã gặp phải sự cố tương tự/giống nhau và nguyên nhân là gì và cách họ khắc phục sự cố.

EDIT:

Sooo ... tôi phát hiện ra nó là cái gì, nhưng vẫn im một chút nhầm lẫn về cách nó đã xảy ra.

Mã thủ phạm là thế này:

Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox(); 

nơi định nghĩa cho getMinimumBoundingBox là thế này:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox(); 

và nó trả về một VectorXd mà luôn luôn được khởi tạo như VectorXd output(6, 1). Vì vậy, tôi ngay lập tức nghĩ rằng, phải là vì VectorXd không được khởi tạo, nhưng thay đổi nó thành điều này:

Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox(); 

Nhưng điều này không hiệu quả.Trong thực tế, tôi đã phải sửa chữa nó bằng cách thay đổi định nghĩa của hàm này:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input); 

và cuộc gọi đến này

Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb); 

Vì vậy, bây giờ là câu hỏi mới:

gì Địa ngục? Tại sao không phải là công việc đầu tiên thay đổi nhưng thứ hai đã làm, tại sao tôi phải vượt qua bằng cách tham khảo? Oh và câu hỏi lớn, làm thế nào địa ngục đã không phá vỡ này khi đồng nghiệp của tôi biên soạn nó và tôi chạy nó? Đó là một lỗi bộ nhớ thẳng ra, chắc chắn nó không nên phụ thuộc vào máy tính biên dịch nó, đặc biệt là kể từ khi trình biên dịch và tất cả những điều quan trọng khác là như nhau !! ??

Cảm ơn các bạn đã giúp đỡ.

+2

Âm thanh như vấn đề về bộ nhớ - valgrind trong chế độ gỡ lỗi vẫn đáng để thử - nó sẽ giúp quyết định xem đó có phải là bộ nhớ hay không. – John3136

+2

"1. Mã không ở chế độ phát hành nhưng không phải chế độ gỡ lỗi:" - đó là một dấu hiệu không phổ biến của vấn đề bộ nhớ (do sự khác biệt về dấu chân) –

+0

@ John3136 Thật không may tôi không thể sử dụng valgrind vì tôi đang chạy trên QNX không có hỗ trợ. Tôi có thể thử lấy chức năng ra và vào linux (ubuntu hoặc fedora) nhưng điều đó sẽ mất nhiều thời gian nên tôi muốn thử những thứ khác trước. –

Trả lời

7

... nhị phân được tạo ra từ biên soạn trên máy tính của mình, mà là như nhau, khoảng 6MB lớn

Đó là giá trị tìm ra những gì là sự khác biệt (ngay cả khi nó chỉ là những trường hợp đó mình xây dựng da, trong khi bạn cho thấy, một lỗi thực):

  • kiểm tra bạn đang biên soạn chính xác cùng mã (không có thay đổi địa phương bỏ cam kết, không có tiêu đề phụ trong con đường tìm kiếm bao gồm, vv)
    • kiểm tra ba lần bằng cách thêm một chuyển đổi -E vào các đối số gcc của bạn trong cmake, vì vậy nó sẽ xử lý trước các tệp của bạn với cùng đường dẫn bao gồm biên dịch thông thường; sản lượng diff trước xử lý
  • so sánh sản lượng từ nm hoặc objdump hoặc bất cứ điều gì bạn có để cho hai thực thi liên kết của bạn: nếu một số hệ thống hoặc của bên thứ 3 thư viện là một phiên bản khác nhau trên một hộp, nó có thể hiển thị ở đây
  • so sánh sản lượng từ ldd nếu nó tự động liên kết, chắc chắn rằng họ đang cả hai nhận được các phiên bản cùng một thư viện
    • so sánh các phiên bản thư viện nó thực được trong thời gian chạy quá, nếu có thể.Hy vọng rằng bạn có thể làm một trong số: chạy pldd, so sánh .so mục trong /proc/pid/map, chạy quá trình dưới strace/dtrace/truss và so sánh các hoạt động liên kết lúc chạy

Đối với mã .. . nếu điều này không làm việc:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox(); 
// ... 
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox(); 

và điều này không:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input); 
// ... 
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb); 

bạn có thể gặp sự cố với toán tử gán. Nếu nó có bản sao nông và có bộ nhớ được cấp phát động trong vectơ, bạn sẽ kết thúc với hai vectơ giữ cùng một con trỏ, và cả hai sẽ là free/delete nó.

Lưu ý rằng nếu toán tử không được xác định, thì mặc định là làm bản sao cạn này.

+0

+1 để kiểm tra/phát ra nhiễu. – Macke

+0

Câu trả lời hay, Phần thứ hai giải thích vấn đề với lỗi bộ nhớ. Tôi sẽ xem xét phần đầu tiên và xem những gì tôi tìm thấy. –

0

Bạn nói rằng bạn phải thay đổi từ:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input); 

là gì nó trước?

Nếu nó là:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input); 

và các nhà thầu copy/toán tử gán không được thực hiện đúng cách nó có thể gây ra vấn đề.

Vui lòng kiểm tra xem chúng được triển khai như thế nào. Đây là some info có thể hữu ích.

+0

Nó nói trong câu hỏi nó là gì trước đây. Đây không phải là vấn đề. Cảm ơn sự giúp đỡ của bạn. –

+0

Phải vậy. Bạn đã không làm theo quy tắc của ba. –

+0

@LightnessRacesinOrbit Nope nó không phải, đó không phải là đầu vào trước đây. –

Các vấn đề liên quan