7/01/2013

Немного про volatile

В языках C и C++ есть такое замечательно ключевое слово volatile.
Согласно стандарту языка C, переменная обозначенная типом с квалификатором volatile может быть изменена каким-то неизвестным способом (may be modified in ways, unknown to the implementation).

Допустим у нас есть вот такой код:

int a = 0;


int main (void) {

   while (*(int*)&a == 0)

      /* do smth. */ ;

   return 0;

}


Компилятор, скорее всего во время оптимизации этого кода отбросит все ненужные шаги по инициализации переменной, проверки ее на 0 и т.д., т.к. для него очевидно что это просто бесконечный цикл, и можно сгенерировать следующий код:

00008294<main>:

   8294:   eafffff    b    8294 <main>

Очевидно, что для того, чтобы заставить компилятор сгенерировать код, который бы проверял каждый раз значение переменной a, нужно использовать ключевое слово volatile при объявлении a
volatile int a = 0;


int main (void) {

   while (*(int*)&a == 0)

      /* do smth. */ ;

   return 0;

}


Но если скомпилировать эту программу мы увидим все тот же бесконечный цикл:
00008294<main>:

   8294:   eafffff    b    8294 <main>


Это все происходит из-за того, что при преобразовании в теле цикла к указателю на int, снимается квалификатор типа volatile, и когда мы разыменовываем указатель, то уже имеем переменную типа int, которая и сравнивается с 0.

Поэтому, чтобы добиться желаемого эффекта volatile нужно употребить сразу в двух местах:


volatile int a = 0;


int main (void) {

   while (*(volatile int*)&a == 0)

      /* do smth. */ ;

   return 0;

}


И тогда наконец-то мы получим то, что хотели:

