CoderFunda
  • Home
  • About us
    • Contact Us
    • Disclaimer
    • Privacy Policy
    • About us
  • Home
  • Php
  • HTML
  • CSS
  • JavaScript
    • JavaScript
    • Jquery
    • JqueryUI
    • Stock
  • SQL
  • Vue.Js
  • Python
  • Wordpress
  • C++
    • C++
    • C
  • Laravel
    • Laravel
      • Overview
      • Namespaces
      • Middleware
      • Routing
      • Configuration
      • Application Structure
      • Installation
    • Overview
  • DBMS
    • DBMS
      • PL/SQL
      • SQLite
      • MongoDB
      • Cassandra
      • MySQL
      • Oracle
      • CouchDB
      • Neo4j
      • DB2
      • Quiz
    • Overview
  • Entertainment
    • TV Series Update
    • Movie Review
    • Movie Review
  • More
    • Vue. Js
    • Php Question
    • Php Interview Question
    • Laravel Interview Question
    • SQL Interview Question
    • IAS Interview Question
    • PCS Interview Question
    • Technology
    • Other

01 January, 2024

Calling different functions of a DLL from different threads simultaneously segfaults or gives a status_stack_buffer_overrun

 Programing Coderfunda     January 01, 2024     No comments   

I'm writing a library regarding Bridge (the card game), which performs deals generation, performance analysis and other stuff. I'm using Rust and, for some functionalities, I'm leaning on the DLL of a C++ library, called Double Dummy Solver (henceforth DDS - Site, GitHub). I used bindgen to create the bindings for the DLL (I don't know if this is the correct approach: I am not a programmer by trade and I kinda had an hard time wrapping my head around how DLL and FFI works and how to use them in Rust. I'll happily accept advices regarding this.) and everything seemed to work perfectly.


After implementing a parallel function to analyse multiple deals simultaneously (AnalyseAllPlaysBin, link to the docs) and writing a little test for it, cargo test started failing with:


exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN
or with:
exit code: 0xc0000005, STATUS_ACCESS_VIOLATION
note: test exited abnormally; to see the full output pass --nocapture to the harness.
Segmentation fault



I was a bit surprised and I dug a bit to understand the problem. I found out that the reason for the failure was cargo running the tests in parallel, and I think simultaneous calls mess up with the DLL, making it segfault.


Using cargo t -- --test-threads=1 solves the problem, but since I'm writing a library I hope to use for an application in the future, I would like to understand the problem and solve it in some way. I'm not planning to make multiple simultaneous calls to the DLL but the problem still bothers me.

I cannot provide an MWE but I'll give some code for reference:

use dds::{
deal, // The `deal` type the C++ library uses
solvedPlays, // Type of the C++ library
solvedPlay, // Same as above
playTraceBin, // Same as above
playTracesBin, // Same as above
PlayTraceBin, // Cards played for the deal to analyze
PlayTracesBin, // Collection of PlayTraceBin for different deals
SolvedPlays, // My wrapper around the C++ type
SolvedPlay, // Same
RankSeq, // Sequence of the rank (2,3,Q,K,A ecc.) of cards played
RawDDSRef, // Trait (fn get_raw(&self)) for getting a ref to the underlying struct of the Rust wrapper types
RawDDSRefMut, // Same as above, but mut (fn get_raw_mut(&mut self))
AsRawDDS, // Same as above, but not a ref (fn as_raw(self))
SuitSeq, // Sequence of suits of cards played
Target,Mode,Solutions // Parameters used by the DLL
MAXNOOFBOARDS,
};

const TRIES: usize = 200;
const CHUNK_SIZE: i32 = 10;

pub fn initialize_test() -> DealMock {
DealMock {
hands: [
[8712, 256114688, 2199023255552, 2344123606046343168],
[22528, 10485760, 79182017069056, 744219838422974464],
[484, 1612185600, 1924145348608, 4611686018427387904],
[1040, 268435456, 57415122812928, 1522216674051227648],
],
}
}

pub trait PlayAnalyzer {
/// Analyzes a single hand
/// # Errors
/// Will return an Error when DDS fails in some way.
fn analyze_play(
deal: &D,
contract: &C,
play: PlayTraceBin,
) -> Result;
/// Analyzes a bunch of hands in paraller.
/// # Errors
/// Will return an Error when DDS fails in some way or the deals and contracts vecs have
/// different length or their length doe
fn analyze_all_plays(
deals: Vec,
contracts: Vec,
plays: &mut PlayTracesBin,
) -> Result;
}

