piątek, 30 października 2015

valgrind - szukanie wycieków pamięci

Chciałbym zaprezentować pożyteczny program konsolowy valgrind, który bada wycieki pamięci w programach.

Wyciek pamięci (ang. memory leak) – niezamierzone użycie pamięci przez program komputerowy, gdy nie zwalnia on zaalokowanej wcześniej pamięci, która nie jest już mu potrzebna.

Wycieki pamięci są efektem bardzo niepożądanym. Program bowiem zajmuje coraz więcej pamięci, ale nie jest w stanie jej wykorzystać ani zwolnić. Szczególnie w aplikacjach, które działają przez długi czas (w większości serwerowych), efekt wycieku pamięci stopniowo narasta. Sam wyciek prowadzi do spadku wydajności systemu, w skrajnym przypadku zawieszenia się programu lub innych programów, którym system nie może przydzielić wystarczającej ilości pamięci, a nawet zablokowania całego systemu operacyjnego. Kod programu, który powoduje wycieki pamięci, jest kodem błędnym.

Użycie programu valgrind jest bardzo proste:

valgrind nazwa_programu

np.:

valgrind putty
valgrind ./myprog

Wynikiem powyższych poleceń jest uruchomienie danego programu, a po jego zakończeniu wyświetlenie ilości bajtów, które wyciekły.

Program valgrind przydaje się, gdy na komputerze uruchamiamy program, który po pewnym czasie zaczyna "mulić". Można wtedy sprawdzić, czy nie ma dużych wycieków pamięci.

W językach programowania takich jak Java czy C# problem wycieków pamięci został częściowo zniwelowany poprzez zastosowanie odśmiecania pamięci (ang. Garbage Collector). W językach C i C++ programista musi zwalniać pamięć. Poniżej przykład programu w C, który nie zwalnia zaalokowanej wcześniej pamięci na zmienną typu int (4 bajty):

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

int main(void)
{
  int *x = malloc(sizeof(int));
  *x = 16;
  printf("%d\n",*x);
  return 0;
}

Powyższy kod kompilujemy następująco:

gcc memleak.c -o memleak

Sprawdzamy wycieki pamięci:

valgrind ./memleak

Dostajemy informację, że wyciekły 4 bajty.

Poprawnie napisany program powinien zawierać funkcję free(), która zwalnia zarezerwowaną wcześniej pamięć:
 
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int *x = malloc(sizeof(int));
  *x = 16;
  printf("%d\n",*x);
  free(x);
  return 0;
}

środa, 10 czerwca 2015

Podstawy systemu JunOS

W dzisiejszym poście omówię podstawy konfiguracji urządzeń sieciowych firmy Juniper Networks przy pomocy CLI systemu operacyjnego JunOS. System ten oparty jest na jądrze FreeBSD i zawiera obsługę większości używanych współcześnie protokołów routingu.

Nasz przykładowy router R1 posiada dwa interfejsy sieciowe em0 oraz em1.


Legenda do rysunku:
R1 - router Juniper
SW1 - switch 1
SW2 - switch 2
C1 - host 1
C2 - host 2
C3 - host 3
C4 - host 4
 
W systemie JunOS nie da się ustawić adresu IP bezpośrednio na fizycznym interfejsie sieciowym, tylko na logicznym zwanym unitem. Każdy unit posiada swój identyfikator w postaci liczby całkowitej. W naszym przypadku jest to 0, czyli mamy unit 0 na em0 (em0.0) oraz unit 0 na em1 (em1.0). Identyfikator unitu jest dowolną liczbą całkowitą.

W naszym przypadku będziemy mieć następującą adresację interfejsów:
em0.0 : 192.168.0.1 z maską 255.255.255.0
em1.0 : 10.10.10.1 z maską 255.255.255.0

System JunOS może pracować w dwóch trybach:
- Operational Mode - do odczytywania informacji i monitorowania urządzenia;
- Configuration Mode - do zmiany konfiguracji urządzenia.
Tryby te można rozróżnić po znaku zachęty:
> Operational Mode
# Configuration Mode

Domyślnie pracujemy w Operational Mode. Aby przejść do Configuration Mode trzeba wydać polecenie:

root> configure

Powrót do Operational Mode:

root# exit

Aby odczytać konfigurację wydajemy polecenie:

root> show configuration

Aby uzyskać pomoc wydajemy polecenie:

root> ?

Co robi dana komenda dowiemy się tak:

root> show?

Listę opcji (dopełnień) danej komendy uzyskamu tak:

root> show ?

