반응형
작성일: 2025년 2월 4일

 

 

 

아래 블로그가 Proxy ARP를 쉽게 설명하고 있다. (예제를 이용하여 설명)

 

https://blog.naver.com/eqelizer/20133718343

 

위 블로그가 다루는 내용:

  • Proxy ARP 장점
  • Proxy ARP 단점
  • Proxy ARP 동작 원리 (예제 네트워크 구성도를 이용하여 동작 원리를 설명함)

 

반응형
작성일: 2025년 2월 2일

 

작년에 삼성 갤럭시 s23을 해외 직구로 구입하고, 처음 1년은 USIM(유심)으로 SKT 망에서 개통해서 사용했다.

그러다가 번호이동할 때가 되어, 통신사를 옮겨서 eSIM으로 개통하려고 보니 자꾸 에러가 나면서 eSIM 개통이 안 되었다. ㅠㅠ

우편물로 USIM을 받으면, USIM 배송에 시간이 걸리는 문제와 배송 봉투 & 안내문 같은 것이 나중에 쓰레기가 되서 환경 문제를 유발한다.

eSIM을 사용하면 쓰레기가 발생하지 않으니까 최대한 eSIM으로 개통하려고 노력 중인데,

이렇게 저렇게 알아보니까 해외 직구폰은  "IMEI 사전등록 신청"을 해야 한다고 한다.

(국내 생산 또는 국내 정식 유통되는 스마트폰은 제조사 또는 유통사가 직접 IMEI 등록을 하기 때문에 이런 절차가 필요없다고 한다)

 

 

IMEI 사전 등록 신청

아래 웹 페이지에서 해외 직구한 스마트폰의 IMEI를 사전등록하면 된다.

 

https://www.imei.kr/user/imei/instImei_step1.do

 

 

 

참고: IMEI 확인하는 방법

전화 패드에서 아래 코드를 입력하면 IMEI 번호를 확인할 수 있다.

(단, T전화 또는 에이닷 같은 런처 앱을 사용하면 안 된다. 순정 전화 패드에서만 IMEI 번호를 확인할 수 있다)

 

*#06#

 

 

 

위 IMEI 등록 절차가 끝나면, 1분 뒤쯤 통신사(또는 알뜰폰) 홈페이지에서 eSIM 개통 시도하면 된다.

아마 한국정보통신진흥협회에 있는 IMEI 정보가 각 통신사로 전달되기 까지는 시간이 소요되는 것 같다. (몇 초 ~ 수십 초)

 

 

반응형
작성일: 2025년 2월 2일

 

PDF 파일에 있는 각 페이지를 각각의 그림 파일(PNG)로 변환하고자 할 때, 아래처럼 따라하면 된다.

 

 

PyMuPDF 파이썬 패키지 설치하기

$ pip install pymupdf

 

 

PDF 파일을 이미지 파일(PNG)로 변환하기 위한 코드 작성하기

## File name: main.py

import sys, pymupdf

fname = sys.argv[1]
doc = pymupdf.open(fname)

for page in doc:  
    pix = page.get_pixmap(dpi=300)  ## 참고: 300 DPI 해상도로 이미지를 변환.
    pix.save("page-%i.png" % page.number)  # PNG 포맷의 이미지 파일로 저장

 

 

Python 코드 실행하기

$ python3 main.py myexample.pdf

 

위 python code를 실행하면,  page-1.png  page-2.png ... 처럼 각 페이지 단위로 그림 파일이 생성된다.

 

 

PyMuPDF 파이썬 패키지 - 공식 매뉴얼

https://pymupdf.readthedocs.io/en/latest/recipes-images.html#how-to-make-images-from-document-pages

 

 

반응형
작성일: 2025년 2월 2일

 

 

아이뮤즈(iMUZ) 뮤펜 mu-PEN 태블릿 스타일러스 펜 - 사용자 가이드(매뉴얼)

제품명: 스타일러스 펜

모델명: IP-CT01C

 

 

 

반응형
작성일: 2025년 2월 2일

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

 

 

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

 

[ 앤커 사운드코어 ] 스페이스원 사용자 매뉴얼 (User Manual)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
작성일: 2025년 2월 4일

 

 

소스 코드 분석 도구를 분류해본다면, "유료" or "무료"가 아닐까?
(나의 개인적 의견임 ^^)
내가 "유료", "무료"를 분류한 이유는 "유료" 분석 도구가 어마어마하게 비싸서이다. ㅠㅠ
작은 회사가 구입해서 쓸 수 있는 소프트웨어가 아니다.
너무 비싸서, 대기업이나 되야 유료 소스 코드 분석 도구의 유용함을 체감할 수 있다.

 

 

Blackduck Coverity (유료)

많이 비싸다.

"한번 써볼까?" 이런 느낌으로 쓸 수 있는 수준의 가격이 아니다. ㅠㅠ

 

어쨌든, 나는 Blackduck Coverity 분석 도구에 대한 도입을 고려하고 공급사에 문의 중이니까 의미있는 문의 결과가 있으면 여기에 추가로 내용을 공유할 생각임.

 

 

 

 

