Identified root cause of SocketBox bug - local variable clone issue

Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-08-14 07:51:06 +00:00
parent 1bcd425edb
commit 5730d2fa0f
2 changed files with 50 additions and 6 deletions

View File

@ -56,25 +56,34 @@ pub struct SocketBox {
impl Clone for SocketBox { impl Clone for SocketBox {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { let cloned = Self {
base: BoxBase::new(), // New unique ID for clone base: BoxBase::new(), // New unique ID for clone
listener: Arc::clone(&self.listener), listener: Arc::clone(&self.listener),
stream: Arc::clone(&self.stream), stream: Arc::clone(&self.stream),
is_server: Arc::clone(&self.is_server), is_server: Arc::clone(&self.is_server),
is_connected: Arc::clone(&self.is_connected), is_connected: Arc::clone(&self.is_connected),
} };
let original_arc_ptr = Arc::as_ptr(&self.is_server) as usize;
let cloned_arc_ptr = Arc::as_ptr(&cloned.is_server) as usize;
let is_server_value = *self.is_server.lock().unwrap();
println!("🔄 SocketBox::clone() - original Box ID: {}, cloned Box ID: {}, Arc ptr: {:x} -> {:x}, is_server: {}",
self.base.id, cloned.base.id, original_arc_ptr, cloned_arc_ptr, is_server_value);
cloned
} }
} }
impl SocketBox { impl SocketBox {
pub fn new() -> Self { pub fn new() -> Self {
Self { let instance = Self {
base: BoxBase::new(), base: BoxBase::new(),
listener: Arc::new(Mutex::new(None)), listener: Arc::new(Mutex::new(None)),
stream: Arc::new(Mutex::new(None)), stream: Arc::new(Mutex::new(None)),
is_server: Arc::new(Mutex::new(false)), is_server: Arc::new(Mutex::new(false)),
is_connected: Arc::new(Mutex::new(false)), is_connected: Arc::new(Mutex::new(false)),
} };
let arc_ptr = Arc::as_ptr(&instance.is_server) as usize;
println!("🔧 SocketBox::new() - created (Box ID: {}, Arc ptr: {:x})", instance.base.id, arc_ptr);
instance
} }
/// TCP ソケットをアドレス・ポートにバインド /// TCP ソケットをアドレス・ポートにバインド
@ -83,22 +92,31 @@ impl SocketBox {
let port_str = port.to_string_box().value; let port_str = port.to_string_box().value;
let socket_addr = format!("{}:{}", addr_str, port_str); let socket_addr = format!("{}:{}", addr_str, port_str);
println!("🔍 SocketBox::bind() called with address: {} (Box ID: {})", socket_addr, self.base.id);
match TcpListener::bind(&socket_addr) { match TcpListener::bind(&socket_addr) {
Ok(listener) => { Ok(listener) => {
println!("✅ SocketBox::bind() - TcpListener created successfully (Box ID: {})", self.base.id);
match self.listener.lock() { match self.listener.lock() {
Ok(mut listener_guard) => { Ok(mut listener_guard) => {
*listener_guard = Some(listener); *listener_guard = Some(listener);
println!("✅ SocketBox::bind() - Listener stored successfully (Box ID: {})", self.base.id);
}, },
Err(_) => { Err(_) => {
println!("🚨 SocketBox::bind() - Failed to acquire listener lock (Box ID: {})", self.base.id);
return Box::new(BoolBox::new(false)); return Box::new(BoolBox::new(false));
} }
} }
match self.is_server.lock() { match self.is_server.lock() {
Ok(mut is_server_guard) => { Ok(mut is_server_guard) => {
*is_server_guard = true; *is_server_guard = true;
let arc_ptr = Arc::as_ptr(&self.is_server) as usize;
// Verify the value was actually set
let verify_value = *is_server_guard;
println!("✅ SocketBox::bind() - is_server set to true (Box ID: {}, Arc ptr: {:x}, verify: {})", self.base.id, arc_ptr, verify_value);
}, },
Err(_) => { Err(_) => {
println!("🚨 SocketBox::bind() - Failed to acquire is_server lock (Box ID: {})", self.base.id);
// Non-critical error, continue // Non-critical error, continue
} }
} }
@ -114,26 +132,36 @@ impl SocketBox {
/// 指定した backlog で接続待機開始 /// 指定した backlog で接続待機開始
pub fn listen(&self, backlog: Box<dyn NyashBox>) -> Box<dyn NyashBox> { pub fn listen(&self, backlog: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let _backlog_num = backlog.to_string_box().value.parse::<i32>().unwrap_or(128); let _backlog_num = backlog.to_string_box().value.parse::<i32>().unwrap_or(128);
println!("🔍 SocketBox::listen() called (Box ID: {})", self.base.id);
// Check if listener exists and is properly bound // Check if listener exists and is properly bound
let listener_guard = match self.listener.lock() { let listener_guard = match self.listener.lock() {
Ok(guard) => guard, Ok(guard) => guard,
Err(_) => return Box::new(BoolBox::new(false)), Err(_) => {
println!("🚨 SocketBox::listen() - Failed to acquire listener lock (Box ID: {})", self.base.id);
return Box::new(BoolBox::new(false));
},
}; };
if let Some(ref listener) = *listener_guard { if let Some(ref listener) = *listener_guard {
println!("✅ SocketBox::listen() - Listener found (Box ID: {})", self.base.id);
let arc_ptr = Arc::as_ptr(&self.is_server) as usize;
println!("🔍 SocketBox::listen() - Arc ptr: {:x}", arc_ptr);
// Try to get the local address to confirm the listener is working // Try to get the local address to confirm the listener is working
match listener.local_addr() { match listener.local_addr() {
Ok(_addr) => { Ok(_addr) => {
println!("✅ SocketBox::listen() - Listener is valid (Box ID: {})", self.base.id);
// Listener is properly set up and can accept connections // Listener is properly set up and can accept connections
Box::new(BoolBox::new(true)) Box::new(BoolBox::new(true))
}, },
Err(_) => { Err(_) => {
println!("🚨 SocketBox::listen() - Listener exists but has issues (Box ID: {})", self.base.id);
// Listener exists but has issues // Listener exists but has issues
Box::new(BoolBox::new(false)) Box::new(BoolBox::new(false))
} }
} }
} else { } else {
println!("🚨 SocketBox::listen() - No listener bound (Box ID: {})", self.base.id);
// No listener bound - this is expected behavior for now // No listener bound - this is expected behavior for now
// HTTPServerBox will handle binding separately // HTTPServerBox will handle binding separately
Box::new(BoolBox::new(false)) Box::new(BoolBox::new(false))
@ -314,7 +342,11 @@ impl SocketBox {
/// サーバーモード確認 /// サーバーモード確認
pub fn is_server(&self) -> Box<dyn NyashBox> { pub fn is_server(&self) -> Box<dyn NyashBox> {
Box::new(BoolBox::new(*self.is_server.lock().unwrap())) let is_server_value = *self.is_server.lock().unwrap();
let arc_ptr = Arc::as_ptr(&self.is_server) as usize;
println!("🔍 SocketBox::is_server() called - returning {} (Box ID: {}, Arc ptr: {:x})",
is_server_value, self.base.id, arc_ptr);
Box::new(BoolBox::new(is_server_value))
} }
} }

View File

@ -328,6 +328,18 @@ impl NyashInterpreter {
// オブジェクトを評価(通常のメソッド呼び出し) // オブジェクトを評価(通常のメソッド呼び出し)
let obj_value = self.execute_expression(object)?; let obj_value = self.execute_expression(object)?;
// Debug: Print object type and Box ID for SocketBox debugging
if method == "bind" || method == "listen" || method == "isServer" {
println!("🔍 DEBUG: Method '{}' called on object type: {} (Box ID: {})",
method,
obj_value.type_name(),
if let Some(socket_box) = obj_value.as_any().downcast_ref::<SocketBox>() {
socket_box.box_id().to_string()
} else {
"N/A".to_string()
});
}
// StringBox method calls // StringBox method calls
if let Some(string_box) = obj_value.as_any().downcast_ref::<StringBox>() { if let Some(string_box) = obj_value.as_any().downcast_ref::<StringBox>() {
return self.execute_string_method(string_box, method, arguments); return self.execute_string_method(string_box, method, arguments);