Przejdźmy teraz do konfiguracji interfejsów sieciowych. Chcemy wyświetlić bieżącą informację o interfejsach:

root> show interfaces terse


Teraz chcemy ustawić adresację na em0.0:

root> configure

root# set interfaces em0 unit 0 family inet address 192.168.0.1/24

root# commit

Komendy są prawidłowe, ale i tak dostaniemy błąd Missing mandatory statement: 'root-authentication'. Chodzi o to, że domyślnie konto root-a nie ma założonego hasła. Trzeba je założyć:

root# set system root-authentication plain-text-password

root# commit

Polecenie commit zatwierdzi zmianę hasła dla root-a, ale również poprzednią komendę set interfaces, która wygenerowała błąd.

Możemy teraz ustawić IP na em1.0:

root# set interfaces em1 unit 0 family inet address 10.10.10.1/24

root# commit

Przechodzimy do Operational Mode i wyświetlamy interfejsy:

root# exit

root> show interfaces terse

 
Jak widać udało się ustawić adresację na interfejsach sieciowych.

wtorek, 14 kwietnia 2015

ODBC w Linuksie

ODBC (ang. Open DataBase Connectivity - otwarte łącze baz danych) - interfejs pozwalający programom łączyć się z systemami zarządzającymi bazami danych. Jest to API niezależne od języka programowania, systemu operacyjnego i bazy danych. W skład ODBC wchodzą wywołania wbudowane w aplikacje oraz sterowniki ODBC. Pierwsza implementacja ODBC pojawiła się w systemie Windows, lecz obecnie możliwe jest korzystanie z niego na platformach Unix, Linux oraz Macintosh.

W systemie Windows zarządzanie sterownikami ODBC oraz źródłami danych jest bardzo proste i od razu dostępne w systemie - wystarczy wejść w Panel sterowania -> Narzędzia administracyjne -> Źródła danych (ODBC).

Pod linuksem sytuacja jest trochę bardziej skomplikowana:

1. Trzeba zainstalować pakiet unixodbc:

sudo apt-get install unixodbc

Jest to główna biblioteka ODBC dla systemu Linux. Pakiet unixodbc zawiera także narzędzie wiersza poleceń isql, umożliwiające interaktywne wprowadzanie poleceń SQL.

2. Powinniśmy też zainstalować pakiet unixodbc-bin dostarczający graficznych narzędzi do zarządzania sterownikami i źródłami danych:

sudo apt-get install unixodbc-bin

Pakiet ten oferuje dwa pożyteczne graficzne narzędzia:

ODBCManageDataSourcesQ4 - zarządzanie źródłami danych i sterownikami ODBC 



ODBCCreateDataSourceQ4 - kreator źródeł danych




3. Teraz można już instalować sterowniki ODBC do różnych baz danych. Część można znaleźć w Menedżerze Pakietów np. synaptic a część na stronie:


4. Przykład - sterownik SQLite ODBC

sudo apt-get install libsqliteodbc

Efekt jest następujący:


Wystarczy teraz skonfigurować źródło danych (Data Source Names w ODBCManageDataSourcesQ4 lub za pomocą kreatora ODBCCreateDataSourceQ4) i można się do niego podpiąć różnymi programami, które korzystają z ODBC np. LibreOffice Base.

Do testów na wyciągnięcie ręki mamy na przykład dane przechowywane przez Firefoksa w katalogu domowym użytkownika /home/user/.mozilla/firefox. Są to pliki .sqlite np. places.sqlite - baza, która  w swoich tabelach trzyma zakładki i historię przeglądania.

piątek, 20 marca 2015

watch - pożyteczne linuksowe polecenie

Za pomocą polecenia watch możemy cyklicznie wywoływać inne polecenie (proces) w terminalu. Wynik wywoływanego polecenia wyświetla się standardowo co 2 sekundy bez przewijania ekranu konsoli, dzięki czemu odnosimy wrażenie uruchomionego programu przez cały czas. Czas odświeżania procesu możemy zmieniać za pomocą parametru -n.

Wynik działania komendy watch free:



Parametry programu watch:

-n - zmiana czasu (w sekundach) wywoływania procesu, np.:
      -n 0  - 0.1 sekundy
      -n 1  - 1 sekunda
      -n 3  - 3 sekundy
-d - podświetla zmiany
-t - nie wyświetla nagłówka

Przykłady użycia:

watch -n 0 free - monitoruje wykorzystanie pamięci,

watch sensors - monitorowanie temperatur np. temperatury procesora,

