lsyncd + rsync로 디렉토리 실시간 백업하기

lsyncd + rsync로 디렉토리 거의 실시간 백업하기
실시간 동기화 라고 할 수도 있지만.. 실제로는 원본 디렉토리에 파일이 생성된 직후 rsync가 실행되어 백업 서버로 동기화 하기 때문에 파일이 copy되는 동안의 시간차 발생함.
1. rsync 설치, 설치 확인 (백업서버)
[root@vm2 sdir]# yum install rsync
[root@vm2 sdir]# rpm -qa | grep rsync
rsync-3.0.6-4.el5_7.1
2. rsync 활성화 (백업서버)
[root@vm2 data]# vi /etc/xinetd.d/rsync
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
# allows crc checksumming etc.
service rsync
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = –daemon
log_on_failure += USERID
}
3. rsyncd.conf 설정 (백업서버)
[root@vm2 data]# vi /etc/rsyncd.conf
[data_sync]
path=/data/sdir <– 접근을 허용할 디렉토리(백업디렉토리)
hosts allow=192.168.122.20 <– 접근을 허용할 서버 IP, 여러대를 동기화 할 경우 , 로 IP 추가
uid=0
gid=0
use chroot=yes
read only=no
[root@vm2 data]# mkdir /data/sdir
[root@vm2 data]#
[root@vm2 data]# /etc/init.d/xinetd restart
xinetd 를 정지 중: [ OK ]
xinetd (을)를 시작 중: [ OK ]
[root@vm1 data]#
4. lsyncd 설치 (원본서버)
[root@vm1 yum.repos.d]# yum install lsyncd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.daum.net
* extras: ftp.daum.net
* rpmforge: ftp.riken.jp
* updates: ftp.daum.net
Setting up Install Process
Resolving Dependencies
–> Running transaction check
—> Package lsyncd.i386 0:2.0.4-1.el5.rf set to be updated
–> Processing Dependency: lua for package: lsyncd
–> Running transaction check
—> Package lua.i386 0:5.1.4-2.el5.rf set to be updated
–> Finished Dependency Resolution
Dependencies Resolved
====================================================================================================================================
Package Arch Version Repository Size
====================================================================================================================================
Installing:
lsyncd i386 2.0.4-1.el5.rf rpmforge 149 k
Installing for dependencies:
lua i386 5.1.4-2.el5.rf rpmforge 242 k
Transaction Summary
====================================================================================================================================
Install 2 Package(s)
Upgrade 0 Package(s)
Total download size: 391 k
Is this ok [y/N]: y
Downloading Packages:
(1/2): lsyncd-2.0.4-1.el5.rf.i386.rpm | 149 kB 00:00
(2/2): lua-5.1.4-2.el5.rf.i386.rpm | 242 kB 00:00
————————————————————————————————————————————
Total 243 kB/s | 391 kB 00:01
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : lua 1/2
Installing : lsyncd 2/2
Installed:
lsyncd.i386 0:2.0.4-1.el5.rf
Dependency Installed:
lua.i386 0:5.1.4-2.el5.rf
Complete!
[root@vm1 yum.repos.d]#
– yum 으로 실치가 불가능할 경우 아래와 같이 rpmforge의 레포지터리를 추가하거나, rpm 파일을 다운로드 받아서 설치
[root@vm1 yum.repos.d]# cat /etc/yum.repos.d/rpmforge.repo
[rpmforge]
name = Red Hat Enterprise $releasever – RPMforge.net – dag
#baseurl = http://apt.sw.be/redhat/el5/en/$basearch/dag
mirrorlist = http://apt.sw.be/redhat/el5/en/mirrors-rpmforge
#mirrorlist = file:///etc/yum.repos.d/mirrors-rpmforge
enabled = 1
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 0
5. lsyncd.conf 파일 생성 (원본서버)
settings = {
logfile = “/var/log/lsyncd.log”, <– 로그파일 경로 설정
statusFile = “/var/log/lsyncd-status.log”, <– lsyncd 상태 로그 경로
delay = 1,
}
sync{
default.rsync,
source= “/data/sdir”, <– 동기화 할 원본 디렉토리
rsyncOpts= “-avz”,
target= “192.168.122.184::data_sync” <– backup 경로, rsyncd.conf 파일에 지정된 서비스명
}
sync{
default.rsync,
source= “/data/sdir”, <– 동기화 할 원본 디렉토리
rsyncOpts= “-avz”,
target= “192.168.122.150::data_sync”, <– backup 경로, rsyncd.conf 파일에 지정된 서비스명
}
==============================================
– 백업서버가 2EA 이상일 경우, 아래와 같은 형식으로 작성해도 됨.
[root@vm1 sdir]# cat /etc/lsyncd.conf
settings = {
logfile = “/var/log/lsyncd.log”, <– 로그파일 경로 설정
statusFile = “/var/log/lsyncd-status.log”, <– lsyncd 상태 로그 경로
delay = 1,
}
targetlist = {
“192.168.122.184::data_sync”, <– backup 경로, rsyncd.conf 파일에 지정된 서비스명
“192.168.122.150::data_sync” <– backup 경로, rsyncd.conf 파일에 지정된 서비스명
}
for _, server in ipairs(targetlist) do
sync{ default.rsync,
source=”/data/sdir/”, <– 동기화 할 원본 디렉토리
target=server,
rsyncOpts= “-avz”,
}
end
6. lsyncd 데몬 실행 (원본서버)
[root@vm1 sdir]# /etc/init.d/lsyncd restart
lsyncd (을)를 시작 중: [ OK ]
7. 동기화 테스트
– 원본 서버의 source 디렉토리(/data/sdir) 에서 파일을 생성/삭제하면서, 백업서버의 target 디렉토리가 정상적으로 동기화 되는지 확인
8. 여러대의 서버를 서로 상호간 동기화 설정을 하기 위해서는
– 원본 서버에 백업서버와 동일하게 rsyncd.conf 파일을 생성하여 백업서버에서 접근이 가능하도록 설정
– 백업서버에 원본과 동일하게 lsyncd를 실행하고 백업 디렉토리에 생성/삭제된 파일이 원본서버로 동기화 되도록 설정

How to install asterisk and freepbx on ubuntu 16.04

출처 : https://schooloffreelancing.blogspot.com/2017/11/asterisk-freepbx-install-into-ubuntu.html