impl PlayAnalyzer for DDSPlayAnalyzer {
#[inline]
fn analyze_all_plays(
deals: Vec,
contracts: Vec,
plays: &mut PlayTracesBin,
) -> Result {
let deals_len = i32::try_from(deals.len().clamp(0, MAXNOOFBOARDS)).unwrap();
let contracts_len = i32::try_from(contracts.len().clamp(0, MAXNOOFBOARDS)).unwrap();

if deals_len != contracts_len || deals_len == 0 || contracts_len == 0 {
return Err(RETURN_UNKNOWN_FAULT.into()); // The error tells that
// either something went terribly wrong or we used wrongly sized inputs.
}

let mut c_deals: Vec = contracts
.into_iter()
.zip(deals)
.map(|(contract, deal)| construct_dds_deal(contract, deal))
.collect();
c_deals.resize(
MAXNOOFBOARDS,
deal {
trump: -1,
first: -1,
currentTrickSuit: [-1i32; 3],
currentTrickRank: [-1i32; 3],
remainCards: [[0u32; 4]; 4],
},
);
let mut boards = boards {
noOfBoards: deals_len,
// We know vec has the right length
deals: match c_deals.try_into().unwrap(),
target: [Target::MaxTricks.into(); MAXNOOFBOARDS],
solutions: [Solutions::Best.into(); MAXNOOFBOARDS],
mode: [Mode::Auto.into(); MAXNOOFBOARDS],
};
let mut solved_plays = SolvedPlays {
solved_plays: solvedPlays {
noOfBoards: deals_len,
solved: [solvedPlay::new(); MAXNOOFBOARDS],
},
};

let bop: *mut boards = &mut boards;
let solved: *mut solvedPlays = solved_plays.get_raw_mut();
let play_trace: *mut playTracesBin = (*plays).get_raw_mut();

// SAFETY: calling C
let result = unsafe { AnalyseAllPlaysBin(bop, play_trace, solved, CHUNK_SIZE) };
match result {
// RETURN_NO_FAULT == 1i32
1i32 => Ok(solved_plays),
n => Err(n.into()),
}
}

#[inline]
fn analyze_play(
deal: &D,
contract: &C,
play: PlayTraceBin,
) -> Result {
let c_deal = construct_dds_deal(contract, deal);
let mut solved_play = SolvedPlay::new();
let solved: *mut solvedPlay = &mut solved_play.solved_play;
let play_trace = play.as_raw();
// SAFETY: calling an external C function
let result = unsafe { AnalysePlayBin(c_deal, play_trace, solved, 0) };
match result {
1i32 => Ok(solved_play),
n => Err(n.into()),
}
}
}

/// Constructs a DDS deal from a DDS contract and a DDS deal representation
fn construct_dds_deal(contract: &C, deal: &D) -> deal {
let (trump, first) = contract.as_dds_contract();
deal {
trump,
first,
currentTrickSuit: [0i32; 3],
currentTrickRank: [0i32; 3],
remainCards: deal.as_dds_deal().as_slice(),
}
}

#[test]
fn analyse_play_test() {
let deal = initialize_test();
let contract = ContractMock {};
let suitseq = SuitSeq::try_from([0i32, 0i32, 0i32, 0i32]).unwrap();
let rankseq = RankSeq::try_from([4i32, 3i32, 12i32, 2i32]).unwrap();
let play = PlayTraceBin::new(suitseq, rankseq);
let solvedplay = DDSPlayAnalyzer::analyze_play(&deal, &contract, play).unwrap();
assert_eq!([2, 2, 2, 2, 2], solvedplay.solved_play.tricks[..5]);
}

#[test]
fn analyse_all_play_test() {
let mut deals_owner = Vec::with_capacity(TRIES);
deals_owner.resize_with(TRIES, initialize_test);
let deals = deals_owner.iter().collect();
let suitseq = SuitSeq::try_from([0, 0, 0, 0]).unwrap();
let rankseq = RankSeq::try_from([4, 3, 12, 2]).unwrap();
let mut suitseqs = Vec::with_capacity(TRIES);
let mut rankseqs = Vec::with_capacity(TRIES);
suitseqs.resize_with(TRIES, || suitseq.clone());
rankseqs.resize_with(TRIES, || rankseq.clone());
let contracts_owner = Vec::from([ContractMock {}; TRIES]);
let contracts = contracts_owner.iter().collect();
let mut plays = PlayTracesBin::from_sequences(suitseqs, rankseqs).unwrap();
let solved_plays = DDSPlayAnalyzer::analyze_all_plays(deals, contracts, &mut plays).unwrap();
let real_plays = solved_plays.get_raw();
assert_eq!(TRIES, real_plays.noOfBoards.try_into().unwrap());
for plays in real_plays.solved {
assert_eq!([2, 2, 2, 2, 2], plays.tricks[..5]);
}
}