watch "dmesg | tail -20" - monitorowanie stanu urządzeń i innych zdarzeń systemowych, np. gdy coś podłączymy do USB, to zobaczymy informacje o tym urządzeniu.

czwartek, 12 marca 2015

Kurs Bash cz.2

1. Arytmetyka

W bashu mamy następujące operatory arytmetyczne:

+ dodawanie
- odejmowanie
* mnożenie
/ dzielenie
% reszta z dzielenia (modulo)
** potęgowanie

Przykład wykorzystania tych operatorów:

#!/bin/bash

X=9
Y=4

# dodawanie
let Z=X+Y
echo "$X + $Y = $Z"

# odejmowanie
let Z=X-Y
echo "$X - $Y = $Z"

# mnozenie
let Z=X*Y
echo "$X * $Y = $Z"

# dzielenie
let Z=X/Y
echo "$X / $Y = $Z"

# reszta z dzielenia (modulo)
let Z=X%Y
echo "$X modulo $Y = $Z"

# potegowanie
let Z=X**Y
echo "$X^$Y = $Z"


Uruchamiając powyższy skrypt widać, że bash operuje tylko na liczbach całkowitych tzn. 9/4 =2. Resztę z dzielenia otrzymujemy po wykonaniu operacji modulo.

Mamy też operatory arytmetyczne bitowe:

>> przesunięcie bitowe w prawo
<< przesunięcie bitowe w lewo
~ bitowa negacja
& AND bitowe
| OR bitowe
^ XOR bitowe

#!/bin/bash

X=8
Y=1

# przesuniecie bitowe w prawo
let "Z=X>>2"
echo "$Z"

# przesuniecie bitowe w lewo
let "Z=X<<2"
echo "$Z"

# bitowa negacja
let "Z=~X"
echo "$Z"

# AND bitowe
let "Z=X&Y"
echo "$Z"

# OR bitowe
let "Z=X|Y"
echo "$Z"

# XOR bitowe
let "Z=X^Y"
echo "$Z"

W bashu można też przeliczać systemy liczbowe:

#!/bin/bash

declare -i a #deklaracja zmiennej calkowitej

#BIN->DEC
a=2#1001
echo $a

#HEX->DEC
a=16#EF
echo $a

2. Pętle

Pętla for - wykonuje polecenia zawarte wewnątrz pętli, na każdym składniku listy (iteracja).

for zmienna in lista
do
  polecenia
done


Na poniższym przykładzie mamy dwie pętle for. Pierwsza wyświetla elementy listy a druga wszystkie pliki o rozszerzeniu .sh:

#!/bin/bash

for x in apple pear strawberry
do
  echo "This is $x"
done

for plik_sh in *.sh
do
  echo $plik_sh
done

I tu przychodzi następujące pytanie - jak odliczać kolejne wartości liczbowe w pętli for. Jest kilka sposobów. Oto  jeden z nich:

#!/bin/bash

for i in {1..10}
do
  echo $i
done

Pętla while - sprawdza warunek czy jest prawdziwy, jeśli tak to wykonane zostaną polecenia wewnątrz pętli, gdy warunek stanie się fałszywy pętla zostanie zakończona.

while warunek
do
polecenia
done


Przykład:

#!/bin/bash

x=1

while [ $x -le 10 ] #-le mniejsze badz rowne
do
echo $x
x=$[x+1]
done

Pętla until - działa odwrotnie niż while; polecenia w pętli wykonywane są, gdy warunek jest fałszywy - aż stanie się prawdziwy.

until warunek
do
polecenia
done


Przykład:

#!/bin/bash

x=1

until [ $x -ge 10 ] #-le wieksze badz rowne
do
echo $x
x=$[x+1]
done

Koniec części drugiej, cdn. 

niedziela, 22 lutego 2015

Android: TrackID™ - rozpoznawanie utworów muzycznych

Ostatnio w radiu leciał fajny utwór. Niestety nie mogłem ustalić tytułu i wykonawcy tego utworu. Postanowiłem sobie coś zainstalować na przyszłość w telefonie z Androidem do takiego rozpoznawania muzyki.
Na Google play znalazłem aplikację TrackID™. Ma ona bardzo dużą bazę utworów i rozpoznaje utwory muzyczne po naciśnięciu jednego przycisku po kilku sekundach. Wystarczy nagrać utwór muzyczny z telewizora, radia lub dowolnego głośnika zewnętrznego.
Oprócz wykonawcy i tytułu, TrackID™ podaje także informacje o albumie, z którego pochodzi dany utwór.

wtorek, 17 lutego 2015

