Tiến trình bị treo khi gọi hàm function() trong linux

Xin phép mọi người.

Em đang làm 1 project trên linux , trong đó sẽ gọi hàm system() trong code c để thực hiện 1 command ở ngoài.

Vấn đề là khi chương trình chạy tới hàm system() thì hàm này bị treo khiến chương trình bị crash như hình . Ngay cả khi em kill process của chương trình gốc đi thì process của system() vẫn còn.

Em xin lỗi nếu đặt vấn đề sơ sài, nhưng có ai đã từng gặp tình trạng hàm system() bị treo như vậy, hoặc có hướng giải quyết nào đó khả thi có thể giúp em được không ạ.

Bạn không nói rõ chương trình bạn chạy là chương trình nào, bạn có thử gõ lệnh trên Terminal để nó chạy và quan sát trước khi gọi bằng C hay không? Có những chương trình dạng daemon, service khi chạy xong nó nằm ở đó và crash không phải ngay lúc gõ lệnh xong mà khi gặp phải điều kiện/ tình huống nào đó.

Túm lại: phải tìm hiểu nguyên nhân gây crash, đọc log xem có manh mối gì không, mình không nghĩ ở đây chương trình C của bạn gây vấn đề. Về lý thuyết, gọi hàm system trong C chỉ đơn giản là thay vì mình gõ lệnh ở Terminal, thì C làm giúp mà thôi nếu ta không định dùng C để chọc ngoáy gì vào ứng dụng được gọi. Cũng có thể dùng C để gọi vài ứng dụng khác chạy xem có crash hay không để phần nào giúp tìm được nguyên nhân.

3 Likes

Trong hình của cậu chỉ show các process đang chạy thôi, có liên quan tới app crash đâu cậu? :smile:
Ngoài ra:

  • ovs là gì thế cậu? Nó liên quan gì tới vấn đề của cậu?
  • Cậu gọi command để chạy script ovs-otctl à?
  • Cậu cho bọn tớ xem đoạn code cậu gọi script được không? Cậu gọi script cùng process hay ở 1 thread nào khác?
  • Cuối cùng thì chương trình của cậu bị hang (treo) hay bị crash vậy? :smile:
3 Likes
  1. OVS là chương trình để tạo ra switch ảo trên linux, mình nghĩ nói cụ thể khá dài nên mình không thêm vào
  2. Đúng r b à
  3. Mình có để code trong câu hỏi trên stack overflow
  4. Nó bị treo bạn ạ

viết bash script cho chạy ovs trước khi chạy chương trình này ko được à :thinking:

3 Likes

Mình muốn có 1 trigger cụ thể trong OVS thì mới gọi system để chạy command này, còn mình cũng thử vài cách như tạo process con cho system(), hoặc viết command ra bash script rồi gọi file bash này nhưng đều bị treo.

Ở reply trước mình đã lờ mờ đoán (“chọc ngoáy gì vào ứng dụng”), và đúng là hóa ra là bạn viết thêm đoạn code của bạn vào mã nguồn Open vSwitch. Điều này khác hoàn toàn với việc viết mã nguồn C, compile rồi gọi chương trình bên ngoài chạy, vì có khả năng code của bạn gây bug khiến hỏng phần mềm kia.

Vậy cho nên, khuyên bạn tham gia vào https://docs.openvswitch.org/en/latest/internals/mailing-lists/ để hỏi nhé, bởi vì bây giờ bạn đã tham gia vào cộng đồng người dùng/ phát triển cái phần mềm chuyên biệt này rồi, không còn là câu hỏi chung nữa. Ở Dạy Nhau Học có rất ít người dùng Open vSwitch, đợi được người dùng Open vSwitch đọc thấy, trả lời cho bạn có khi mất hàng tháng, hàng năm. Ngay cả trên StackOverfollow họ cũng thấy bối rối vì chắc cũng chưa thử chọc vào mã nguồn Open vSwitch như bạn.

5 Likes

Nó nên bị treo cậu ạ @@

Trong code của cậu, cậu không spawn bất cứ thread hay subprocess nào để thực thi. Lệnh system của cậu sẽ khiến cho chương trình C của cậu bị hang cho tới khi câu lệnh bên kia được thực hiện thành công. Vì cậu nói đó là câu lệnh nhận add flow, tớ nghĩ câu lệnh đó tốn thời gian thực hiện, và khiến cho chương trình của cậu bị hang sau đó.
Ngoài ra, common implementation của 1 phần mềm có “add flow” như ovs là lưu dữ liệu đó vào file. Rất dễ để cậu gặp vấn đề khi sử dụng 2 process mở và ghi vào chung 1 file config. Đó có thể là nguyên nhân khiến process bị hang (đây là phán đoán thôi nha, cậu cần đọc code để hiểu chính xác hơn).

Thử thêm & đằng sau command của cậu như này xem:

snprintf(bar1, sizeof(bar1), "ovs-ofctl add-flow s1 priority=5,tcp,in_port=\"%s\",eth_src=%s,eth_dst=%s,  ipv4_src=%s,ipv4_dst=%s,tcp_src=%u,tcp_dst=%u,action=output:\"%s\" &"
                 ,in ,sMAC ,dMAC, sIP, dIP, sPort, dPort, out); // pass agr to cmd

Thêm & sẽ làm cho câu lệnh kia được thực hiện ở background. Tất nhiên, cậu sẽ cần bỏ đoạn in log ra, và gộp nó vào câu lệnh mà cậu muốn gọi từ hàm system kia.

Và đồng thời, tớ recommend cậu tìm hiểu kỹ add flow ở script ovsctl làm gì. Thử đọc script hay đoạn code đó, vì có khả năng cậu đang sửa code để gọi tới 1 script, mà script đó gọi lại một hàm trong code cậu đang sửa. Điều này khiến việc gọi system trở nên thừa thãi (gọi system như cậu đang làm không phải cách tiêu chuẩn, hay nói cách khác, cậu đang hack để làm điều cậu muốn).

Nếu vẫn gặp vấn đề, cậu nên chuẩn bị minimal reproducible example. Nó sẽ giúp mọi người điều tra vấn đề của cậu nhanh hơn.

5 Likes

Cảm ơn vì câu trả lời chi tiết của bạn. Mình cũng nghi ngờ từ đầu vấn đề đến từ việc cả 2 process cùng ghi chung vào 1 vùng nhớ vì trong struct lưu trữ flow có đề cập đến việc nó được bảo vệ bằng RCU lock. Mình trình bày với trường nhóm nhưng anh đó không đồng ý. Có lẽ mình sẽ tìm cách giải quyết theo hướng khác.

1 Like

Đó có vẻ là suy đoán tốt, nhưng để trình bày với trưởng nhóm được, cậu phải tìm cách chứng minh trước. Nếu không, không ai đồng ý được đâu :smile:

Dù cách khác có là gì, tớ cũng khuyên cậu nên đọc kỹ ovs-ofctl trước, và hiểu add-flow thực sự làm gì. Nếu không làm được điều đó, cậu sẽ rất tốn thời gian để try-and-error (tốn hơn nhiều việc phân tích mã nguồn và thiết kế cách giải quyết).

Hope it helps!

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?