@Topconf Tallinn

November 2nd, 2012

Kevlin Henney is so cool I consider buying his books instead of using thepiratebay.se.

That’s what’s wrong with the world

October 25th, 2012

The world is full of “scalability engineers” who would die from an orgasm if their software ever saw 10,000 requests in a day.

Labotā misija

June 18th, 2012

Nosist čūsku, iestādīt koku, izaudzināt dēlu, uzcelt māju nomaksāt mājokļa kredītu (vēlams, pirms pensijas vecuma sansiegšanas).

Cyclomatic complexity

June 4th, 2012

Spēlējos ar hfcca.py rīku ciklomātiskās kompleksitātes mērīšanai C++ programmās, kaut kad pa vidu nācās salabot XML formāta izvaddatus (lai tie atbilst patiesībai).
Tagad, skatoties beigu atskaitēs, ir ļoti labi redzams, ka kompleksitātes skaitlis nav saistīts ar problēmapgabalu, bet spēcīgi korelē ar koda autoru. Diemžēl.

All your core dumps are belong to us II

May 31st, 2012

Turpinot par Oracle ADR – tā ir ļaunuma sakne un bieži vien, mēģinot apstrādāt avārijas situācijas, rada jaunas avārijas.

Jāsāk ar to, ka visbiežāk malloc()/free() realizācija lieto parastus, nevis rekursīvus muteksus (reentrant mutex). Kas nozīmē, ka viens pavediens nevar vairākas reizes iegūt to pašu muteksu, toties muteksa realizācijai ir labāka ātrdarbība. (Manuprāt, tas ir labi un pareizi, jo rekursīvi muteksi liecina par programmas dizaina kļūdu.) Bet tad notiek mēģinājums atbrīvot atmiņu norādot “sliktu” adresi:

  • free() funkcija paņem muteksu
  • mēģina lasīt “slikto” adresi un saņem SIGSEGV signālu
  • pamostas Oracle ADR un mēģina pierakstīt kur un kāpēc notikusi avārija
  • nezināmu iemeslu dēļ sauc dlsym() funkciju
  • dlsym(), savukārt, mēģina izsaukt malloc()
  • malloc() mēģina paņemt muteksu, ko iepriekš ir paņēmusi free() funkcija
  • … un iestājas mūžīgā gaidīšana

Pilns skaistums:
Read the rest of this entry »

All your core dumps are belong to us

May 18th, 2012

Gatavojot apmācību par atkļūdošanu unix vidē, iedomājos, ka ar šādu virsraksta frāzi varētu raksturot Oracle ADR – ja kādai programmai pietika nekaunības pieslēgties pie Oracle datubāzes, ADR klusiņām savāks pie sevis visus core dump. Varbūt Oracle uzskata, ka vairākums kritisko kļūdu ir viņu, nevis aplikācijas kodā.

Autortiesības

May 10th, 2012

Raksts un komentāri par autortiesībām un Latvijas aku un laipu. Lai gan autoriem, protams, ir tiesības saņemt samaksu par savu darbu, man nepatīk, ka to iekasē visās iespējamās vietās un veidos: par datu nesējiem, kur es potenciāli varu kaut ko ierakstīt; no radio par atskaņošanu; no veikala un transporta, kur es potenciāli varētu to dzirdēt, ja neklausītos pleijeri; no darba vietas par to, ka radio mēģina slāpēt nepatīkamās skaņas labierīcībās; utt.

Neesmu mūziķis, bet ja par man neļautu publicēt atvērto kodu un būtu speciāli jāraksta iesniegumi dažādās hvz organizācijās, kas pēc noklusēšanas mēģina par manu darbu iekasēt naudu… ^$&#*%&!!!

C (and C++) backtraces

May 10th, 2012

Lai gan C un C++ nav iebūvētu iespēju stack trace iegūšanai kā interpretējamās valodās, GLIBC bibliotēkā ir backtrace() funkcija, kas māk izdarīt ko līdzīgu. Tomēr, lai to pilnvērtīgi izmantotu, viss kods ir jākompilē ar GCC parametru -rdynamic: rezultātā visas funkcijas tiek eksportētas un dinamiski resolvētas, kas palielina programmas izmēru un samazina ātrdarbību. Faila nosaukumu un koda rindiņu tādā veidā nevar iegūt.

