andreykaipov / goobs

Go client library for OBS Studio
Apache License 2.0
117 stars 21 forks source link

goobs has a 1,27% chance to crash OBS while connecting on Windows #130

Closed Gambloide closed 5 months ago

Gambloide commented 5 months ago

Problem Even the basic goobs example crashes OBS on Windows from time to time. While the example given below seems extreme, since it connects so quickly, I have only resorted to this because goobs has been crashing my OBS while streaming repeatedly just when I restarted an application using goobs that only connects and then sends one request per second.

Steps to Reproduce Run this:

package main

import (
    "log"

    "github.com/andreykaipov/goobs"
)

func main() {
    counter := 1
    for {
        log.Println(counter)
        client, err := goobs.New("localhost:4455", goobs.WithPassword("<password>"))
        if err != nil {
            panic(err)
        }
        client.Disconnect()
        counter++
    }
}

Based on my own small sample-sized measurements (20 crashes in 1572 connections) this will crash OBS on average on iteration 79.

Further Information This problem seems to be specific to goobs. When I create a similar example with obs-websocket-js in node, I can open thousands of connections in a matter of seconds with no problems at all.

andreykaipov commented 5 months ago

Hey @Gambloide! Thank you for the detailed report! I'm able to reproduce it. Apologies for the crashes this caused while streaming! :(

That debug log entry about a client connecting with a pre-5.0.0 protocol is technically expected, because of an old check I added during the v4 -> v5 migration in https://github.com/andreykaipov/goobs/pull/37. The motivation was to make it easier to debug when obs-websocket used to be a binary you manually copied into your plugins folder, but since obs-websocket ships with OBS now, I think it makes sense to remove that v4 check altogether.

And sure enough once I commented out this bit:

https://github.com/andreykaipov/goobs/blob/521d68f18e52611f0fd770a56b9f52d4f5adf3f6/client.go#L191-L193

The count in your loop got past 20k before my fans started going crazy.

If you're able to, can you try removing these lines to see if it works for you as well? If it does, please feel free to open it up as a PR too!


Interestingly looking at the stack trace from the crash log, the last bit is from obs-websocket, which might suggest something up with the v4 disconnection logic around here: https://github.com/obsproject/obs-websocket/blob/07537a33faff62b6cb8202b5369720bf2a52d8b6/src/websocketserver/WebSocketServer.cpp#L433-L441. I might send this their way too.

Unhandled exception: c0000005                                                                                                                                                                                                                                                                                                                                                                 
Date/Time: 2024-01-25, 19:35:01                                                                                                                                                                                                                                                                                                                                                               
Fault address: 7FFB0D9DB20D (c:\program files\obs-studio\obs-plugins\64bit\obs-websocket.dll)                                                                                                                                                                                                                                                                                                 
libobs version: 30.0.2 (64-bit)                                                                                                                                                                                                                                                                                                                                                               
Windows version: 10.0 build 22621 (release: 22H2; revision: 3007; 64-bit)                                                                                                                                                                                                                                                                                                                     
CPU: AMD Ryzen 5 5600X 6-Core Processor                                                                                                                                                                                                                                                                                                                                                       

