Archive for the 'Розробка софту' Category

Зневадження коду за допомогою strace

неділя, Лютий 8th, 2009

Ви коли небуть ломали собі голову над пошуком помилки? Помилки, яку ніяк не вдається знайти у джерельних текстах, але яка часто проявляється після компіляції і запуску програми. Знайомтесь: strace. strace — це утиліта, яка дозволяє вам трасувати системні виклики і сигнали конкретної команди. Якої команди? А які у вас є?

strace — вільне програмне забезпечення, що розповсюджується на умовах ліцензії, подібної до ліцензії BSD. Спершу утиліта була написана Полом Краненбургом (Paul Kranenburg) для SunOS за мотивами іншої утиліти для SunOS, trace. На Linux її портував Бранко Ланкестер (Branko Lankester), котрий, окрім цього, реалізував її підтримку в ядрі. У 1993, Рік Следкі (Rick Sladkey) об’єднав strace 2.5 для SunOS з другою версією strace для Linux, додавши при цьому багато можливостей truss(1) з SVR4. В результаті, з’явилася strace, котра працювала на обох платформах. Сьогодні, strace підтримується Уічертом Аккерманом (Wichert Akkerman) і Роландом МакҐрасом (Roland McGrath).

Трасування helloworld

Робота strace полягає у перехопленні і записі системних викликів, виконаних процесом, а також отриманих ним сигналів. Для кожного системного виклику, до стандартного файлу помилок, або ж до будь якого іншого заданого файлу, виводиться його ім’я, аргументи і код виклику. Як щодо кількох прикладів?

Щоб не ускладнювати роботу strace, я використав найпростішу з можливих програм.

1
2
3
4
5
6
7
#include <stdio .h>
 
main()
{
    printf("Hello World n");
}
</stdio>

Компілюємо її:

# gcc -o helloworld helloworld.c

Готово! Запускаємо: ./helloworld, і отримаємо на стандартний вихід:

Hello World

Виглядає надзвичайно просто. Тепер запустимо strace. strace протрасує, і виведе на stderr усі системні виклики і сигнали:

# strace ./helloworld

Вивід команди `strace ./helloworld`:

 1  execve("./helloworld", ["./helloworld"], [/* 22 vars */]) = 0
 2  uname({sys="Linux", node="knuth", ...}) = 0
 3  brk(0)                                  = 0x81f7000
 4  access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
 5  open("/etc/ld.so.cache", O_RDONLY)      = 3
 6  fstat64(3, {st_mode=S_IFREG|0644, st_size=73856, ...}) = 0
 7  old_mmap(NULL, 73856, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fed000
 8  close(3)                                = 0
 9  open("/lib/tls/libc.so.6", O_RDONLY)    = 3
10  read(3, "177ELF111331 ?B00"..., 512) = 512
11  fstat64(3, {st_mode=S_IFREG|0755, st_size=1454835, ...}) = 0
12  old_mmap(0x40f000, 1215644, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x40f000
13  old_mmap(0x532000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x123000) = 0x532000
14  old_mmap(0x536000, 7324, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x536000
15  close(3)                                = 0
16  old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fec000
17  mprotect(0x532000, 4096, PROT_READ)     = 0
18  mprotect(0x40b000, 4096, PROT_READ)     = 0
19  set_thread_area({entry_number:-1 -> 6, base_addr:0xb7fec940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
20  munmap(0xb7fed000, 73856)               = 0
21  fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
22  mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fff000
23  write(1, "Hello World n", 13)          = 13
24  munmap(0xb7fff000, 4096)                = 0
25  exit_group(13)                          = ?

Перше, що ми бачимо — це execve. execve() виконує програму, задану ім’ям файлу. Далі, uname() отримує ім’я і тип системи, яку я використовував для тесту. Після цього, наша програма запитує певну кількість пам’яті і мапи розміщення розділюваних бібліотек, необхідних для роботи, наприклад, динамічний завантажувач і libc. До всієї цієї інформації ми скоро повернемося, а поки подивимося, що відбувається далі. Рядок 23 виводу трасування, нарешті відкриває нам призначення нашої програми helloworld (як би ми не бачили джерельного коду): вивести у файловий дескриптор 1 (STDOUT), повідомити кількість байт у виведеній інформації та їх значення. Не складно здогадатися, що застосування трасування може допомогти вам відстежити у програмі конкретний виклик або сигнал. Чим же це корисно? Якщо ви пишете програму трохи більш складну, ніж helloworld.c, і вона дає збій, видаючи мінімум, або взагалі не видаючи інформації про те, що з нею сталося, трасування може вам допомогти виявити причину, яка викликає збій у процесі роботи.

Read the rest of this entry »

Code Review

четвер, Лютий 5th, 2009

“Doing reviews is the most important step you can
take to improve your software engineering performance”.

Watts Humphrey

Огляд або перевірка коду (Coding Review) — девелоперська практика попереднього перегляду і утверджувати коду іншими розробниками перед його заливкою на CVS.

Тобто, перед тим, як сабмітити свій код на cvs, ви даєте його на читання іншому програмістові. Той уважно (не бігло, а приділяючи цьому бодай 10-15 хвилин) його вичитує, вникає в логіку роботи, і намагається знайти у ньому, бодай очевидні помилки, або ж запропонувати інші, більш вдалі рішення вирішуваних вами задач. Якщо такі знаходяться, код повертається вам доопрацювання!

code_review_comic

Власне, навіщо це потрібно. Ну звісно ж, відповідь очевидна — у першу чергу, для підвищення якості коду. Адже, як відомо, одна голова добре, а дві — інколи, ліпше. Далеко не завжди певну роботу виконує програміст, який ліпше за усіх інших членів команди на ній знається. Та й, як би це банально, і до бридоти не серйозно й не звучало б, навіть початківці, зі своїм більше свіжим баченням та чистими від вбитих у голову шиблонів, можуть підкинути файну ідею.

Read the rest of this entry »

Короткий довідник The Pragmatic Programmer

субота, Січень 24th, 2009

Даний посібник — це лаконічна збірка порад наданих розробникам програмного забезпечення з книги The Pragmatic Programmer.

Для більш детальної інформації дивіться майданчик тенет www.pragmaticprogrammer.com.

Read the rest of this entry »

25 найнебезпечніших програмістських помилок

середа, Січень 14th, 2009

Я намагатимусь не публікувати тут різні новини, бо цей блоґ не для кроспостингу, однак, цього разу маю зробити вийняток, оскільки, новина цікава, важлива, до того ж, це переклад з англійської.

Так от, інститут SANS (SysAdmin, Audit, Network, Security) співпрацюючи з організацією MITRE опублікував перелік 25 найнебезпечніших помилок, які призводять до виникнення серйозних вразливостей у програмному забезпеченні. Помилки відбирались з урахуванням їх розповсюдженості, складності знаходження і простоти використання для здійснення шкідливих дій.

Read the rest of this entry »

GTK+ — 2. Перша програма

понеділок, Січень 12th, 2009

У цій частині, в межах курсу по вивченню бібліотеки GTK+, ми напишемо, і покрокового розберемо першу просту програму.

Простий приклад

Розпочнемо з дуже простої програми. Вона створює і відображає просте вікно.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <gtk /gtk.h>
 
int main(int argc, char *argv[])
{
    GtkWidget *window;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);
 
    gtk_main();
 
    return 0;
}
</gtk>

Read the rest of this entry »