Bet mazliet pacīnoties var izdarīt labāk. Komplektā ar GCC kompilatoru nāk header fails unwind.h ar vairākām noderīgām funkcijām. Viena no tām ir _Unwind_Backtrace, kas māk apstaigāt steku un katrā freimā izsaukt programmētāja norādīto funkciju. Ar _Unwind_GetIP var iegūt instrukcijas rādītāju. Programmas adreses var iegūt, bet ko tālāk?

Ja programma ir kompilēta ar debug informāciju, tad GDB kaut kādā veidā māk pa soļiem izpildīt programmu un izdrukāt atbilstošās koda rindiņas. Par laimi ir maza programmiņa addr2line, kas māk nolasīt debug informāciju no izpildfailiem un izdrukāt konkrētai adresei atbilstošo funkcijas nosaukumu, failu un rindiņu tajā.

Tas strādā mazām demo programmām, bet reālā dzīvē programma parasti izmanto bibliotēkas, pie tam daļu no bibliotēkām var ielādēt un izlādēt programmas izpildes laikā. Kā saprast kura adrese atbilst kurai bibliotēkai programmas izpildes laikā?

Te nāk palīgā Linux /proc failu sistēma: /proc/<PID>/exe var atrast saiti uz pašu izpildfailu, bet /proc/<PID>/maps var atrast dotajā brīdī lietotās bibliotēka ar adrešu intervālu, kas tām piešķirts (un nobīdi bibliotēkas failā, jo viena bibliotēka tiek ielādēta dažādos adrešu intervālos). Tālāk mazliet aritmētikas un addr2line var norādīt pareizo izpildfailu un pareizo adresi.

Saliekot visas šīs lietas kopā, var iegūt strādājošu backtrace() analogu ar detalizētāku informāciju. Kā iegūt C++ izņēmumu stack trace arī ir interesants temats, bet to vēlāk.

.com

April 30th, 2012

Es nosapņoju, ka daudzas lietas dzīvē notiek cikliski, un šī brīža startup kults izbeigsies tāpat kā .com startupu burbulis.

Pile of poo

February 3rd, 2012

💩, bet jums jau nav pareizo fontu.

Linux, 1333 un Oracle 11.2

January 21st, 2012

Tabula:

CREATE TABLE testret(id VARCHAR2(4), data VARCHAR2(4000));

Un tad 4 INSERTi, kas atšķiras tikai ar varchar mainīgā izmēru, bet ne datu garumu.

EXEC SQL BEGIN DECLARE SECTION;
    varchar data1333[1333];
    varchar data1334[1334];

    varchar id1333[1333];
    varchar id1334[1334];
EXEC SQL END DECLARE SECTION;

memset(data1333.arr, 'X', 1);
data1333.len = 1;
memset(data1334.arr, 'X', 1);
data1334.len = 1;
id1333.len = 0;
id1334.len = 0;

EXEC SQL INSERT INTO testret (id, data) VALUES ('1', :data1333) RETURNING id INTO :id1333;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('2', :data1334) RETURNING id INTO :id1333;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('3', :data1333) RETURNING id INTO :id1334;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('4', :data1334) RETURNING id INTO :id1334;
assert(SQLCODE == 0);

Izpildot programmu pret Oracle 11.2 serveri UTF-8 kodējumā, kā jums liekas, kāds būs rezultāts šādam vaicājumam?

SELECT id, DECODE(data, NULL, 0, LENGTH(data)) data_length FROM testret;

Nepareizi! Pārsniedzot maģisko izmēru 1333, dati tiek pazaudēti:

ID   DATA_LENGTH
---- -----------
1	       1
2	       1
3	       1
4	       0

To pašu var uzrakstīt arī ar OCI, nevis PRO*C. Un binārais fails korekti strādā pret vecākām 10.x servera versijām.

Vispār, kopš redzēju kā Oracle 10.2 sajauca vietām kolonas, ja mainīgā izmērs pārsniedza kaut kādus 400x baitus, šajā gadījumā mani pārsteidz tikai maģiskais skaitlis 1333.

Dāvana vadītājai

December 1st, 2011

Ieraugot aprakstu “Melna ādas pletne ar gumijas rokturi spēcīgiem pārbaudījumiem“, sapratu, ka šī ir īstā:

Belašu kods

November 29th, 2011

Ja tu redzēsi kā tas tiek rakstīts, vairs nekad negribēsi lietot programmu.
Un tamlīdzīgi.