VitalRecorder
A free software to record and analyze biosignal waveforms and vital signs from GE® (Solar 8000®, Dash, Bx50®), Philips® (Intellivue®), Drager® (Infinity®, Nihon Kohden® (PSM®, Primus®), Maquet® (Flow-i®, Servo-i®) ventilators, Fresenius Kabi® (Orchestra®, Agilia®, and Link+®), BBraun® syringe pumps, Medtronic® BIS®, Masimo® Root®, DataQ® ADCs, etc. (Full list of supported devices)The use of the VitalRecorder program is completely free. Download and try the latest version.
(Downloaded 182,781 times since Feb 2017)
OS:
Version:
View All Versions
1.19.9
1.19.9 Fixed: 큰 녹화 파일(약 100MB 이상)을 서버로 올릴 때 프로그램이 메모리 부족으로 강제 종료되고, 재시작 후 같은 파일을 다시 시도하다 무한 반복되던 문제 — 업로드 본문을 메모리에 통째로 만들지 않고 디스크에서 흘려보내도록 변경(100MB 파일 기준 최대 메모리 208MB → 14MB). 큰 파일이 한 개라도 쌓이면 그 장비의 이후 업로드가 전부 막히던 증상이 사라진다. 1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.8
1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.7
1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.5
1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.4
1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.9
1.19.9 Fixed: 큰 녹화 파일(약 100MB 이상)을 서버로 올릴 때 프로그램이 메모리 부족으로 강제 종료되고, 재시작 후 같은 파일을 다시 시도하다 무한 반복되던 문제 — 업로드 본문을 메모리에 통째로 만들지 않고 디스크에서 흘려보내도록 변경(100MB 파일 기준 최대 메모리 208MB → 14MB). 큰 파일이 한 개라도 쌓이면 그 장비의 이후 업로드가 전부 막히던 증상이 사라진다. 1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.8
1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.7
1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.5
1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.4
1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.9
1.19.9 Fixed: 큰 녹화 파일(약 100MB 이상)을 서버로 올릴 때 프로그램이 메모리 부족으로 강제 종료되고, 재시작 후 같은 파일을 다시 시도하다 무한 반복되던 문제 — 업로드 본문을 메모리에 통째로 만들지 않고 디스크에서 흘려보내도록 변경(100MB 파일 기준 최대 메모리 208MB → 14MB). 큰 파일이 한 개라도 쌓이면 그 장비의 이후 업로드가 전부 막히던 증상이 사라진다. 1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.8
1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.7
1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.5
1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.4
1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.18.40
Hotfix: Drager Medibus 프로토콜 사용 베드에서 1.15.11 이후 vr.service 가 SIGSEGV 로 무한 재시작하던 문제. 1.15.10 (a8c7b2a) 의 "Sampling rate estimation" 리팩터링이 m_ptrk_awp/awf/co2 트랙을 add_trks() 에서의 eager 생성 (default srate=62.5Hz) 에서 realtime data 100 샘플 모인 후 lazy 생성으로 바꿨는데, Medibus 핸드셰이크 순서 (0x51 ICC → 0x52 DeviceID → 0x53 RealtimeConfig 응답 → 0x54 → realtime data 시작) 상 0x53 응답 핸들러 (Drager.cpp:295-307) 가 트랙들이 아직 nullptr 인 시점에 `ptrk->m_srate = 1000000.0/interval` 로 NULL 역참조 → 즉시 SEGV. 그 베드의 vr.service 가 systemd Restart=on-failure 로 재시작 → 다시 connect → 동일 0x53 패킷 받고 동일 SEGV → 무한 루프 (journald 로그상 restart counter 61 까지 누적, code=killed status=11/SEGV). 1.15.9 까진 트랙이 add_trks() 에서 생성되어 0x53 도착 시 항상 non-NULL 이라 안전했음. 수정: (a) add_trks() 에서 m_ptrk_awp/awf/co2 eager 생성 복원 (srate=62.5Hz default) — 0x53 는 ptrk->m_srate 만 갱신 (트랙 재생성 X). (b) on_received() 의 lazy creation + packet-timing srate 추정 블록 제거 — 0x53 가 권위 있는 srate 소스이고 packet 타이밍 기반 추정은 network jitter 에 약해 불안정. (c) 0x53 핸들러에 `if (interval > 0)` guard 추가 — 페이로드 깨졌을 때 div-by-zero / inf srate 방지. 영향 범위: Drager Primus / Apollo / Perseus / Fabius 등 Medibus 사용 마취기 전부. 우회 방법은 1.15.9 다운그레이드 외엔 없었음 (그 베드의 모든 데이터 유실 + 환자 모니터링 불가). MFC + Qt + Pi (RPI64) + Ubuntu Qt + AppImage 빌드 모두 통과.
1.18.37
Refactored: 필터 다이얼로그의 python 런타임 — pyvital → openvital 0.3.0 로 교체 + 동봉 python.zip 슬림화. 핵심 동기 셋: (1) pyvital 0.6.0 이 tensorflow+torch+keras 를 hard-dep 으로 끌어들여 PyPI upgrade 가 사실상 깨짐, (2) 기존 zip 121 MB 안에 botocore/aiobotocore/s3fs/pyarrow/pandas/aiohttp 등 vitaldb 클라우드 업로드용 deps 가 ~250 MB unpacked 차지 — 필터 서버는 한 번도 쓴 적 없는 dead weight, (3) sanic 25.x 의 multi-process worker 가 openvital __main__.py 를 fork 후 재import 하면서 worker 가 module-top app instance 를 못 찾아 "Sanic app name not found" 로 죽음 — 단순 endpoint 2개 로컬호스트 서버에 async stack 자체가 과함. 해결: openvital 0.3.0 (commit b6f445b) 가 sanic 을 stdlib http.server (BaseHTTPRequestHandler + HTTPServer) 로 50 LOC 재작성 — wire protocol (GET / 필터목록 JSON, POST /<modname> gzip 본문) 동일해 VR 클라이언트 변경 0줄. 단일 스레드로 기존 sanic event loop semantics (cfgs/default_cfgs lock-free 변경) 보존. build_python_zip.py (NEW) 가 Python 3.11.9 embed + numpy + openecg + openvital (local checkout 우선, fallback PyPI) 만으로 27 MB zip 빌드 — 기존 121 MB 대비 78% 감소. ML 필터 (sv_dlapco/abp_hpi/ecg_classifier/ecg_beat_noise_detector) 는 [Hybrid 모델] 사용자가 Add filter 다이얼로그의 "Install ML filters" 버튼 누를 때 silent pip install openvital[all] (cmd 창 미노출 — VRApp::install_pip_package + run_pip_silent 이 자체 progress 다이얼로그에 stdout heartbeat 흘림). 버튼 라벨은 "Upgrade pyvital" → "Install ML filters" 로 의도 명시. openvital __main__.py 가 missing extras 를 graceful skip 하므로 base 환경에서도 11개 필터 (ECG QRS detector, HRV, MTWA, annotator, eeg_fft, nirs_cox, pkpd_3comp, pleth_dpop/ptt/pvi, resp_compliance) 즉시 사용 가능. Migration: 기존 사용자의 user_dir/python 폴더는 pyvital + 옛 deps 가 그대로 남아있고 vitaldb.net/python.zip 만 새로 올리면 (a) 기존 폴더 삭제 후 install_python 으로 새 zip 받으면 깔끔, (b) 폴더 유지 시 server 가 openvital 못 찾아 필터 다이얼로그 에러 → release note 에 명시 필요. MFC + Qt 양쪽 코드: VRGui.rc 의 IDC_UPGRADE 버튼 라벨 + DlgAddFilter.cpp 의 dist-info prefix 매칭 (pyvital- 8자 → openvital- 10자) + QtDlgAddFilter.cpp 도 동일 변경 + onUpgrade 가 cmd /k QProcess::startDetached 대신 theApp.install_pip_package("openvital[all]") 호출 (Linux Qt 빌드는 #ifdef _WIN32 가드). VRApp.cpp:318 의 python -m pyvital → -m openvital. install_pip_package 는 anonymous namespace 의 is_safe_pkg_spec 화이트리스트 검증 + run_pip_silent (CreateProcessA + CREATE_NO_WINDOW + 자식 stdout pipe) + CDlgProgress / QtDlgProgress 자체 progress UI. 빌드 검증: python -m openvital 이 GET / 로 11 필터 반환, sanic import 부재 확인. zip 27.5 MB.
1.18.33
Fixed: Demo device never started since 1.18.11 (bed_manager skipped empty port_name as passive but Demo has no port and still needs lock_and_open); Fixed: Qt fit-to-window button rendered at top-left (0,0) instead of right-aligned in bottom nav bar; Fixed: Qt crash when closing tab / deleting device / deleting filter - paint dereferenced freed pointer before panel timer rebuilt items (added MFC-style stale-pointer guard to QtDeviceItem and QtFilterItem); Added: macOS DMG main window now shown on launch (restoreWindowPos had no Mac/Linux branch); Added: macOS Homebrew dylibs (openssl) bundled in Contents/Frameworks; Added: macOS .app bundle now notarized + stapled (drag-to-Applications no longer needs xattr -cr on first launch); Changed: Qt MSI ~1MB smaller (dropped unused iconengines and imageformats plugins)
1.18.31
Added: drug slot shows DOSE_AMOUNT (mg etc) in preference to VOL (mL) when available; Added: DOSE_RATE / DOSE_AMOUNT montypes bound to BBraun tracks for monitor view; Added: HL7 MDC_DOSE_DRUG_DELIV_TOTAL unit picked up dynamically from UCUM
1.19.9
1.19.9 Fixed: 큰 녹화 파일(약 100MB 이상)을 서버로 올릴 때 프로그램이 메모리 부족으로 강제 종료되고, 재시작 후 같은 파일을 다시 시도하다 무한 반복되던 문제 — 업로드 본문을 메모리에 통째로 만들지 않고 디스크에서 흘려보내도록 변경(100MB 파일 기준 최대 메모리 208MB → 14MB). 큰 파일이 한 개라도 쌓이면 그 장비의 이후 업로드가 전부 막히던 증상이 사라진다. 1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.8
1.19.8 Fixed: 자동 파일 자르기(CUT_FILE) 를 쓰는 베드에서 환자가 계속 연결돼 있는데도 녹화 파일이 PT_WAITING_TIME(기본 5분) 마다 잘리던 문제 — 웹 모니터링 전송 후 메모리를 비우는 과정에서 환자 연결 판정에 쓰이는 최근 구간까지 지워져 "환자가 나갔다" 로 오판하던 것. 이제 판정에 필요한 구간은 보존한다. 파일이 5분마다 끊기고 그때마다 수 초가 유실되던 증상이 사라진다. 1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.7
1.19.7 Added: GE Corometrics(분만 태아감시) 모체 vitals 지원 — 기존엔 태아 심박(HR1/HR2)·자궁수축(UACT)만 기록됐으나 이제 같은 장비가 함께 보내는 모체 SpO2/맥박(PR)/NIBP(수축·이완·평균)도 한 파일에 기록. Fixed: 프로세스 종료(서비스 매니저의 정상 종료 요청, SIGTERM) 시 즉시 종료되지 않고 강제 종료되던 문제 — 이제 SIGTERM 을 받아 녹화 버퍼를 flush 하고 스레드를 정리한 뒤 정상 종료. 1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.5
1.19.5 Fixed: CUT_HOURLY 가 동작하지 않는 것처럼 보이던 문제의 실체 — k3s 컨테이너에서 기본 저장 경로가 $HOME/recordings(임시 레이어)로 잡혀, 매일 자정 재시작 때 업로드 안 된 하루치 녹화가 통째로 사라짐. hostPath 마운트 /recordings 가 있으면 그것을 기본 저장 경로로 사용. Fixed: 종료(daily restart) 시 멀티베드 TCP 노드가 terminate(exit=133)/SIGSEGV(139) 로 죽던 문제. Linux finalize 가 device 스레드를 정지하지 않고 반환해 exit() 전역 소멸자가 살아있는 PortRouter accept_thread 를 파괴하며 std::terminate — DISPLAY::quiesce_threads + PortRouter::shutdown 으로 정리 후 종료 (코어 백트레이스로 확정, 로컬 재현 후 수정 검증). Fixed: Link+/Agilia 파서가 시리얼 노이즈(size byte 0 또는 헤더 없는 잡음 8byte)에 역전된 반복자 범위로 vector 를 생성하다 std::length_error 로 죽던 문제(or-110) — sentinel 상태 파싱 봉쇄 + 재동기화. Fixed: FILENAME_TEMPLATE 의 %Y(4자리 연도)가 "0126" 으로 나오던 문제 (tm_year+1900 누락). 1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
1.19.4
1.19.4 Fixed: Link+ 등 재접속이 잦은 장비에서 시리얼 포트를 재오픈할 때 "terminate called without an active exception" 으로 프로세스가 죽던 문제(exit=133). reading_thread_func 이 스스로 반환해도 std::thread 객체는 joinable 로 남는데, open() 이 join 없이 새 스레드를 대입해 std::terminate 가 호출됨 → 스레드 생성 전에 이전 reading/parsing 스레드를 join 후 재생성. Fixed: headless/AUTO_DETECT 모드에서 실제 장비가 없을 때 Demo 장비가 생성돼 가짜 vital 트랙 38종이 업로드되던 문제 → --console 또는 AUTO_DETECT 시 Demo 미생성. 1.19.3 Fixed: 여러 베드를 한 프로세스가 TCP 로 수집하는 구성에서 클라이언트 재접속이 잦으면 프로세스가 SIGSEGV 로 죽던 문제(accept_handoff 가 replace 시 옛 소켓을 즉시 close 해 recv 중인 reader 와 경합, fd 번호 재사용). tcp reader 를 poll(200ms) 게이트 뒤의 recv 로 재구성하고 replace 는 shutdown 후 소유권을 reader/close 로 단일화. SNUH 회복실 VRN 15대에서 재현. Fixed: ICU 등 Intellivue 다수 베드에서 반복되던 SIGSEGV(139) 두 계열의 use-after-free. (1) DISPLAY::add_rec 이 레코드를 트랙에 push 한 뒤 저장했는데, push 직후 p 가 다른 스레드에 공유되고 Linux 의 메모리 보존 루프(600초 이전 레코드 delete)가 시계 어긋난 모니터에서 방금 넣은 레코드를 즉시 evict 해, 이어지는 p->save() 가 해제된 메모리에 가상 호출 → 저장을 push 앞으로 옮겨 공유 후 p 미접근. (2) DISPLAY::del_trk 이 트랙을 목록에서 뺀 직후 raw delete 해, 파싱 스레드의 캐시 포인터·장비 이름맵·recorded_trks 가 죽은 포인터를 참조 (특히 IAP 채널변경의 del 직후 add 가 해제 포인터 반환) → DEVICE 규칙처럼 살아있는 동안 삭제 금지, ~DISPLAY 에서 일괄 해제. picu-11 코어 덤프로 크래시 지점(add_rec vtable 간접호출) 확정. SNUH fleet ~100 노드 실배포에서 기대 크래시 다수 대비 실제 0, 미배포 노드는 계속 크래시. Fixed: Linux from_utf16 이 locale 의존·비스레드안전 wcstombs 를 쓰고 UTF-16 을 UTF-32 wchar_t 로 오해석하던 문제 → 수동 UTF-8 인코더(서로게이트 페어 재조립, 무효값 U+FFFD)로 교체. Added: AUTO_DETECT=1(vr.conf) 시리얼 장비 자동 판별. 회선 측정(보레이트·프레임폭·패리티) → 후보 필터(3축 일치, 베드당 클래스 배타, 포트 사전확률, 판별캐시) → 트랙 수확량 경쟁. 드라이버 무수정, 미설정 시 유휴 대기라 기존 설정 무영향. SNUH 수술장·ICU 실측 오탐 0.
Apple Silicon (arm64) only · Requires macOS 11 or later · Developer ID signed & notarized
Download Raspberry Pi Image
Preinstalled SD card image (.img.xz) · Flash to an SD card with Raspberry Pi Imager or balenaEtcher
If you use the VitalRecorder in your research, please cite the following publication:
Lee HC, Jung CW. VitalRecorder-a free research tool for automatic recording of
high-resolution time-synchronised physiological data from multiple anaesthesia devices. Sci Rep.
2018 Jan 24;8(1):1527. doi:
10.1038/s41598-018-20062-4. Available from: https://www.nature.com/articles/s41598-018-20062-4