CppCheck (무료)

CppCheck에 대한 자세한 설명은 아래 웹 문서를 참고:

https://cppcheck.sourceforge.io/

 

CppCheck 프로그램 설치하기

## Debian, Ubuntu
$ apt install cppcheck

## macOS
$ brew install cppcheck

## Fedora
$ yum install cppcheck

 

CppCheck 명령 실행하기

내가 제일 많이 사용하는 옵션은 아래와 같다.

현재 디렉토리에 있는 모든 파일을 분석할거라면, 아래의 옵션으로 실행하는 것을 추천한다. 

$ cppcheck  --check-level=exhaustive \
          --enable=warning,style,performance,portability,unusedFunction ./

 

 

 

SonarQube

## 작성 보류.

반응형
작성일: 2025년 1월 21일

 

C언어로 작성된 Signal Handler 내에서  "localtime()" 함수를 사용할 때, 주의할 점이 있다.

아래 예제 코드처럼 program 내에서 이미 localtime() 함수가 사용되고 있다면, Signal Handler 내부의 localtime() 함수로 인해서 호출되는  futex_wait() 함수 부분에서 Deadlock(데드락) 상태로 빠질 수 있다.

 

아래 예제 소스 코드를 컴파일하고, 테스트해보면 1~5초가 지날 때쯤 deadlock 상태가 된다.

일반적으로 multi thread 환경에서 mutex lock 때문에 deadlock이 되는 경우는 많지만, 아래 예제 코드처럼 multi thread가 아닌데 deadlock 상태가 되는 경우는 경험하기 쉽지 않다.

 

만약, 아래 예제 코드에서 signal handler를 제거한다면 deadlock 상황은 발생하지 않는다.

 

/****************************************************
 * How to compile
 *  $ gcc -g main.c -o myapp
 * How to test
 *  $ ./myapp
 ***************************************************/

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>


static void sigchd_handler(int signo)
{
    time_t tv;
    tv = time(NULL);

    struct tm mytime = *localtime(&tv); // NOTE: 이 부분에서 Deadlock 발생함.
    char my_date[64];
    sprintf(my_date, "%d-%02d-%02d %02d:%02d:%02d",
                mytime.tm_year + 1900, mytime.tm_mon + 1, mytime.tm_mday,
                mytime.tm_hour, mytime.tm_min, mytime.tm_sec);
    printf("%s(%d) %s() time: %s\n", __FILE__, __LINE__, __func__, my_date);
    fflush(NULL);
    return ;
}


int register_signal_handler(void)
{
    struct sigaction sa;

    sa.sa_handler = sigchd_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;

    sigaction(SIGCHLD, &sa, NULL);

    return __LINE__;
}

#define LOOP_TRUE 1

int main(void)
{
    int ret;
    int idx;

    ret = register_signal_handler();

    time_t tv;
    while (LOOP_TRUE)
    {
        printf("My PID: %d\n", (int) getpid());

        FILE *fp = popen("ls -al", "r");
        tv = time(NULL);
        struct tm mytime;
        for (idx = 0; idx < 10000; idx++)
        {
            printf("localtime() Function Call Counter: %d \r", idx);
            fflush(NULL);
            mytime = *localtime(&tv); // NOTE: 이 부분에서 Deadlock 발생함.
        }
        printf("\n");
        char my_date[64];
        sprintf(my_date, "%d-%02d-%02d %02d:%02d:%02d",
                    mytime.tm_year + 1900, mytime.tm_mon + 1, mytime.tm_mday,
                    mytime.tm_hour, mytime.tm_min, mytime.tm_sec);
        printf("%s(%d) %s() time: %s\n", __FILE__, __LINE__, __func__, my_date);
        fflush(NULL);
        pclose(fp);

        sleep(1);
    }

    return 0;
}

 

 

위 예제 코드에서 signal handler 때문에 deadlock이 발생하는 이유는 무엇일까?

localtime() 함수의 구현 부분을 보면, futex_wait() 함수를 호출하는 부분이 있다. 이 futex_wait() 함수가 이미 호출된 상태인데 또 한번 futex_wait() 함수가 호출되면 deadlock 상태가 된다. 즉, localtime() 함수가 호출 중인 상태에서 또 한번 localtime() 함수가 호출되면 동일 lock 변수인 tzset_lock 변수를 통해서 lock 시도를 했는데, 또 tzset_lock 변수를 이용해서 lock 시도는 하는 셈이 되는 것이다.

결국 tzset_lock -> locking 그리고 tzset_lock -> locking  이런 식으로 연속으로 두번 locking 시도를 하면서 2번째 locking 시도는 영원히 locking하려고 대기하게 된다. 또한 첫번째 locking 시도는 두 번째의 locking 시도를 한 signal_handler가 종료가 되지 않으니까 영원히 signal_handler의 종료만 기다리며 tzset_lock이 unlocking 되지 않는 것이다.

 

 

Deadlock 상태에 빠지는 이유를 이해했다면, 실습해보자!

아래와 같이 Source code를 compile하고, 바이너리 코드를 실행해보자.