Oracle Solaris 11.2 - brak GUI

Po instalacji systemu Oracle Solaris 11.2 brakuje środowiska graficznego. Wystarczą trzy polecenia w konsoli tekstowej, aby mieć Gnoma.

Sprawdzenie statusu pakietu solaris-desktop:

pkg info -r solaris-desktop

Instalacja pakietu solaris-desktop:

pkg install solaris-desktop

Restart systemu:

shutdown -i6 -g0 -y

Opis parametrów polecenia shutdown znajduje się tutaj.

niedziela, 15 lutego 2015

Kurs Bash cz.1

1. Wstęp

Bourne Again Shell (bash) - jest to jedna z wielu powłok występujęcych w systemach uniksowych. Wywodzi się od powłoki Bourne'a sh, która była jedną z pierwszych i najważniejszych powłok systemu Unix oraz zawiera pomysły zawarte w powłokach ksh i csh. Poza tym bash jest również językiem skryptowym.

2. Pierwszy skrypt

Tworzymy nowy plik np. hello.sh a potem nadajemy mu uprawnienia do wykonywania (uruchamiania).

chmod +x hello.sh

W tym pliku wpisujemy kod skryptu np.:

#!/bin/bash
#To jest komentarz
echo "Hello World"

Wykonanie skryptu:

./hello.sh

3. Polecenie echo

Polecenie echo wyświetla napis lub zmienną na ekranie.

Przykłady:

echo "Hello World"
echo "$ZMIENNA"
echo -e "Hello World \n"

Parametr -e umożliwia stosowanie znaków specjalnych np.:

\b - backspace
\n - nowa linia
\t - tabulacja pozioma
\xnn - znak ASCII o wartości szesnastkowej
\unnnn - znak Unicode o wartości szesnastkowej

unicode-table.com - tabela znaków Unicode.

4. Zmienne

Zmienne w bashu mogą być typu tekstowego lub liczbowego, ale też mogą służyć do cytowania poleceń. Myślę, że najlepiej typy zmiennych pokaże nam poniższy przykład.

#!/bin/bash

#zmienne lancuchowe
S1="Zmienna tekstowa (lancuch znakow)"
echo $S1
S2='To tez jest lancuch znakow'
echo $S2

#cytowanie polecen
C=`uname -a`
echo $C

#liczba
X=31
echo $X

W bashu istnieją także zmienne specjalne:

$0 - nazwa naszego skryptu
$# - liczba przekazanych parametrów
$$ - numer indentyfikacjny procesu skryptu (PID)
$* - lista porozdzielanych parametrów
$@ - lista parametrów z którymi został uruchomiony skrypt
$? - kod ostatniego wykonywalnego polecenia
$1,$2,$3,... - poszczególne parametry


Można też używać zmiennych środowiskowych (printenv) np. $HOME, $USER, $SHELL i wielu innych.

Zmienne tablicowe są to takie zmienne, które przechowują listę określonych wartości. W bashu stosujemy tablice jednowymiarowe. Zmienne tablicowe indeksujemy liczbami całkowitymi zaczynając od 0. Poniżej prosty przykład.

#!/bin/bash
TAB=(Alpha Beta Gamma Delta)
echo ${TAB[0]}
echo ${TAB[1]}
echo ${TAB[2]}
echo ${TAB[3]}

Mamy też podział zmiennych na globalne i lokalne. Zmienne globalne są dostępne w obrębie całego skryptu. We wszystkich powyższych przykładach mieliśmy do czynienia ze zmiennymi globalnymi. Zmienne lokalne działają tylko w obrębie danej funkcji. Poprzedzone są słowem kluczowym local. Poniżej przykład pokazujący różnicę między globalnymi i lokalnymi zmiennymi.

#!/bin/bash
ZMIENNA="zmienna globalna"

function fun1 {
  local ZMIENNA="zmienna lokalna"
  echo $ZMIENNA
}

echo $ZMIENNA
fun1
echo $ZMIENNA

Wynik działania tego skryptu:

zmienna globalna
zmienna lokalna
zmienna globalna

5. Polecenie read - wprowadzanie danych

Polecenie read służy do wprowadzania danych przez użytkownika. Mogą to być wartości tekstowe lub liczbowe. Poniżej prezentuję skrypt operujący na wejściowych danych tekstowych oraz liczbowych.

#!/bin/bash

echo -en "Podaj swoje imie: "
read IMIE
echo "Witaj $IMIE"