apt-get -y autoremove
apt-get -y update
apt-get -y upgrade
# Some Utils
apt-get install -y curl vim-nox
# PJSIP
apt-get install -y make gcc g++ binutils sudo git
cd /usr/src
git clone https://github.com/asterisk/pjproject.git
cd /usr/src/pjproject
CFLAGS=’-DPJ_HAS_IPV6=1′ ./configure –prefix=/usr –enable-shared –disable-sound –disable-resample –disable-video –disable-opencore-amr
make dep 
make
make install
ldconfig
ldconfig -p | grep pj
# Asterisk 13
apt-get install -y libtool pkg-config libnewt-dev subversion
apt-get install -y libncurses5-dev uuid-dev libjansson-dev libxml2-dev libsqlite3-dev
apt-get install -y libmysqlclient-dev 
apt-get install -y unixodbc-dev libmyodbc
apt-get install -y libssl-dev libcurl4-openssl-dev libgnutls28-dev libsrtp0-dev
apt-get install -y bison flex
apt-get install -y sox lame flac mpg123 libmpg123-dev libogg-dev libvorbis-dev libspeex-dev libspeexdsp-dev libasound2-dev
apt-get install -y libiksemel-dev libiksemel-utils 
apt-get install -y libspandsp-dev
apt-get install -y libical-dev libneon27-dev 
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz
tar zxvf asterisk-13-current.tar.gz
cd asterisk-*
# contrib/scripts/install_prereq install
contrib/scripts/get_mp3_source.sh
./configure
make menuselect.makeopts
menuselect/menuselect –enable-category MENUSELECT_ADDONS menuselect.makeopts
menuselect/menuselect –enable CORE-SOUNDS-EN-GSM –enable MOH-OPSOUND-WAV –enable EXTRA-SOUNDS-EN-GSM –enable cdr_mysql menuselect.makeopts
menuselect/menuselect –disable app_mysql –disable app_setcallerid –disable func_audiohookinherit menuselect.makeopts
make
make install
make config
make samples
ldconfig
ldconfig -p | grep asterisk
systemctl disable asterisk.service
cd /var/lib/asterisk/sounds
wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-en-wav-current.tar.gz
wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-extra-sounds-en-wav-current.tar.gz
tar xvf asterisk-core-sounds-en-wav-current.tar.gz
rm -f asterisk-core-sounds-en-wav-current.tar.gz
tar xfz asterisk-extra-sounds-en-wav-current.tar.gz
rm -f asterisk-extra-sounds-en-wav-current.tar.gz
# Wideband Audio download 
wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-en-g722-current.tar.gz
wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-extra-sounds-en-g722-current.tar.gz
tar xfz asterisk-extra-sounds-en-g722-current.tar.gz
rm -f asterisk-extra-sounds-en-g722-current.tar.gz
tar xfz asterisk-core-sounds-en-g722-current.tar.gz
rm -f asterisk-core-sounds-en-g722-current.tar.gz
useradd -m asterisk
chown asterisk. /var/run/asterisk
chown -R asterisk. /etc/asterisk
chown -R asterisk. /var/{lib,log,spool}/asterisk
chown -R asterisk. /usr/lib/asterisk
# FreePBX 13
export DEBIAN_FRONTEND=noninteractive
apt-get install -y apache2 mysql-server mysql-client php5 php5-curl php5-cli php5-mysql php5-gd php-pear unixodbc
rm /var/www/html/index.html
sed -i ‘s/\(^upload_max_filesize = \).*/\120M/’ /etc/php5/apache2/php.ini
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf_orig
sed -i ‘s/^\(User\|Group\).*/\1 asterisk/’ /etc/apache2/apache2.conf
sed -i ‘s/AllowOverride None/AllowOverride All/’ /etc/apache2/apache2.conf
service apache2 restart
cat >> /etc/odbcinst.ini << EOF
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
FileUsage = 1
 
EOF
cat >> /etc/odbc.ini << EOF
[MySQL-asteriskcdrdb]
Description=MySQL connection to ‘asteriskcdrdb’ database
driver=MySQL
server=localhost
database=asteriskcdrdb
Port=3306
Socket=/var/run/mysqld/mysqld.sock
option=3
 