실행하고 대략 1~5초 후에 프로세스가 아무것도 출력하지 않고 멈춘 것처럼 보일 것이다.

이때가 동일한 tzset_lock 변수에 대해서 첫번째 locking -> 두번째 locking을 연달아 시도하면서 deadlock 상태에 빠진 것이다.

$ gcc -g main.c -o myapp

$ ./myapp

My PID: 255676
main.c(25) sigchd_handler() time: 2025-01-21 07:54:58
localtime() Function Call Counter: 9999
main.c(72) main() time: 2025-01-21 07:54:58
My PID: 255676
localtime() Function Call Counter: 382    <-- 여기서 Deadlock 상태에 빠짐

 

 

머리로 이해한 것을 Process 내부의 function call stack을 통해서 확인해보자!

Deadlock 상태에 빠졌을 때, 아래와 같이 gdb로 function call stack을 확인해보면

  1. main()함수는 localtime()를 호출하면서 tzset_lock 변수를 통해 locking 시도를 하고 있었고,
  2. 이런 와중에 popen("ls -al", "r") 함수를 통해 실행되었던 child process가 종료되면서,
  3. Parent Process인 "myapp"이 SIGCHLD를 수신하게 된다.
  4. 이때 signal handler인 "sigchd_handler"가 실행되면서 localtime() 함수를 한번 더 실행하게 된다.
  5. 짠~!  main() 함수가 아직 localtime()함수를 통해 tzset_lock을 unlock하지 않았는데, signal handler의 localtime() 함수가 tzset_lock을 locking 시도를 했기 때문에 이때부터 dealock 상태가 되는 것이다.

 

$ gdb ./myapp 255676

(gdb) where
#0  futex_wait (private=0, expected=2, futex_word=0x7fa99d11c760 <tzset_lock>) at ../sysdeps/nptl/futex-internal.h:146
#1  __GI___lll_lock_wait_private (futex=futex@entry=0x7fa99d11c760 <tzset_lock>) at ./nptl/lowlevellock.c:34
#2  0x00007fa99cfd6744 in __tz_convert (timer=1737446099, use_localtime=1, tp=0x7fa99d11c6a0 <_tmbuf>) at ./time/tzset.c:572
#3  0x0000564ee1a0a30e in sigchd_handler (signo=17) at main.c:20
#4  <signal handler called>
#5  __GI___fstatat64 (fd=-100, file=0x7fa99d0d4b02 "/etc/localtime", buf=0x7ffdd9ca4780, flag=0)
    at ../sysdeps/unix/sysv/linux/fstatat64.c:166
#6  0x00007fa99cfd683c in __tzfile_read (file=file@entry=0x7fa99d0d4b02 "/etc/localtime", extra=extra@entry=0,
    extrap=extrap@entry=0x0) at ./time/tzfile.c:155
#7  0x00007fa99cfd5c24 in tzset_internal (always=<optimized out>) at ./time/tzset.c:405
#8  0x00007fa99cfd65a7 in __tz_convert (timer=1737446099, use_localtime=1, tp=0x7fa99d11c6a0 <_tmbuf>) at ./time/tzset.c:577
#9  0x0000564ee1a0a528 in main () at main.c:65
(gdb)

 

 

그러면, signal handler 내부의 localtime() 함수 때문에 deadlock이 생기는 상황을 피하려면 어떻게 해야 할까?

signal handler에서는 Lock 관련 함수/변수 사용 금지, I/O 관련 함수 호출을 하지 말라는 권고가 옛날부터 전해져 내려오고 있다.

signal handler는 최소의 작업만, 그리고 빠른 시간에 처리하고 종료되도록 구현하라는 권고도 있어왔다.

그러니까 localtime() 함수로 예쁘게 date 값을 뽑아내려고 하지 말고, 그냥 time(NULL)을 이용해서 epoch time 값을 뽑아서 활용하면 문제를 해결할 수 있다. 

signal handler 내부에서 Lock 관련 함수를 쓰지 않으면 만사 OK !!

반응형
작성일: 2025년 1월 13일

 

Golang으로 코드를 작성하다보면, 다른 개발자가 작성한 go package를 사용할 일이 생긴다.

분명 누군가 go package를 만들었을 것 같은데, 찾기가 쉽지 않다.

(안정성, 보안성 측면에서 믿을 만한 package를 찾기가 힘들다는 뜻)

 

아래의 웹 사이트를 이용해서 Go Package를 찾아보는 것을 추천!

Golang 표준 라이브러리 (표준 패키지)

https://pkg.go.dev/std

 

Standard library - Go Packages

Discover Packages Standard library Version: go1.23.4 Opens a new window with list of versions in this module. Published: Dec 3, 2024 License: BSD-3-Clause Opens a new window with license information. Jump to ... Directories Directories ¶ Show internal Exp

pkg.go.dev

 

"Awesome Go" 에서 많이 사용되는 패키지 모음

https://github.com/avelino/awesome-go

 

GitHub - avelino/awesome-go: A curated list of awesome Go frameworks, libraries and software

A curated list of awesome Go frameworks, libraries and software - avelino/awesome-go

github.com

 

+ Recent posts