Thread 330C: (Crashed)                                                                                                                                                                                                                                                                                                                                                                        
Stack            EIP              Arg0             Arg1             Arg2             Arg3             Address                                                                                                                                                                                                                                                                                 
0000002AA6ABDEE0 00007FFB0D9DB20D 0000000000000000 000001E3F12287C0 0000002AA6ABE208 00007FFBAE2D37EB obs-websocket.dll!WebSocketServer::onClose+0xcd                                                                                                                                                                                                                                         
0000002AA6ABE160 00007FFB0D9B9B31 000001E3F7C716E0 0000000000000078 0000000000000000 0000000000000080 obs-websocket.dll!std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,void (__cdecl WebSocketServer::*)(std::weak_ptr<void>) __ptr64,WebSocketServer * __ptr64,std::_Ph<1> const & __ptr64>,void,std::weak_ptr<void> >::_Do_call+0x31                                                  
0000002AA6ABE1A0 00007FFB0D9B666C 0000000000000000 0000002AA6ABE208 000001E3F12B0000 00007FFBADF7DF68 obs-websocket.dll!std::_Func_class<void,std::weak_ptr<void> >::operator()+0x1c                                                                                                                                                                                                          
0000002AA6ABE1D0 00007FFB0D9D24DC 0000002AA6ABE3A0 0000002AA6ABE3A0 000001E38293CF40 0000002AA6ABE330 obs-websocket.dll!websocketpp::connection<websocketpp::config::asio>::handle_terminate+0x13c                                                                                                                                                                                            
0000002AA6ABE290 00007FFB0D9CE3F7 000001E382F443A8 0000002AA6ABE320 0000002AA6ABE330 000001E382F45120 obs-websocket.dll!websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::handle_async_shutdown+0x1d7                                                                                                                                                    
0000002AA6ABE300 00007FFB0D99FDD2 0000002AA6ABE330 0000002AA6ABE3F0 0000002AA6ABE480 000001E3828FBC20 obs-websocket.dll!std::_Binder<std::_Unforced,void (__cdecl websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::*)(std::shared_ptr<asio::basic_waitable_timer<std::chrono::steady_clock,asio::wait_traits<std::chrono::steady_clock>,asio::any+0x82  
0000002AA6ABE380 00007FFB0D9BB680 000001E38293CF40 0000002AA6ABE689 000001E38293CF40 000001E382F6E2D0 obs-websocket.dll!websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::async_shutdown+0x360                                                                                                                                                           
0000002AA6ABE5C0 00007FFB0D9EC432 0000000000002746 00007FFB0DA98000 0000000000002746 00007FFB0DA98000 obs-websocket.dll!websocketpp::connection<websocketpp::config::asio>::terminate+0x2a2                                                                                                                                                                                                   
0000002AA6ABE6F0 00007FFB0D9D0D82 0000002AA6ABEED0 000001E38293CF40 0000000000000000 0000002AA6ABEED0 obs-websocket.dll!websocketpp::connection<websocketpp::config::asio>::handle_read_frame+0x12c2                                                                                                                                                                                          
0000002AA6ABEE40 00007FFB0D9CE183 0000000000000000 0000002AA6ABEEE0 0000000000000000 00007FFBB0C0BE70 obs-websocket.dll!websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::handle_async_read+0x153                                                                                                                                                        
0000002AA6ABEEA0 00007FFB0D9A2B07 0000000000000000 0000002AA6ABEFF0 0000002AA6ABEFF0 0000000000000000 obs-websocket.dll!asio::asio_handler_invoke<asio::detail::binder2<websocketpp::transport::asio::custom_alloc_handler<std::_Binder<std::_Unforced,void (__cdecl websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::*)(std::function<void __cde+0x67  
0000002AA6ABEF40 00007FFB0D9A5100 0000002AA6ABF188 000001E3FCBB79F0 0000002AA6ABF0C0 0000000000000000 obs-websocket.dll!asio::detail::strand_service::dispatch<asio::detail::binder2<websocketpp::transport::asio::custom_alloc_handler<std::_Binder<std::_Unforced,void (__cdecl websocketpp::transport::asio::connection<websocketpp::config::asio::transport_config>::*)(std::functi+0x70  
0000002AA6ABEFA0 00007FFB0D9B68E8 00000000FFFFFFFF 000001E3F50878D0 0000002AA6ABF770 0000000000000000 obs-websocket.dll!asio::detail::read_op<asio::basic_stream_socket<asio::ip::tcp,asio::any_io_executor>,asio::mutable_buffers_1,asio::mutable_buffer const * __ptr64,asio::detail::transfer_at_least_t,asio::detail::wrapped_handler<asio::io_context::strand,websocketpp::transpo+0x98  
0000002AA6ABF090 00007FFB0D9A2BC7 000001E38293D0E0 0000002AA6ABF120 0000002AA6ABF290 0000000000000000 obs-websocket.dll!asio::asio_handler_invoke<asio::detail::rewrapped_handler<asio::detail::binder2<asio::detail::read_op<asio::basic_stream_socket<asio::ip::tcp,asio::any_io_executor>,asio::mutable_buffers_1,asio::mutable_buffer const * __ptr64,asio::detail::transfer_at_lea+0x37  
0000002AA6ABF0E0 00007FFB0D9C0E91 0000002AA6ABF770 000001E38293D0E0 000001E3FCBB79F0 000001E38293D0E0 obs-websocket.dll!asio::detail::completion_handler<asio::detail::rewrapped_handler<asio::detail::binder2<asio::detail::read_op<asio::basic_stream_socket<asio::ip::tcp,asio::any_io_executor>,asio::mutable_buffers_1,asio::mutable_buffer const * __ptr64,asio::detail::transfer+0xc1  
0000002AA6ABF270 00007FFB0D9C3021 000001E3FCCEE580 000001E3FCD936D0 0000002AA6ABF4B0 000001E38293D0E0 obs-websocket.dll!asio::detail::strand_service::do_dispatch+0x121                                                                                                                                                                                                                       
0000002AA6ABF2E0 00007FFB0D9A553E 0000000000000000 0000002AA6ABF440 0000000000000000 000001E38293D0E0 obs-websocket.dll!asio::detail::strand_service::dispatch<asio::detail::rewrapped_handler<asio::detail::binder2<asio::detail::read_op<asio::basic_stream_socket<asio::ip::tcp,asio::any_io_executor>,asio::mutable_buffers_1,asio::mutable_buffer const * __ptr64,asio::detail::tr+0xde  
0000002AA6ABF340 00007FFB0D9C2270 000001E3FCBB79F0 0000000000000000 0000000000000000 0000000000000040 obs-websocket.dll!asio::detail::win_iocp_socket_recv_op<asio::mutable_buffers_1,asio::detail::read_op<asio::basic_stream_socket<asio::ip::tcp,asio::any_io_executor>,asio::mutable_buffers_1,asio::mutable_buffer const * __ptr64,asio::detail::transfer_at_least_t,asio::detail:+0x220 
0000002AA6ABF620 00007FFB0D9C34C2 000001E300000000 0000002AFFFFFFFF 0000002AA6ABF770 0000002AA6ABF820 obs-websocket.dll!asio::detail::win_iocp_io_context::do_one+0x372                                                                                                                                                                                                                       
0000002AA6ABF730 00007FFB0D9E8915 000001E3FCA7E080 0000000000000000 0000000000000002 0000002AA6ABF848 obs-websocket.dll!asio::detail::win_iocp_io_context::run+0xf5                                                                                                                                                                                                                           
0000002AA6ABF7F0 00007FFB0D9B8452 0000000000000000 000001E3FCBA3CB0 0000000000000000 0000000000000000 obs-websocket.dll!WebSocketServer::ServerRunner+0x42                                                                                                                                                                                                                                    
0000002AA6ABF840 00007FFB0D9A1C8F 000001E3FCD60530 0000000000000000 0000000000000000 0000000000000000 obs-websocket.dll!std::thread::_Invoke<std::tuple<void (__cdecl Utils::Obs::VolumeMeter::Handler::*)(void) __ptr64,Utils::Obs::VolumeMeter::Handler * __ptr64>,0,1>+0xf                                                                                                                 
0000002AA6ABF870 00007FFBAE2E9363 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ucrtbase.dll!0x7ffbae2e9363                                                                                                                                                                                                                                                             
0000002AA6ABF8A0 00007FFBAFEC257D 0000000000000000 0000000000000000 0000000000000000 0000000000000000 kernel32.dll!0x7ffbafec257d                                                                                                                                                                                                                                                             
0000002AA6ABF8D0 00007FFBB0C2AA58 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ntdll.dll!0x7ffbb0c2aa58    
Gambloide commented 5 months ago

132 created as requested

Thank you for the quick fix! I was not able to reproduce the issue on my device anymore after applying this change.

andreykaipov commented 5 months ago

Awesome! I cut a release for this: https://github.com/andreykaipov/goobs/releases/tag/v1.1.7