echo -en "Podaj liczbe X: "
read X
echo -en "Podaj liczbe Y: "
read Y
let Z=X*Y
echo "$X * $Y = $Z"

Koniec części pierwszej, cdn.

środa, 11 lutego 2015

NetHogs - monitorowanie łącza

NetHogs to niewielki konsolowy program dla linuksa służący do wyświetlenia informacji o bieżącym obciążeniu łącza. Pokazuje statystyki dla poszczególnych programów.


Znaczenie poszczególnych kolumn

  • PID - identyfikator procesu
  • USER - użytkownik uruchamiający dany program
  • PROGRAM - aplikacja wykorzystująca łącze
  • DEV - interfejs sieciowy np. eth0, wlan0 itp.
  • SENT - upload
  • RECEIVED - download 
Klawisze

[M] - przełącznik pomiędzy widokiem średnich wartości wysyłania/odbierania [kB/s] a sumarycznym zestawieniem wysłanych i odebranych danych [kB; B; MB]

[Q] - wyjście

Instalacja programu (Debian, Ubuntu, Mint)

sudo apt-get install nethogs

Uruchomienie programu (tylko z prawami root-a)

sudo nethogs interfejs_sieciowy

np. sudo nethogs wlan0

Początki systemu Linux

Na grupie dyskusyjnej comp.os.minix można zobaczyć post Linusa Torvaldsa z sierpnia 1991 roku na temat tworzenia darmowego systemu operacyjnego podobnego do miniksa. Później system ten stał się linuksem.

What would you like to see most in minix? 

From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
Newsgroups: comp.os.minix
Subject: What would you like to see most in minix?
Summary: small poll for my new operating system
Keywords: 386, preferences
Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI>
Date: 25 Aug 91 20:57:08 GMT
Organization: University of Helsinki
Lines: 20

Hello everybody out there using minix -

I'm doing a (free) operating system (just a hobby, won't be big and
professional like gnu) for 386(486) AT clones.  This has been brewing
since april, and is starting to get ready.  I'd like any feedback on
things people like/dislike in minix, as my OS resembles it somewhat
(same physical layout of the file-system (due to practical reasons)
among other things).

I've currently ported bash(1.08) and gcc(1.40), and things seem to work.
This implies that I'll get something practical within a few months, and
I'd like to know what features most people would want.  Any suggestions
are welcome, but I won't promise I'll implement them :-)

                Linus (torv...@kruuna.helsinki.fi)

PS.  Yes - it's free of any minix code, and it has a multi-threaded fs.
It is NOT protable (uses 386 task switching etc), and it probably never
will support anything other than AT-harddisks, as that's all I have :-(.



Czołem użytkownicy miniksa.

Tworzę darmowy system operacyjny (takie hobby, nie będzie tak wielki i profesjonalny jak gnu) dla klonów AT 386 (486). Tworzę go od kwietnia, i już jest prawie gotowy. Przydałyby mi się uwagi na temat tego, co lubcie w miniksie, a czego nie, bo mój system go przypomina (taki sam rozkład plików systemowych, tak będzie praktycznie).

Przeportowałem basha (1.08) i gcc (1.40) i zdaje się, że działają. Oznacza to, że uda mi się osiągnąć za kilka miesięcy coś do praktycznego wykorzystania, chętnie poznam wasze potrzeby. Sugestie mile widziane, ale nie obiecuję, że je zaimplenetuję :-)

                Linus (torv...@kruuna.helsinki.fi)


P.S. Nie ma tu kodu miniksa, ma wielowątkowość, nie jest multiplatformowy (wykorzystuje zarządzanie zadaniami w 386) i najpewniej nigdy nie będzie obsługiwał innych dysków twardych niż AT, bo tylko taki mam :-(.

wtorek, 10 lutego 2015

Historia systemów z rodziny Unix

Na stronie www.levenez.com/unix/unix_a4.pdf znajduje się świetny diagram przedstawiający historię systemów uniksopodobnych od 1969 roku.

Pod adresem www.levenez.com można też zobaczyć diagramy dla języków programowania i systemów z rodziny Windows.

Witam...

Witam na moim blogu. Będę tu przeważnie wrzucał teksty dotyczące systemów uniksopodobnych, języków programowania oraz języków skryptowych. Być może znajdą się też informacje z dziedzin takich jak: elektronika, fizyka i matematyka.

Ja obecnie w domu używam systemu Linux Mint 17.1 Cinnamon 64-bit zainstalowanego na dysku SSD - działa rewelacyjnie.

W pracy oprócz administrowania serwerami linuksowymi, muszę też popracować na windowsach.