00008294<main>:

         8294:   e59f2010   ldr     r2, [pc, #16]   ; 82ac
      <main+0x18>
         8298:   e5923000        ldr     r3, [r2]
         829c:   e3530000        cmp     r3, #0
         82a0:   0afffffc        beq     8298 <main+0x4>
         82a4:   e3a00000        mov     r0, #0
         82a8:   e12fff1e        bx      lr
         82ac:   000104f4        .word   0x000104f4

7/23/2012

не работает ptrace в Ubuntu

Обнаружили тут, что системный вызов ptrace не работает в Ubuntu 
и вываливается с ошибкой 'operation not permitted'.
 
Оказывается такое поведение по умолчанию включено в Ubuntu начиная с версии 10.10

Чтобы изменить поведение по умолчанию нужно немного поправить настройки ядра:
echo 0 > /proc/sys/kernel/yama/ptrace_scope

Или поправить файлик: 
/etc/sysctl.d/10-ptrace.conf 

3/26/2012

Визуализация разработки компилятора GCC в 1989-2012

Ребята с помощью утилиты Gource визуализировали процесс разработки компилятора gcc. 
На мой взгляд получилось и наглядно и красиво.

3/22/2012

GCC - 25 лет.

Ровно 25 лет назад, в далеком 1987 году Ричард Столлман анонсировал первый публичный релиз набора компиляторов GCC.

И к этой знаменательно дате приурочен выход новой версии GCC-4.7.0.

Компилятор GCC-4.7.0 содержит много новых возможностей, которых не было в ветке 4.6.x.
Из основных можно отметить:
  • Транзакционная память.
  • Поддержка большого количества фич стандарта ISO C++11, таких как atomics и новая модель памяти, определяемы пользователем литералы и т.д.
  • Значительно улучшен фреймворк оптимизации на этапе линковки (link-time optimization framework (LTO))
  • Улучшена поддержка расширений формата отладочной информации DWARF ()
  • Добавлена поддержка аппаратных платформ: 
    • Adapteva's Epiphany process
    • National Semiconductor's CR16 
    • TI's C6X 
    • Tilera's TILE-Gx and TILEPro.
    • Intel Haswell
    • AMD Piledriver 
    • ARM Cortex-A7 family.

Более подробно об изменениях можно почитать тут:
http://gcc.gnu.org/gcc-4.7/changes.html

Как узнать версию библиотеки libc?

Достаточно просто запустить файл библиотеки:

/lib/libc.so.6

GNU C Library stable release version 2.14.1, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.5.3.
Compiled on a Linux 3.2.0 system on 2012-01-18.
Available extensions:
        C stubs add-on version 2.1.2
        crypt add-on version 2.1 by Michael Glad and others
        Gentoo patchset 3
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        Support for some architectures added on, not maintained in glibc core.
        BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
.

2/15/2012

libreoffice + Gentoo = SIGILL

Ну вот как так можно собирать libreoffice-bin чтобы он падал по SIGILL?
После очередного обновления он именно этим и начал заниматься.


После расследования оказалось что падает при попытке исполнения инструкции vmovsd, которая является SIMD инструкцией AVX расширения процессора Intel и  на моем процессоре не поддерживается.

Багрепорт и немного расследования:
https://bugs.gentoo.org/show_bug.cgi?id=403931

Лечится сборкой LO из исходников или откатом на предыдущую версию.

2/06/2012

Переезжаем с Postgresql 8.4 на Postgresql 9.1 в Ubuntu


Делается это так:

$ su - postgres

Делаем backup на всякий случай:

$ pg_dumpall >backup_db

Останавливаем сервер:

$ pg_dropcluster --stop 9.1 main

Переносим данные со старого сервера:

$ pg_upgradecluster 8.4 main

Удаляем старый сервер:

$ pg_dropcluster 8.4 main

... 
Profit !

2/01/2012

Linux_x86_64 и Skype

21 век на дворе а skype до сих пор не распространяется для 64-х битных
линуксов.
Постоянно приходится извращаться, потому что при каждом обновлении в Gentoo появляются проблемы с камерой и каждый раз при обновлении
приходится добавлять в /usr/bin/skype вот такую строчку:

export LD_PRELOAD=/usr/lib32/libv4l/v4l1compat.so

Чего-то надоело уже.

Может кто знает, чем его можно заменить, но так, чтобы было возможность общаться с контактами из skype'а?
Есть какой нибудь транспорт, как например в xmpp?

p.s. Пост был  из будущего

1/27/2012

Настройка Apache + git + trac


Для хранения кода своих мелких проектов я частенько использую репозитории обычно или git или svn и систему багтрекинга trac.

Ниже для того, чтобы не забыть как это настраивается опишу все шаги на примере Ubuntu 10.10

1. Установка необходимого софта.

Устанавливаем весь необходимый софт:
$ apt-get install apache2 git subversion postgresql trac python-psycopg2 libapache2-mod-python

Включаем в апаче модули, которые нужны для доступа к репозиторию:
$ a2enmod dav dav_fs

2. Настройка git репозитория

Для примера создам тестовый репозитория с именем my_proj.
Для этого на сервер создаем каталог где у нас будут храниться данные,
как для bare репозитори, так и для обычного

$ mkdir -p /proj/git_repos_bare
$ cd /proj/git_repos_bare

$ git init --bare my_proj_init

Далее создаем каталог, где будут храниться репозитории:
$ mkdir -p /proj/git_repos
$ cd /proj/git_repos

Создаем пустой репозиторий:
$ git clone --bare /proj/git_repos_bare/my_proj_init my_proj

Даем права на доступ в репозиторий пользователю www-data от имени
которого будет хозяйничать апач:
$ chown -R www-data:www-data /proj/git_repos

3. Настройка Trac

Для того чтобы настроить trac сначала потребуется настроить базу данных в которой он будет хранить информацию о коммитах, логи и прочее.
Trac поддерживает много всяких БД: SQLite, MySQL, PostgreSQL.
Мне больше всего нравится PostgreSQL, но и с любой другой БД проблем возникнуть не должно.

3.1 Настройка postgres:

Создаем пользователя:
$ psql -d template1 -U postgres

$ template1=# CREATE USER trac WITH PASSWORD 'trac';

Создаем базу в которой trac будет хранить свои данные:
$ template1=# CREATE DATABASE "trac-my_proj" WITH OWNER = trac TABLESPACE = pg_default CONNECTION LIMIT = -1;

На этом этапе настройка базы данных завершена.

3.2 Настройка Trac

Теперь нужно настроить окружение Trac.

Создаем каталог где будут храниться окружения Trac'а:
$ mkdir -p /var/trac
$ cd /var/trac

Настраиваем окружение:
trac-admin {Название проекта} initenv {Имя репозитория} {Строка соединения с БД} {Тип репозитория} {Путь к репозиторию}

В нашем случае это будет выглядеть так:
$ trac-admin my_proj initenv my_proj postgres://trac:trac@localhost/trac-my_proj git /proj/git_repos/my_proj

Добавляем пользователя который будет являться администратором в Trac :
$ trac-admin my_proj permission add test TRAC_ADMIN

Разрешаем апачу хозяйничать в каталоге с файлами Trac'а:
$ chown -R www-data:www-data /var/trac/my_proj

3.3 Установка плагина для git репозитория

Поумолчанию trac в качестве системы контроля версий поддерживает только subversion, поэтому нужно установить дополнительный плагин для того, чтобы можно было использовать git репозиторий:
$ easy_install http://github.com/hvr/trac-git-plugin/tarball/master

Чтобы проверить что Trac заработал нужно запустить tracd:
$ tracd --port 8000 /var/trac/my_proj

Теперь на результаты деятельности можно посмотреть через браузер:
http://127.0.0.1:8000/

Если все ок, то должна отобразиться заглавная Wiki страничка.

4. Настройка Apache

Теперь для того чтобы иметь унифицированные механизм аутентификации и доступа к репозиториям и баг трекеру настраиваем apache.

Сначала добавим пользователя которому нужно дать доступ в репозитории и в баг трекер:
$ htpasswd -c /var/trac/users.auth test

Вводим пароль и готово.

Далее правим конфигурационный файл апача:
/etc/apache2/sites-enabled/000-default

Если же хочется использовать https, то править нужно:
/etc/apache2/sites-enabled/default-ssl

Сначала устанавливаем  Python handler который будет выводить список проектов при заходе на страничку yourdomain/trac:
<Location /trac/ > 

           SetHandler mod_python
           PythonInterpreter main_interpreter
           PythonHandler trac.web.modpython_frontend
           PythonOption TracEnvParentDir /var/trac
           PythonOption TracUriRoot /trac/
           PythonOption PYTHON_EGG_CACHE /tmp/.eggs

</Location>


После этого, нужно сказать апачу чтобы он не разрешал неавторизованным пользователям ходить в баг трекер.
     <LocationMatch /trac/*> 

            AuthType Basic
            AuthName "Input your username and password to access."
            AuthUserFile /var/trac/users.auth
            Require valid-user
     </LocationMatch>


Далее настраиваем git.
Прописываем переменные окружения, в которых указываем корень каталога с репозиториями, http-бэкенд и прописываем алиас пути к репозиториям через web:
     SetEnv GIT_PROJECT_ROOT /proj/git_repos

     SetEnv GIT_HTTP_EXPORT_ALL

     ScriptAlias /gitweb "/usr/lib/cgi-bin/gitweb.cgi"

     ScriptAlias /git/ /usr/lib/git-core/git-http-backend

     Alias /git "/proj/git_repos"


и запрещаем вход без пароля:
<Locationmatch /git/*>      
            DAV on
            AuthType Basic
            AuthName "Git Access"
            AuthUserFile /var/trac/users.auth
            Require valid-user

</LocationMatch>



Делаем в каталоге с репозиторием:
$ git update-server-info

И ,наконец, перезапускаем апач:
$ service apache2 restart

На этом настройка апача завершена.

5. Проверка что все работает.

Проверяем что репозиторий работает:
$ git clone http://test@mydomain/git/my_proj

Cloning into 'my_proj'...
Password for 'mydomain':
warning: You appear to have cloned an empty repository.

Добавляем файлы в репозиторий, и делаем начальный коммит:
git push origin master:master

Вот как-то так.

Если возникли какие-то проблемы, то посмотреть что идет не так можно в логах:
/var/log/apache2

12/21/2011

Code @ C++: Find sum of elements in the array

Code @ C++: Find sum of elements in the array: Наткнулся на задачу, которую предлагают в Yandex на собеседовании: Ниже приведены три варианта суммирования чисел с плавающей точкой (предп...

12/13/2011

Emacs column marker

Очень часто стилем кодированием лимитирована максимальная длина строки кода и хорошо когда про это знает IDE.

В Emacs добавил себе column-marker

(add-to-list 'load-path (expand-file-name "~/emacs/column-marker"))

(require 'column-marker)

(add-hook 'ada-mode-hook (lambda () (interactive) (column-marker-3 79))) 

Теперь, если в в Адском коде длина строки превышает 79 символом,  Emacs подсвечивает часть строки красненьким.

P.S. Заодно проверю, есть ли реклама в Фиде. Вроде с горем пополам я ее отключил.

12/01/2011

Error: Value too large for defined data type

При компиляции сорсов программы в Ubuntu Linux, в директории которподмонтирован по samba, gcc вывалил вот такую ошибку:

Error: Value too large for defined data type

Сначала показалось что ошибка в gcc, однако проблема оказалась в монтировании дирректории по CIFS.


При монтировании нужно добавить несколько опций:

nounix,noserverino
 
В чем причина сего явления не очень понятно.

Решение проблемы подсмотрено тут. 

11/03/2011

Утечки памяти и ошибки доступа.

Ранее я уже писал о том, что можно искать утечки памяти в программе с помощью средств, которые предоставляет glibc. Описанный подход плох тем, что не позволяет искать ошибки доступа к памяти, такие как обращение по нулевому указателю, или обращение к уже освобожденной памяти.

В данном посте речь пойдет о mudflap.
mudflap - это технология проверки указателей, основанная не на бинарной инструментации, как valgrind или dr. Memory, а на инструментации времени компиляции. Если в кратце, во время компиляции программы в исходный код делаются вставки, которые обспечивают различные проверки указателей,к которым осуществляется доступ.

Теперь разберем работу mudflap на конкретном примере.

Для того, чтобы можно было использовать mudflap, нужа поддержка этой технологии в компиляторе и собственно сама библиотека, выполняющая проверки: gcc должен  быть скомпилирован с опцией --enable-libmudflap, и в системе должна присутствовать библиотека libmudflap.so.

В качестве примера рассмотрим программу, котороя пытается записать в уже освобожденную память:
#include <malloc.h>

int main (void)
{
  const int chunk_size = 18;
  const int count  = 10000;
  int j = 0;
  void * ptrs [count];

  /* выделяем 10 000 кусочков памяти по 18 байт.*/
  for (j = 0; j < count; j++) {
    ptrs [j] = malloc (chunk_size);
  }

  /* освобождаем все, кроме первого и последнего */

  for (j = 1; j < count - 2; j++)
    if (ptrs [j])
      free (ptrs [j]);

  /* записываем в освобожденную память*/
  *(char*)ptrs [10] = 10;

  /* просим glibc сделать "дефрагментацию" выделенной памяти */
  malloc_trim (1);

  return 0;
}