I could wrap the DDSAnalyzer in an Arc and then lock it for the duration of the external function call. I think this should work (didn't have time to try it) but I don't know if it is the correct approach.


I would like to ask two things:



* Why I get those errors in a multithreaded situation?

* Would using a Arc work? Is it the correct solution or should I do something different?






Thanks to everyone!
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Email ThisBlogThis!Share to XShare to Facebook
Newer Post Older Post Home

0 comments:

Post a Comment

Thanks

Meta

Popular Posts

  • Generate Migrations from an Existing Database With the Migration Generator Package
    Laravel Migration Generator Migration Generator for Laravel is a package by Bennett Treptow to generate migrations from existing database ...
  • 'Ramayana' to have 'Baahubali'-style cliffhanger ending
    image/jpeg https://timesofindia.indiatimes.com/entertainment/hindi/bollywood/news/ramayana-to-end-on-baahubali-style-cliffhanger-director-ni...
  • Vijay talks about being harassed in an uncomfortable encounter with a model coordinator
    image/jpeg https://timesofindia.indiatimes.com/entertainment/hindi/bollywood/news/he-was-getting-touchy-feely-vijay-varma-opens-up-about-bei...
  • 'Spider-Man: Brand New Day' eyes Rs 250 crore net; beats Endgame
    image/jpeg https://timesofindia.indiatimes.com/entertainment/english/hollywood/news/spider-man-brand-new-day-eyes-rs-250-crore-net-in-india-...
  • SRK's King eyes record-breaking Rs 50 crore music rights deal
    image/jpeg https://timesofindia.indiatimes.com/entertainment/hindi/bollywood/news/shah-rukh-khans-king-eyes-record-breaking-rs-50-crore-musi...

Categories

  • Ajax (26)
  • Bootstrap (30)
  • DBMS (42)
  • HTML (12)
  • HTML5 (45)
  • JavaScript (10)
  • Jquery (34)
  • Jquery UI (2)
  • JqueryUI (32)
  • Laravel (1018)
  • Laravel Tutorials (23)
  • Laravel-Question (6)
  • Magento (9)
  • Magento 2 (95)
  • MariaDB (1)
  • MySql Tutorial (2)
  • PHP-Interview-Questions (3)
  • Php Question (13)
  • Python (36)
  • RDBMS (13)
  • SQL Tutorial (79)
  • Vue.js Tutorial (69)
  • Wordpress (150)
  • Wordpress Theme (3)
  • codeigniter (108)
  • oops (4)
  • php (853)

Social Media Links

  • Follow on Twitter
  • Like on Facebook
  • Subscribe on Youtube
  • Follow on Instagram

Pages

  • Home
  • Contact Us
  • Privacy Policy
  • About us

Blog Archive

  • ►  2026 (118)
    • ►  08/16 - 08/23 (1)
    • ►  08/02 - 08/09 (8)
    • ►  07/26 - 08/02 (108)
    • ►  06/28 - 07/05 (1)
  • ►  2025 (4)
    • ►  07/06 - 07/13 (2)
    • ►  06/29 - 07/06 (2)
  • ►  2024 (486)
    • ►  09/15 - 09/22 (30)
    • ►  09/08 - 09/15 (35)
    • ►  09/01 - 09/08 (35)
    • ►  08/11 - 08/18 (2)
    • ►  08/04 - 08/11 (33)
    • ►  07/28 - 08/04 (30)
    • ►  07/07 - 07/14 (11)
    • ►  06/30 - 07/07 (35)
    • ►  06/23 - 06/30 (5)
    • ►  06/02 - 06/09 (31)
    • ►  05/26 - 06/02 (20)
    • ►  05/05 - 05/12 (29)
    • ►  04/28 - 05/05 (26)
    • ►  04/07 - 04/14 (10)
    • ►  03/31 - 04/07 (34)
    • ►  03/24 - 03/31 (10)
    • ►  03/03 - 03/10 (35)
    • ►  02/25 - 03/03 (15)
    • ►  02/04 - 02/11 (22)
    • ►  01/28 - 02/04 (30)
    • ►  01/07 - 01/14 (8)
  • ▼  2023 (484)
    • ▼  12/31 - 01/07 (35)
      • Access denied error using move-item to recursively...
      • Triangular linear system with triangular right han...
      • Laravel Wallet
      • Z-Function. String algorithms. Optimize for large ...
      • I have a _ctx.product is undefined
      • I'm getting an unexpected Tensorflow ResourceExhau...
      • Get parameters for currently running queries in Po...
      • Alpine adds a new build to work with Content Secur...
      • Integrating Cloudflare R2 with Laravel
      • Localhost for Mail server?
      • Syntax error in the code creating a PostgreSQL pro...
      • R: Pattern matching one column to a json string st...
      • Use Model shouldBeStrict when starting a new Larav...
      • Advanced Laravel Repository
      • Generate PDFs in Laravel from Blade Views
      • DataSnap - how to change SELECT query to show diff...
      • Is there any way to observe all data attributes in...
      • How to remove specific characters from select colu...
      • Laravel SQS DLQ
      • How to fill out existing PDF?
      • How to fetch data server-side in the latest Next.j...
      • Prevent default (ionChange) ion-checkbox
      • Easily create PDFs in Laravel apps
      • Any good AI tools that stay up-to-date with the la...
      • Add Primevue Theme To Laravel InertiaJs
      • issue inserting data to joining table of many to m...
      • Compression of randomly ordered non-repeating incr...
      • Does a timer-triggered Azure function execute if a...
      • Calling different functions of a DLL from differen...
      • Weekly /r/Laravel Help Thread
      • change inija2 template file with jquery or javascript
      • How do I scroll an element to a specific height of...
      • Why is the tag deprecated in HTML?
      • Firebase passwordless sign-in to be only allowed f...
      • Unleash the Power of Random Scheduling in Laravel ...
    • ►  12/24 - 12/31 (10)
    • ►  12/03 - 12/10 (33)
    • ►  11/26 - 12/03 (20)
    • ►  11/05 - 11/12 (35)
    • ►  10/29 - 11/05 (20)
    • ►  10/22 - 10/29 (9)
    • ►  10/15 - 10/22 (7)
    • ►  10/08 - 10/15 (9)
    • ►  10/01 - 10/08 (10)
    • ►  09/24 - 10/01 (9)
    • ►  09/17 - 09/24 (9)
    • ►  09/10 - 09/17 (7)
    • ►  09/03 - 09/10 (9)
    • ►  08/27 - 09/03 (9)
    • ►  08/20 - 08/27 (8)
    • ►  08/13 - 08/20 (8)
    • ►  08/06 - 08/13 (8)
    • ►  07/30 - 08/06 (8)
    • ►  07/23 - 07/30 (7)
    • ►  07/16 - 07/23 (8)
    • ►  07/09 - 07/16 (7)
    • ►  07/02 - 07/09 (8)
    • ►  06/25 - 07/02 (7)
    • ►  06/18 - 06/25 (7)
    • ►  06/11 - 06/18 (7)
    • ►  06/04 - 06/11 (11)
    • ►  05/28 - 06/04 (7)
    • ►  05/21 - 05/28 (8)
    • ►  05/14 - 05/21 (11)
    • ►  05/07 - 05/14 (7)
    • ►  04/30 - 05/07 (7)
    • ►  04/23 - 04/30 (8)
    • ►  04/16 - 04/23 (9)
    • ►  04/09 - 04/16 (7)
    • ►  04/02 - 04/09 (4)
    • ►  03/26 - 04/02 (21)
    • ►  03/19 - 03/26 (2)
    • ►  03/12 - 03/19 (9)
    • ►  03/05 - 03/12 (26)
    • ►  02/26 - 03/05 (25)
    • ►  01/15 - 01/22 (7)
    • ►  01/08 - 01/15 (1)
  • ►  2022 (1037)
    • ►  12/11 - 12/18 (13)
    • ►  12/04 - 12/11 (1)
    • ►  11/27 - 12/04 (40)
    • ►  11/06 - 11/13 (1)
    • ►  10/16 - 10/23 (13)
    • ►  09/04 - 09/11 (5)
    • ►  08/21 - 08/28 (24)
    • ►  08/14 - 08/21 (24)
    • ►  07/03 - 07/10 (9)
    • ►  06/19 - 06/26 (3)
    • ►  05/29 - 06/05 (3)
    • ►  05/22 - 05/29 (3)
    • ►  05/15 - 05/22 (109)
    • ►  05/01 - 05/08 (7)
    • ►  04/24 - 05/01 (7)
    • ►  04/17 - 04/24 (64)
    • ►  04/10 - 04/17 (115)
    • ►  04/03 - 04/10 (73)
    • ►  03/27 - 04/03 (77)
    • ►  03/13 - 03/20 (2)
    • ►  03/06 - 03/13 (25)
    • ►  02/27 - 03/06 (18)
    • ►  02/20 - 02/27 (153)
    • ►  02/13 - 02/20 (187)
    • ►  01/30 - 02/06 (45)
    • ►  01/23 - 01/30 (15)
    • ►  01/16 - 01/23 (1)
  • ►  2021 (412)
    • ►  10/24 - 10/31 (2)
    • ►  07/25 - 08/01 (1)
    • ►  07/11 - 07/18 (10)
    • ►  06/13 - 06/20 (29)
    • ►  05/23 - 05/30 (1)
    • ►  05/02 - 05/09 (24)
    • ►  04/25 - 05/02 (24)
    • ►  04/18 - 04/25 (112)
    • ►  04/11 - 04/18 (1)
    • ►  04/04 - 04/11 (6)
    • ►  03/28 - 04/04 (86)
    • ►  03/21 - 03/28 (19)
    • ►  03/14 - 03/21 (2)
    • ►  03/07 - 03/14 (10)
    • ►  02/28 - 03/07 (1)
    • ►  02/21 - 02/28 (29)
    • ►  02/14 - 02/21 (13)
    • ►  02/07 - 02/14 (12)
    • ►  01/31 - 02/07 (6)
    • ►  01/17 - 01/24 (2)
    • ►  01/10 - 01/17 (8)
    • ►  01/03 - 01/10 (14)
  • ►  2020 (376)
    • ►  12/27 - 01/03 (37)
    • ►  12/20 - 12/27 (92)
    • ►  12/13 - 12/20 (29)
    • ►  12/06 - 12/13 (37)
    • ►  11/29 - 12/06 (4)
    • ►  11/15 - 11/22 (14)
    • ►  11/08 - 11/15 (8)
    • ►  11/01 - 11/08 (2)
    • ►  10/18 - 10/25 (14)
    • ►  10/11 - 10/18 (16)
    • ►  10/04 - 10/11 (10)
    • ►  09/20 - 09/27 (10)
    • ►  09/06 - 09/13 (19)
    • ►  08/30 - 09/06 (26)
    • ►  08/23 - 08/30 (4)
    • ►  08/16 - 08/23 (2)
    • ►  07/12 - 07/19 (48)
    • ►  05/17 - 05/24 (2)
    • ►  01/05 - 01/12 (2)
  • ►  2019 (74)
    • ►  07/07 - 07/14 (6)
    • ►  06/16 - 06/23 (6)
    • ►  02/10 - 02/17 (17)
    • ►  01/13 - 01/20 (37)
    • ►  01/06 - 01/13 (8)
  • ►  2018 (376)
    • ►  12/30 - 01/06 (24)
    • ►  12/16 - 12/23 (8)
    • ►  12/09 - 12/16 (98)
    • ►  12/02 - 12/09 (16)
    • ►  11/18 - 11/25 (36)
    • ►  11/04 - 11/11 (18)
    • ►  10/28 - 11/04 (10)
    • ►  10/21 - 10/28 (26)
    • ►  10/14 - 10/21 (52)
    • ►  10/07 - 10/14 (4)
    • ►  09/30 - 10/07 (2)
    • ►  09/23 - 09/30 (68)
    • ►  09/16 - 09/23 (4)
    • ►  09/09 - 09/16 (4)
    • ►  08/26 - 09/02 (6)

Data Publish News

Loading...

Al Jazeera – Breaking News, World News and Video from Al Jazeera

Loading...

Laravel News

Loading...

Copyright © CoderFunda | Powered by Blogger
Design by Coderfunda | Blogger Theme by Coderfunda | Distributed By Coderfunda