EOF
cd /usr/src
wget http://mirror.freepbx.org/modules/packages/freepbx/freepbx-13.0-latest.tgz
tar vxfz freepbx-13.0-latest.tgz
rm -f freepbx-13.0-latest.tgz
cd /usr/src/freepbx
rm /etc/asterisk/*.conf
./start_asterisk start
./install -n
cat >> /etc/systemd/system/freepbx.service << EOF
[Unit]
Description=FreePBX VoIP Server
After=mysql.service
 
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/fwconsole start
ExecStop=/usr/sbin/fwconsole stop
 
[Install]
WantedBy=multi-user.target
 
EOF
systemctl enable freepbx.service
systemctl start freepbx.service
systemctl status freepbx.service
fwconsole chown
fwconsole reload
fwconsole moduleadmin installall
fwconsole moduleadmin upgradeall
fwconsole chown
fwconsole reload
fwconsole moduleadmin uninstall dahdiconfig
fwconsole moduleadmin delete dahdiconfig
fwconsole moduleadmin uninstall sipstation
fwconsole moduleadmin delete sipstation
fwconsole moduleadmin uninstall digium_phones
fwconsole moduleadmin delete digium_phones
fwconsole moduleadmin uninstall cxpanel
fwconsole moduleadmin delete cxpanel
fwconsole moduleadmin uninstall firewall
fwconsole moduleadmin delete firewall
fwconsole moduleadmin upgradeall
fwconsole chown
fwconsole reload
fwconsole chown

MySQL 외부 접속 (root / user) 가능하도록 설정

원격 접속 가능한 호스트 및 사용자 확인

[root@company bin]# mysql uroot p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 561388
Server version: 5.0.51log Source distribution
 
 
 
mysql> select HOST, USER, Password FROM mysql.user;
+—————–+——-+——————————————-+
| HOST            | USER  | Password                                  |
+—————–+——-+——————————————-+
| localhost       | root  | *(생략)                           | 
| company         | root  |                                           | 
| 127.0.0.1       | root  |                                           | 
| localhost       |       |                                           | 
| company         |       |                                           | 
| localhost       | news  | *(생략)                                | 
| 211.200.200.200 | news  | (생략)                                     | 
| 100.200.100.100 | news  | (생략)                                      | 
| 192.168.100.110 | news  | (생략)                                      | 
+—————–+——-+——————————————-+
 
9 rows in set (0.02 sec)

위 경우 HOST에 명시된 호스트에서만 접속 가능.

따라서 사용자 추가.

mysql> show databases;
+——————–+
| Database           |
+——————–+
| information_schema | 
| mysql              | 
| company            | 
+——————–+
3 rows in set (0.01 sec)
 
mysql> use mysql
Database changed
 
mysql> insert into user (host,user,password) 
values(‘%’,‘news’,password(‘newspasswd’));
Query OK, 0 rows affected (0.02 sec)
 
mysql> GRANT all privileges on *.* to ‘news’@‘%’ 
identified by ‘newspasswd’ ;
Query OK, 0 rows affected (0.02 sec)
 
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)
 
 
mysql> select HOST, USER, Password FROM mysql.user;
+—————–+——-+——————————————-+
| HOST            | USER  | Password                                  |
+—————–+——-+——————————————-+
| localhost       | root  | *7540F67EE4(생략)                         | 
| company         | root  |                                           | 
| 127.0.0.1       | root  |                                           | 
| localhost       |       |                                           | 
| company         |       |                                           | 
| localhost       | news  | *7540F67EE4                               | 
| 211.200.200.200 | news  | 49d7                                      | 
| 100.200.100.100 | news  | 49d7                                      | 
| 192.168.100.110 | news  | 49d7                                      | 
| %  | news  | *7540F67EE4                               | 
+—————–+——-+——————————————-+
10 rows in set (0.02 sec)
 


단 MySQL 5.7에서는 Insert 명령어를 아래와 같이 변경해야 함.
insert into user(host,user,authentication_string,ssl_cipher,x509_issuer,x509_subject) values (‘%’, ‘news’, password(‘password’),”,”,”);


호스트를 %로 할경우 어떤 호스트에서든 접속 가능.

이렇게 하고도… 외부에서 접속이 안될 경우

1. OS 방화벽 (리눅스 방화벽 확인 ) 해제 – ufw disable
2. MySQL 설정 파일 “my.cnf” (mysqld.cnf) 에, bind-address=127.0.0.1 로 되어 있는 것을 “0.0.0.0” 으로 변경 후, 
3. MySQL 재시작

UBuntu 16.04 – 부팅시 rc.local 파일 실행 되지 않을 때 (systemd 기반 rc.local 활성화)

우분투 16.04 버전은 systemd 기반으로 PID들이 관리된다,
rc.local을 부득이 하게 사용할 일이 생겨 사용하려 했으나 활성화가 안되어 있어서 활성화 방법을 찾아서 기록

 

/lib/systemd/sytem/rc-local.service 을 수정한다.

 

가장 하단에 

 

[#M_ more.. | less.. |[Install]
WantedBy=multi-user.target _M#]

 

​위 와 같이 추가 시켜준 뒤 

[#M_ more.. | less.. |systemctl enable rc-local.service _M#]

 

​rc.local 서비스를 활성화 시켜준다.

Install을 추가시켜주지 않고 활성화를 시켜주려 하면, 해당 부분이 없어 활성화가 되지 않는다.

 

rc.local이 제데로 동작하는지 테스트는 서비스 재시작 뒤 확인 해주면 된다.

[#M_ more.. | less.. |service rc.local restart
systemctl status rc-local.service_M#]

 

​정상적으로 동작한다면 

 

[#M_ more.. | less.. |

root@stream:~# systemctl status rc-local.service

● rc-local.service – /etc/rc.local Compatibility

   Loaded: loaded (/etc/systemd/system/rc-local.service; static; vendor preset: enabled)

  Drop-In: /lib/systemd/system/rc-local.service.d

           └─debian.conf

   Active: active (running) since Mon 2018-04-02 15:23:37 KST; 3min 43s ago

  Process: 1434 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)

    Tasks: 87

   Memory: 111.9M

      CPU: 3.000s

   CGroup: /system.slice/rc-local.service

           ├─1529 /usr/local/bin/tvheadend –config /home/TVHeadEnd/.hts/tvheadend/ –user root –gr

           └─1530 /usr/local/bin/istatserver -d

 

Apr 02 15:23:38 stream tvheadend[1529]: scanfile: DVB-C – loaded 18 regions with 60 networks

Apr 02 15:23:38 stream tvheadend[1529]: scanfile: ATSC-T – loaded 2 regions with 12 networks

Apr 02 15:23:38 stream tvheadend[1529]: scanfile: ATSC-C – loaded 1 regions with 5 networks

Apr 02 15:23:38 stream tvheadend[1529]: scanfile: ISDB-T – loaded 2 regions with 1297 networks

Apr 02 15:24:37 stream tvheadend[1529]: iptv: m3u parse: 0 new mux(es) in network ‘IPTV’ (total 116)

 _M#]

active (활성화) 되었다고 표시되며, 하단에 로그도 확인이 가능하다.

메모리 보호 기법 SSP(Stack Smashing Protector)

출처: http://bbolmin.tistory.com/65 

Stack Smashing Protector은 gcc 4.1버전 부터 있는 stack overflow를 방지하기 위한 컴파일러 옵션이다.

 

gcc 4.6.1버전에서 컴파일 후 overflow가 발생하는 프로그램을 실행시켜 보니 다음과 같이 stack smashing detected가 뜨는 것을 확인 할 수 있다.

SSP 끄기 : -fno-stack-protector

SSP를 모든 함수에 설치 : -fstack-protector-all (원래는 일정 크기의 char배열이 있는 함수에만 적용됨)


SSP의 기능을 살펴보자

1. 로컬 변수 재배치

2. 로컬 변수전에 포인터 배치

3. canary 삽입

 

1. 로컬 변수 재배치

 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

 

void main(int argc, char *argv[])

{

    int check=0;
    char buf[10];

    strcpy(buf, argv[1]);

    if(check==0)
        exit(0);

    printf(“check : %d\n”, check);

}

buf를 오버플로우시켜서 check값을 바꿀 수 있을 것이다. 하지만 SSP는 스택에서 char배열을 제일 높은 곳으로 올려 다른 변수 값이 변조되는 것을 막는다.

 

 

2. 로컬 변수전에 포인터 배치

 

void test(char *arg)

{

char buf[10];

strcpy(buf, arg);

}

위와 같이 포인터가 있을 때 buf를 오버플로우 시켜서 test함수의 파라미터로 전달된 포인터 arg값을 바꿀 수 있을 것이다. 하지만 SSP는 arg포인터를 buf아래 쪽에 두어서 변조되는 것을 막는다.

 

 

 

3. canary 삽입

 

————

|       ret     |

————

|      ebp     |

————

|   canary  |

————

|       buf     |

————

 

stack guard처럼 canary를 두어 ret변조를 탐지한다. 이 때 canary는 ebp와 buf 사이에 넣는다. canary 값은 1) random, 2) terminator, 3) null 을 사용하여 우회하는 것을 방지한다. canary 변조를 탐지 했을 때 맨위 그림와 같이 stack-smashing-detected 메시지를 띄어준다. (변조 탐지시 __stack_chk_fail함수를 호출)

 

GDB 사용시 raise.c 와 같이 glibc 파일이 없다고 나오는 경우

에러 메시지 
Unable to open ‘raise.c’: File not found (file:///build/glibc-Cl5G7W/glibc-2.23/sysdeps/unix/sysv/linux/raise.c).

이 경우 우선 glibc 를 소스까지 다운로드


Building glibc without installing

To build glibc without installing you can do the standard configure and make e.g.

$ mkdir $HOME/src
$ cd $HOME/src
$ git clone git://sourceware.org/git/glibc.git
$ mkdir -p $HOME/build/glibc
$ cd $HOME/build/glibc
$ $HOME/src/glibc/configure --prefix=/usr
$ make

Do not run make install.


이후 아래 설명을 참고하여, 찾고자 하는 링크 위치를 심볼릭 링크 걸어주면 해결


To do full source code debugging of the C library on Ubuntu, you need to:

1) install the debuginfo version of libc6.

It’s probably already installed, but in case it isn’t, run sudo apt install libc6-dbg.

2) download the source code corresponding to the installed version of the C library.

First, create a directory anywhere – I’ll use /opt/src here. Then do the following:

sudo apt install dpkg-dev
cd /opt/src
apt source libc6
find $PWD -maxdepth 1 -type d -name 'glibc*'

Remember this name – it’ll be something like /opt/src/glibc-2.23

Now, run gdb, run your program until it stops, and at the gdb prompt do this:

(gdb) info source
Current source file is ../sysdeps/unix/sysv/linux/raise.c
Compilation directory is /build/glibc-KM3i_a/glibc-2.23/signal

So gdb is expecting the source code to be in a directory that’s different from where we put it. There are two ways to fix this:

a) move or use a symlink so that the source code is (or appears to be) in /build/glibc-KM3i_a/glibc-2.23 .

b) tell gdb how to substitute the correct source directory pathname: 

  (gdb) set substitute-path /build/glibc-KM3i_a/glibc-2.23 /opt/src/glibc-2.23

Now, go back to your frame, and gdb should show the source code line:

(gdb) frame 1
#1 0xb7e2fea9 in __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:54
         return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);

원격 호스트의 gdb(gdbserver)를 이용하여 로컬에서 debugging 하기.

다음의 세개의 글 참조

#1 https://www.thegeekstuff.com/2014/04/gdbserver-example
#2 https://medium.com/@spe_/debugging-c-c-programs-remotely-using-visual-studio-code-and-gdbserver-559d3434fb78
#3 https://code.visualstudio.com/docs/languages/cpp#_windows-debugging-with-gdb 


How to Debug Programs on Remote Server using GDBServer Example

GDBRemote debugging is the process of debugging a program running on a different system (called target) from a different system (called host).

To start remote debugging, a debugger running on host machine connects to a program which is running on the target via network.

The debugger in the host can then control the execution of the program on the remote system and retrieve information about its state.

Remote debugging is often useful in case of embedded applications where the resources are limited.

In this tutorial, we will see how we can debug programs running on a different system using GDB Server.

If you are new to GDB, you should first understand how to use GDB to debug C program.

We need the following two utilities to perform a remote debugging.

  • gdbserver – Run this on your target system
  • GDB – Execute this on your host system to connect to your target system

GDB and gdbserver communicate via either a serial line or a network, using the standard gdb remote serial protocol.

1. Install gbdserver on Target System

Target machine is the one which is running the program which you have to debug. You need to have the “gdbserver” executable on the target machine.

$ sudo apt-get install gdbserver

To do remote debugging, start your program using the gdbserver. gdbserver then automatically suspends the execution of your program at its entry point, and it waits for a debugger to connect to it. gdbserver doesn’t need the symbols from your program to debug. So you can strip symbols out of your program binary to save space.

$ gdbserver localhost:2000 my_prg 

Process program created; pid = 2045
Listening on port 2000

The above command suspend the execution on my_prg, and waits for a debugger to connect to it on port 2000.

2. Launch gdb on Host System

The executable file and the libraries in the host, must exactly match the executable file and libraries on the target, with an exception that the target binary symbols can be stripped. You can also load the symbols separately in the host using “file” command in gdb.

Run GDB on the host.

$ gdb my_prg
(gdb)

Use “target remote” to connect to the target system.

(gdb) target remote 192.168.1.10:2000

Now you can run the normal gdb commands, as if you are debugging a local gdb program.

3. Remote Debugging Demo Example

The following C program example will be used to demonstrate the remote debugging.

#include <stdio.h>

int power(int,int);

int main() {

        int i;
        printf("Program to calculate power\n");
        for (i=0;i<10;i++)
                printf("%d %d\n",i, power(2,i));
        return 0;
}

int power (int base, int n) {

        int i,p;
        p=1;
        for (i=1; i<=n; i++)
                p = p*base;
        return p;
}

$ cc -g -o my_prg power.c

On Target Machine,

$ gdbserver localhost:2000 my_prg
Process my_prg created; pid = 20624
Listening on port 2000

On Host Machine,

$ gdb my_prg

(gdb) target remote 192.168.1.10:2000
Remote debugging using 192.168.1.10:2000
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007ffff7dddaf0 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x400550
(gdb) continue 
Continuing.

Breakpoint 1, 0x0000000000400550 in main ()

Now we have connected the gdb for remote debugging. In the last example, we have put a breakpoint in main() function. If we continue our program, the output of the program will be printed in the target machine.

On Host:

(gdb) continue

On Target:

Remote debugging from host 192.168.1.20
Program to calculate power
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
8 256
9 512

Child exited with status 0
GDBserver exiting

4. Attach gdb to a Running Process on Target

First you have to find the process ID of the running process in target.

On Host,

(gdb) attach 3850

Now the gdb will suspend the process 3850 in the target and you can debug the program using normal gdb commands.

5. Launch gdbserver in Multi-process Mode

In the previous demo, you would have noticed that once the program executed successfully, the gdbserver also got exited. In real-time, you may want to debug multiple programs remotely, and you may not want to start the gdbserver every time with different program names. Do the following to achieve that.

On Target, run the gdbserver with –multi and without a program name.

$ gdbserver --multi localhost:2000
Listening on port 2000

On Host,

$ gdb

(gdb) target extended-remote 192.168.1.10:2000
Remote debugging using 192.168.1.10:2000

(gdb) (gdb) set remote exec-file /my_prg
(gdb) file /my_prg 
Reading symbols from /my_prg...(no debugging symbols found)...done.
(gdb) b main
Note: breakpoint 1 also set at pc 0x400550.
Breakpoint 2 at 0x400550
(gdb) run
Starting program: /my_prg
Breakpoint 1, 0x0000000000400550 in main ()

From the above snippet,

  1. ‘target extended-remote’ is used to run gdbserver in multi process mode.
  2. ‘set remote exec-file /my_prg’ is used to set the program which you want to debug in the target.
  3. ‘file /my_prg’ is used to load the debugging symbols from the program in the host.
  4. ‘b main’ is used to set breakpoint at main() function.
  5. ‘run’ is used to run the program, which stops at the breakpoint main().

Note: In the above case, the executable “my_prg” is present under “/” on both target and host.

Now either you can ‘continue’ or ‘detach’ the program from debugging. Still the gdbserver will not exit in the target machine, so you can change the ‘remote exec-file’ at any time, and debug a different set of program.


Debugging C/C++ Programs Remotely Using Visual Studio Code and gdbserver

If you’re like me and prefer using a GUI to a command line for setting breakpoints, stepping through code, and inspecting values as your program runs, here is how you can set up VSCode and gdbserver to edit and debug your code locally while running it on a remote server.

Background: I’m working on an assignment for CSC469 at the University of Toronto, and it will only compile and run on the university’s teaching lab machines. My goal was to be able to edit and debug locally in a familiar editor while compiling and running on the remote teaching lab machines.

Note: I’m using macOS Sierra locally, with the remote machine running Ubuntu 14.04, but this guide should work with any Unix system. (Sorry, Windows users).

Note: Commands to be run on the remote machine are prefixed with remote$and local commands are prefixed with local$ .

1. Install gdbserver on the remote machine

Installation varies by system. On Debian/Ubuntu, you can do:

remote$ apt-get install gdbserver

Since students are not allowed to install software via apt on the U of T machines, I used Linuxbrew to install it to my user folder:

remote$ brew install gdbserver

2. Install gdb on your local machine

On macOS Sierra, I used Homebrew to install gdb:

local$ brew install gdb --with-all-targets

Note: The --with-all-targets option is important; without it, you won’t be able to debug on a remote machine with a different OS or architecture than your local machine.

3. Test gdb

At this point, you should be able to run gdbserver on the remote machine and connect to it from your local gdb CLI. I’ll use the -L option of ssh to forward local port 9091 connections to the remote port 9091:

local$ ssh -L9091:localhost:9091 user@remote
remote$ cd ./myproject/ && make
remote$ gdbserver :9091 ./myprogram

(Port 9091 is arbitrary; use any port number you like)

Leave that command running in a terminal window; it will wait until gdb connects before running ./myprogram .

In another terminal window on your local machine, run gdb:

local$ gdb
GNU gdb (GDB) 7.12
Copyright (C) 2016 Free Software Foundation, Inc.
...
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)

Then connect to the gdbserver instance:

(gdb) target remote localhost:9091
Remote debugging using localhost:9091
...
(gdb)

To verify things are working, you can run various gdb commands like info sources , or set a breakpoint with break . Use continue to run ./myprogram .

4. codesign gdb

VSCode prevents you from running gdb unless it’s signed; follow these steps to ensure it’s signed.

5. Synchronize local and remote file systems

You may have noticed that, for basic functionality, the gdb CLI on your local machine doesn’t need to be provided any information about the program or its source code except for the host and port on which gdbserver is running. But there are two big reasons why you’ll want to keep your local and remote project directories in sync:

  • Viewing source code in the gdb CLI (i.e. list).
  • The VSCode C/C++ extension requires you to provide the path to the compiled executable to launch gdb. (The "program" field in launch.json).

I opted to use sshfs since it required the least server-side setup, but you could use NFS, rsync, or other alternatives.

Using sshfs, mount the remote project folder locally:

local$ mkdir ./myproject
local$ sshfs user@remote:myproject ./myproject

Note: on macOS, you can later unmount the directory with umount ./myproject. On Linux, use fusermount -u ./myproject.

6. Configure Visual Studio Code

Open your newly-mounted project ./myproject/ in VSCode, then open .vscode/launch.json or create it if it doesn’t exist:

{
"version": "0.2.0",
"configurations": [
{
"name": "C++ Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/myprogram",
"miDebuggerServerAddress": "localhost:9091",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"linux": {
"MIMode": "gdb"
},
"osx": {
"MIMode": "gdb"
},
"windows": {
"MIMode": "gdb"
}
}
]
}

This configuration will make it so clicking “C++ Launch” will run gdb similar to:

local$ gdb ./myprogram
...
(gdb) target remote localhost:9091

7. Write a script to compile your program and launch gdbserver

Ideally, you’d want to be able to run a single command or click a single button to compile & debug your program.

This might be possible to do via VSCode tasks and the preLaunchTask option in launch.json, but I was not able to put together a simple solution using those.

Instead I wrote a quick-and-dirty shell script prepare_remote_debug.sh :

# Kill gdbserver if it's running
ssh user@remote killall gdbserver &> /dev/null
# Compile myprogram and launch gdbserver, listening on port 9091
ssh \
-L9091:localhost:9091 \
user@remote \
"zsh -l -c 'cd myproject && make && gdbserver :9091 ./myprogram'"

8. Start debugging

Here is your new workflow:

  1. Edit some code.
  2. Run ./prepare_remote_debug.sh in a terminal window. Your program’s output will appear here.
  3. Set some breakpoints.
  4. Run “C++ Launch”.
  5. Step through your code in VSCode’s debugger.
  6. Repeat.

That’s it! I hope this helps someone, and let me know if it can be simplified even further.


C/C++ for VS Code (Preview)

C/C++ support for Visual Studio Code is provided by a Microsoft C/C++ extension to enable cross-platform C and C++ development using VS Code on Windows, Linux, and macOS. The extension is still in preview and our focus is code editing, navigation, and debugging support for C and C++ code everywhere that VS Code runs.

cpp hero

If you just want a lightweight tool to edit your C++ files, Visual Studio Code is a great choice but if you want the best possible experience for your existing Visual C++ projects or debugging on Windows, we recommend you use a version of Visual Studio such as Visual Studio Community.

If you run into any issues or have suggestions for the Microsoft C/C++ extension, please file issues and suggestions on GitHub. If you haven’t already provided feedback, please take this quick survey to help shape this extension for your needs.

Note for Linux users: The C/C++ extension works on 64-bit Linux distros that have glibc 2.18 or later installed.

Getting Started

To install the Microsoft C/C++ extension:

  • Open VS Code.
  • Click the Extensions View icon on the Sidebar.
  • Search for c++.
  • Click Install, then click Reload.

cpp extension

With the C/C++ extension installed, open a folder that contains your C/C++ source code. VS Code will place various settings files into a .vscode subfolder.

Note: The C/C++ extension does not include a C++ compiler or debugger. You will need to install these tools or use those already installed on your computer. Popular C++ compilers are MinGW for Windows, XCode for macOS, and GCC on Linux. Also make sure your compiler executable is on your platform path for VS Code to find.

IntelliSense

To enable code completion and navigation, you will need to generate a c_cpp_properties.json file:

  • Find any green squiggle in a source file (for example, an #include statement) and set the cursor on the line.
  • Click the lightbulb that appears in the left gutter.
  • Click Update “browse.path” setting.

browse path light bulb

This will generate a c_cpp_properties.json file that allows you to add additional browse paths to properly enable code navigation and auto-completion. The generated c_cpp_properties.json file has sections for different operating systems, make sure you update the appropriate settings for your current platform.

Below you can see that the MinGW C++ include path has been added to browse.path for Windows:

{
    "name": "Win32",
    "includePath": [
        "${workspaceFolder}"
    ],
    "defines": [
        "_DEBUG",
        "UNICODE"
    ],
    "intelliSenseMode": "msvc-x64",
    "browse": {
        "path": [
            "${workspaceFolder}",
            "C:\\MinGW\\lib\\gcc\\mingw32\\6.3.0\\include\\c++"
        ],
        "limitSymbolsToIncludedHeaders": true,
        "databaseFilename": ""
    }
}

Note: You can also generate or edit a c_cpp_properties.json file with the C/Cpp: Edit Configurations command from the Command Palette (Ctrl+Shift+P).

Building your code

If you want to build your application from VS Code, you will need to generate a tasks.json file:

  • Open the Command Palette (Ctrl+Shift+P).
  • Select the Tasks: Configure Tasks… command, click Create tasks.json file from templates, and you will see a list of task runner templates.
  • Select Others to create a task which runs an external command.
  • Change the command to the command line expression you use to build your application (for example g++).
  • Add any required args (for example -g to build for debugging).
  • You can also change the label to be more descriptive.

You should now see a tasks.json file in your workspace .vscode folder that looks something like:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build hello world",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g", "helloworld.cpp"
            ]
        }
    ]
}

If you’d like to be able to build your application with Tasks: Run Build Task (Ctrl+Shift+B), you can add it to the build group.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build hello world",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g", "helloworld.cpp"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

For more information on tasks, see Integrate with External Tools via Tasks.

Debugging your code

To enable debugging, you will need to generate a launch.json file:

  • Navigate to the Debug view by clicking the Debug icon in the Sidebar.
  • In the Debug view, click the Configure icon.
  • Select C++ (GDB/LLDB) (to use GDB or LLDB) or C++ (Windows) (to use the Visual Studio Windows Debugger) from the Select Environment dropdown. This creates a launch.json file for editing with two configurations:
    • C++ Launch defines the properties for launching your application when you start debugging.
    • C++ Attach defines the properties for attaching to a process that’s already running.
  • Update the program property with the path to the program you are debugging.
  • If you want your application to build when you start debugging, add a preLaunchTask property with the name of the build task you created in tasks.json (“build hello world” in the example above).

Below is an example using the MinGW GDB debugger:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/a.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\mingw\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build hello world"
        }
    ]
}

To learn more, see Configuring launch.json for C/C++ debugging.

If you are debugging with GDB on Windows, see Windows Debugging with GDB.

Editing Code

Code Formatting

The C/C++ extension for Visual Studio Code supports source code formatting using clang-format which is included with the extension.

You can format an entire file with Format Document (Shift+Alt+F) or just the current selection with Format Selection (Ctrl+K Ctrl+F) in right-click context menu. You can also configure auto-formatting with the following settings:

  • C_Cpp.clang_format_formatOnSave – to format when you save your file.
  • editor.formatOnType – to format as you type (triggered on the ; character).

By default, the clang-format style is set to “file” which means it looks for a .clang-format file inside your workspace. If the .clang-format file is found, formatting is applied according to the settings specified in the file. If no .clang-format file is found in your workspace, formatting is applied based on a default style specified in the C_Cpp.clang_format_fallbackStyle setting instead. Currently, the default formatting style is “Visual Studio”. Using “Visual Studio” formatting ensures that source code formatting will be compatible in both VS Code and Visual Studio Community.

The “Visual Studio” clang-format style is not yet an official OOTB clang-format style but it implies the following clang-format settings:

UseTab: (VS Code current setting)
IndentWidth: (VS Code current setting)
BreakBeforeBraces: AllMan
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 0

If you’d like to use a different version of clang-format than the one that ships with the extension, you can use the C_Cpp.clang_format_path setting and set its value to the path where the clang-format binary is installed.

For example on the Windows platform:

  "C_Cpp.clang_format_path": "C:\\Program Files (x86)\\LLVM\\bin\\clang-format.exe"

Fuzzy Auto-Complete

Fuzzy auto-complete is powered by an enhanced tag-parser approach. Although suggestions are not based on semantic analysis of your code, this feature provides a wider selection of matches than the single-file IntelliSense experience provided today.

In particular, this feature’s capabilities give a good experience for C code.

Navigating Code

The source code navigation features provided by the C/C++ extension are powerful tools for understanding and getting around in your codebase. These features are powered by tags stored in an offline database of symbol information. With the C/C++ extension installed, this database is generated whenever a folder containing C++ source code files is loaded into VS Code. The platform indicator (Win32 in the figure below) turns red and appears next to a flame icon while the tag-parser is generating this information.

The platform indicator during tag parsing

When the platform indicator returns to its normal appearance, the source code symbols have been tagged in the offline database and source code navigation features are ready to be used.

Specifying Additional Include Directories for Better Symbol Support

To provide the best experience, the C/C++ extension for VS Code needs to know where it can find each header file referenced in your code. By default, the extension searches the current source directory, its sub-directories, and some platform-specific locations. If a referenced header file can’t be found, VS Code displays a green squiggle underneath each #include directive that references it.

To specify additional include directories to be searched, place your cursor over any #include directive that displays a green squiggle, then click the lightbulb action when it appears. This opens the file c_cpp_properties.json for editing; here you can specify additional include directories for each platform configuration individually by adding more directories to the ‘browse.path’ property.

Search for Symbols

You can search for symbols in the current file or workspace to navigate your code more quickly.

To search for a symbol in the current file, press Ctrl+Shift+O, then enter the name of the symbol you’re looking for. A list of potential matches will appear and be filtered as you type. Choose from the list of matches to navigate to its location.

Searching the current file

To search for a symbol in the current workspace, start by pressing Ctrl+T instead, then enter the name of the symbol. A list of potential matches will appear as before. If you choose a match that was found in a file that’s not already open, the file will be opened before navigating to the match’s location.

Searching in your workspace

Alternatively, you can search for symbols by accessing these commands through the Command Palette if you prefer. Use Quick Open (Ctrl+P) then enter the ‘@’ command to search the current file, or the ‘#’ command to search the current workspace. Ctrl+Shift+O and Ctrl+T are just shortcuts for the ‘@’ and ‘#’ commands, respectively, so everything works the same.

Peek Definition

You can take a quick look at how a symbol was defined by using the Peek Definition feature. This feature displays a few lines of code near the definition inside a peek window so you can take a look without navigating away from your current location.

To peek at a symbol’s definition, place your cursor on the symbol anywhere it’s used in your source code and then press Alt+F12. Alternatively, you can choose Peek Definition from the context menu (right-click, then choose Peek Definition).

Peek definition

Currently, the C/C++ extension doesn’t parse code in a way that helps it distinguish between competing definitions based on how the symbol is used. These competing definitions arise when the symbol defines different things in different contexts, such as occurs with overloaded functions, classes and their constructors, and other situations. When this happens, each of the competing definitions are listed in the right-hand side of the peek window with the source code of the current selection displayed on the left.

With the peek window open, you browse the list of competing definitions to find the one you’re interested in. If you want to navigate to the location of one of the definitions just double-click the definition you’re interested in, or by double-clicking anywhere in the source code displayed on the left-hand side of the peek window.

Go to Definition

You can also quickly navigate to where a symbol is defined by using the Go to Definition feature.

To go to a symbol’s definition, place your cursor on the symbol anywhere it is used in your source code and then press F12. Alternatively, you can choose Go to Definition from the context menu (right-click, then choose Go to Definition). When there’s only one definition of the symbol, you’ll navigate directly to its location, otherwise the competing definitions are displayed in a peek window as described in the previous section and you have to choose the definition that you want to go to.

Debugging

After you have set up the basics of your debugging environment as specified in Getting Started, you can learn more details about debugging C/C++ in this section.

VS Code supports the following debuggers for C/C++ depending on the operating system you are using:

  • Linux: GDB
  • macOS: LLDB or GDB
  • Windows: the Visual Studio Windows Debugger or GDB (using Cygwin or MinGW)

Windows Debugging with GDB

You can debug Windows applications created using Cygwin or MinGW by using VS Code. To use Cygwin or MinGW debugging features, the debugger path must be set manually in the launch configuration (launch.json). To debug your Cygwin or MinGW application, add the miDebuggerPath property and set its value to the location of the corresponding gdb.exe for your Cygwin or MinGW environment.

For example:

    "miDebuggerPath": "c:\\mingw\\bin\\gdb.exe"

Cygwin/MinGW debugging on Windows supports both attach and launch debugging scenarios.

Conditional Breakpoints

Conditional breakpoints enable you to break execution on a particular line of code only when the value of the condition is true. To set a conditional breakpoint, right-click on an existing breakpoint and select Edit Breakpoint. This opens a small peek window where you can enter the condition that must evaluate to true in order for the breakpoint to be hit during debugging.

A conditional break

In the editor, conditional breakpoints are indicated by a breakpoint symbol that has a black equals sign inside of it. You can place the cursor over a conditional breakpoint to show its condition.

Function Breakpoints

Function breakpoints enable you to break execution at the beginning of a function instead of on a particular line of code. To set a function breakpoint, on the Debug pane right-click inside the Breakpointssection, then choose Add Function Breakpoint and enter the name of the function on which you want to break execution.

Expression Evaluation

VS Code supports expression evaluation in several contexts:

  • You can type an expression into the Watch section of the Debug panel and it will be evaluated each time a breakpoint is hit.
  • You can type an expression into the Debug Console and it will be evaluated only once.
  • You can evaluate any expression that appears in your code while you’re stopped at a breakpoint.

Note that expressions in the Watch section take effect in the application being debugged; an expression that modifies the value of a variable will modify that variable for the duration of the program.

Multi-threaded Debugging

The C/C++ extension for VS Code has the ability to debug multi-threaded programs. All threads and their call stacks appear in the Call Stack section:

Multi-threaded process

Memory Dump Debugging

The C/C++ extension for VS Code also has the ability to debug memory dumps. To debug a memory dump, open your launch.json file and add the coreDumpPath (for GDB or LLDB) or dumpPath (for the Visual Studio Windows Debugger) property to the C++ Launch configuration, set its value to be a string containing the path to the memory dump. This will even work for x86 programs being debugged on an x64 machine.

Additional Symbols

If there are additional directories where the debugger can find symbol files (for example, .pdb files for the Visual Studio Windows Debugger), they can be specified by adding the additionalSOLibSearchPath(for GDB or LLDB) or symbolSearchPath (for the Visual Studio Windows Debugger).

For example:

    "additionalSOLibSearchPath": "/path/to/symbols;/another/path/to/symbols"

or

    "symbolSearchPath": "C:\\path\\to\\symbols;C:\\another\\path\\to\\symbols"

Locate source files

The source file location can be changed if the source files are not located in the compilation location. This is done by simple replacement pairs added in the sourceFileMap section. The first match in this list will be used.

For example:

"sourceFileMap": {
    "/build/gcc-4.8-fNUjSI/gcc-4.8-4.8.4/build/i686-linux-gnu/libstdc++-v3/include/i686-linux-gnu": "/usr/include/i686-linux-gnu/c++/4.8",
    "/build/gcc-4.8-fNUjSI/gcc-4.8-4.8.4/build/i686-linux-gnu/libstdc++-v3/include": "/usr/include/c++/4.8"
}

GDB, LLDB and MI Commands (GDB/LLDB)

For the C++ (GDB/LLDB) debugging environment, you can execute GDB, LLDB and MI commands directly through the debug console with the -exec command, but be careful, executing commands directly in the debug console is untested and might crash VS Code in some cases.

Other Debugging Features

  • Unconditional breakpoints
  • Watch window
  • Call stack
  • Stepping

For more information on debugging with VS Code, see this introduction to debugging in VS Code.

Known Limitations

Symbols and Code Navigation

All platforms:

  • Because the extension doesn’t parse function bodies, Peek Definition and Go to Definition don’t work for symbols defined inside the body of a function.

Debugging

Windows:

  • GDB on Cygwin and MinGW cannot break a running process. To set a breakpoint when the application is running (not stopped under the debugger), or to pause the application being debugged, press Ctrl-C in the application’s terminal.
  • GDB on Cygwin cannot open core dumps.

Linux:

  • GDB needs elevated permissions to attach to a process. When using attach to process, you need to provide your password before the debugging session can begin.

macOS:

  • LLDB:
    • When debugging with LLDB, if the Terminal window is closed while in break mode, debugging does not stop. Debugging can be stopped by pressing the Stop button.
    • When debugging is stopped the Terminal window is not closed.
  • GDB:
    • Additional manual install steps need to be completed to use GDB on macOS. See Manual Installation of GDB for OS X in the README.
    • When attaching to a process with GDB, the application being debugged cannot be interrupted. GDB will only bind breakpoints set while the application is not running (either before attaching to the application, or while the application is in a stopped state). This is due to a bug in GDB.
    • Core dumps cannot be loaded when debugging with GDB because GDB does not support the core dump format used in macOS.
    • When attached to a process with GDB, break-all will end the process.

Next Steps

Read on to find out about:

  • Basic Editing – Learn about the powerful VS Code editor.
  • Code Navigation – Move quickly through your source code.
  • Tasks – use tasks to build your project and more
  • Debugging – find out how to use the debugger with your project

Common Questions

Q: My project won’t load.

A: VS Code doesn’t currently support C++ project files, instead it considers a directory of your choosing to be the workspace of your project. Source code files inside that directory and its sub-directories are part of the workspace.

Q: How do I build/run my project?

A: VS Code supports tasks that you can configure to build your application, and natively understands the output of MSBuild, CSC, and XBuild. For more information, see the Tasks documentation.

If you have any other questions or run into any issues, please file an issue on GitHub.

Ubunt 16.04 – apt-get install 시, “E: Failed to fetch 403 Forbidden” 오류 발생시,

Ubuntu 16.04에서, 
apt-get install 로 package 설치시,

해당 패키지에 접근할 수 없다는 오류

E: Failed to fetch  ‘패키지 이름’ 403  Forbidden

가 발생시, 
간단하게

다음과 같이 해결 할 수 있다.

우선 /etc/appt/sources.list 파일을 백업 한후,

기존 sources.list 내용을 지우고 다음과 같이 2줄을 추가.

[#M_ more.. | less.. |deb http://archive.ubuntu.com/ubuntu xenial main universe restricted multiverse
deb-src http://archive.ubuntu.com/ubuntu xenial main universe restricted multiverse
_M#]

하고 다시

apt-get update 를 해주면 정상적으로 package가 설치됨.

[Mac] 특정 네트워크 인터페이스에 static route 정보 설정

출처 : http://egloos.zum.com/mcchae/v/11263102

Mac 에서 (Sierra) static route를 설정할 필요가 있습니다.

예를 들어,
Wi-Fi 로 연결된 자신의 주소가 192.168.10.100 이었고,
192.168.10.200 이라는 내부 라우터가
192.168.100.0/24 네트워크를 라우팅할 필요가 있다면
터미널에서
$ sudo route -n add 192.168.100.0/24 192.168.10.200
라고 명령을 주면 됩니다.
문제는 다음에 재기동하면 다시 이 정보가 없어지는 문제가 있지요.
다음은 간단히 networksetup 명령을 이용하여 static routing 정보를
시스템에 등록하는 방법입니다.
우선 현재 시스템에 설치된 인터페이스를 검색합니다.
$ networksetup -listallnetworkservices
An asterisk (*) denotes that a network service is disabled.
Wi-Fi
USB 10/100/1000 LAN
iPhone USB
Bluetooth PAN
Thunderbolt Bridge
Wi-Fi 인터페이스에 지정된 정보를 확인합니다.
$ networksetup -getinfo Wi-Fi
DHCP Configuration
IP address: 192.168.10.160
Subnet mask: 255.255.255.0
Router: 192.168.10.1
Client ID:
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: 80:e6:50:0f:1a:f4
혹시 이전에 설정한 static 정보가 있는지 확인합니다.
$ networksetup -getadditionalroutes Wi-Fi
There are no additional IPv4 routes on Wi-Fi.
 
이제는 위에서 설명한 것과 같은 static 라우팅 정보를 지정합니다.
$ sudo networksetup -setadditionalroutes Wi-Fi 192.168.100.0 255.255.255.0 192.168.10.200
다시 부팅을 하거나 해도 다음과 같이 정적 라우팅 정보를 확인해 보면,
$ networksetup -getadditionalroutes Wi-Fi
192.168.100.0 255.255.255.0 192.168.10.200
과 같이 정적 라우팅이 지정됩니다.

Synology NAS DSM 6.2 업데이트 후, SSH 로그인 실패 현상

DSM 6.2 업데이트 이전에는 잘되던 SSH가 갑지가 6.2 업데이트 후 SSH 접속이 되지 않을 경우,

다음에 따라 수정할 것.

1. telnet 활성화.
2. telnet 을 통해 admin 계정 접속 후,
3. 다음의 파일 수정
  파일 : /etc/ssh/sshd_config

ChallengeResponseAuthentication 는 yes
UsePAM 는 no
로 변경 후,

저장
4. SSH 재시작
  명령어 : killall -1 sshd

이후 SSH 가 접속되는 것을 확인 후 telnet은 비활성화