Результатом работы программы будет Segmentation Fault.
Это происходит потому что при попытке записи в освобожденную память (на самом деле она не освобождается, а помечается как неиспользуемая) программа портит служебную информацию glibc, а именно связный список, который используется в glibc для управления памятью.

Чтобы отловить ошибку в программе нужно пересобрать программы с mudflap инструментацией:

gcc -fmudflapth -lmudflap -Wall -Wextra -g -ggdb3 buggy.c
Запускаем:

./a.out


В результате работы программа выдает следующее:

*******

mudflap violation 1 (check/write): time=1320343428.778161 ptr=0xe85c10 size=1

pc=0x7fcc8d0dc4f8 location=`buggy.c:22:21 (main)'

      /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/libmudflap.so.0(__mf_check+0x38) [0x7fcc8d0dc4f8]

      ./a.out(main+0x301) [0x400da5]

      /lib64/libc.so.6(__libc_start_main+0xec) [0x7fcc8cd63e8c]

number of nearby objects: 0


Ясно видно где в исходном коде возникает проблема.

Для проверки, запустим программу под valgrind-ом, который выдает следующую информацию:
==26575== 

==26575== Invalid write of size 1

==26575==    at 0x4006E0: main (buggy.c:22)

==26575==  Address 0x51bc400 is 0 bytes inside a block of size 18 free'd

==26575==    at 0x4C27F6C: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)

==26575==    by 0x4006C8: main (buggy.c:19)


valgrind как и mudflap, точно показал место ошибки в программе:
buggy.c: 22

Резюмирая можно обозначить плюсы и минусы mudflap:
"+" :
1. Более низкий overhead по сравнению с valgrind.
2. Лучшая переносимость: доступен для платформ ARM и MIPS.
3. Из-за того, что инструментация происходи во время выполнения, может находить более сложные ошибки и более точно показывать их в коде.

"-":
1. Поддержка кода, написанного только на C/C++.
2. Привязка к компилятору GCC.
3. Необходимость перекомпиляции.

Таким образом, mudflap вполне удобный тул, который позволяет искать утечки в памяти не используя valgrind, что особенно полезно для встраиваемых систем (ARM и MIPS), где на исполнение кода существенно влияют накладные расходы на инструментацию.

Больше информации о mudflap можно посмотреть тут : http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging

10/17/2011

Экранирование в bash, кто знает?

Есть такой скриптик в bash:

#!/bin/bash
set -x
a () 
   echo $1 
}

b () 
   a "--some-flag='param1 param2,param3'" 
}
b


в функции a () echo вызывается как:
echo '--some-flag='\''param1' 'param2,param3'\'''

как сделать чтобы параметры которые передаются в a () не экранировались?

т.е. чтобы echo вызывался вот так:
echo --some-flag='param1 param2,param3'

т.е. чтобы параметры передавались как есть ?

10/15/2011

Установил себе grub2 в Gentoo

Надоело мне пользоваться LILO, захотелось чего то нового.
Решил поставить себе GRUB2.

1. Размаскируем пакет:
echo ">=sys-boot/grub-1.99-r2" >> /etc/portage/package.unmask

2. Собираем
emerge grub

3.Настраиваем
 grub2-mkconfig -o /boot/grub2/grub.cfg

4. Проверяем, что конфигурация работает.
grub2-install --grub-setup=/bin/true /dev/sda

5. Устанавливаем
grub2-install /dev/sda

6. Перезагружаемся
reboot.

10/05/2011

kernel.org вернулся

kernel.org снова в строю.
Ждем результатов расследования взлома.

P.S. на lwn.net дали ссылку на https://www.kernel.org,
причем если с https://www.kernel.org все в порядке,
то https://kernel.org ругается на неправильный сертификат.

10/01/2011

Berlios.de - всё

Кризис наступает и в IT индустрии.

Сегодня получил письмо о том, что хостинг открытых проектов www.berlios.de который верой и правдой служил разработчикам 10 лет - будет закрыт 01.01.2012.

Причиной закрытия является нехватка средств у немецкого исследовательского института Fraunhofer FOKU, в связи с урезанием финансирования непрофильных проектов.

Ссылка на официальную новость:  BerliOS will be closed on 31.12.2011

6/28/2011

запуск приложения, читающего стандартный ввод в GDB

Предположим у нас есть приложение, которое что-то читает со стандартного ввода 
и одновременно принимает ключи в командной строке. 

Q : Как запустить это приложение под GDB?
 
A
   gdb application
   gdb> run parameters ... < input_file

6/18/2011

Gentoo, Firefox и NS plugin wrapper.

Не забудьте после очередного обновления nspluginwrapper в Gentoo до версии 1.4.2 выполнить команду:

nspluginwrapper -i /opt/Adobe/flash-player32/plugin/libflashplayer.so

Иначе, у вас перестанет работать flash плагин.

6/14/2011

Вышел GNAT GPL 2011 с новыми вкусностями.

We are pleased to announce the release of GNAT GPL 2011, the integrated
Ada, C, and C++ toolset for Academic users and FLOSS developers.
This new edition provides many new features and enhancements in all
areas of the technology. The most notable ones are:

 - improved support for Ada 2012 
 - enhanced versions of tools 
    - GPS 5.0 enhanced IDE (improved support for C/C++, more powerful
      source editing, better usability, ….),
    - GtkAda (new widgets, interface to the Cairo graphics library)
 - more flexible and more efficient project manager tool
 - support for unloading Ada plug-ins
 - improved support for Ada constructs on the .NET platform
 - more detailed exception messages (-gnateE switch)
 - complete support for Lego MINDSTORMS hardware, including audio and
   I2C sensors

GNAT GPL 2011 comes with version 5.0.1 of the GNAT Programming Studio
IDE and GNATbench 2.5.1, the GNAT plug-in for Eclipse.

GNAT GPL 2011 can be downloaded from the "Download" section on
https://libre.adacore.com.