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.

Dienas joks

November 25th, 2011

- Kā lai es… Kā lai es jums to vieglāk izskaidroju?
- Mēģiniet tā kā tas bija patiesībā, tad būtu skaidrāk.
(apmēram 15:20)

Poor man’s cloud computing

November 3rd, 2011

Serverim jāpiešķir vārds (hostname) “cloud”…

jmc R.I.P.

October 25th, 2011

Lisp nelaime.

Negribu būt ļauns, bet kurš nākošais?

dmr R.I.P.

October 13th, 2011

Khh, par Ābolīša nelaimi rakstīja katrs, kuram nav slinkums, par C un Unix nelaimi Latvija pagaidām klusē. Lai nu kas, bet programmēšana C un Unix-veidīgās operētājsistēmas tiešām ir ietekmējušas manu dzīvi.

His pointer has been cast to void *; his process has terminated with exit code 0.

Dark side

October 10th, 2011

Pirms kāda laika ar kolēģiem runājām, ka mani dēli ir “parasti bērni”: pretēji mītiem, pirms gulētiešanas es viņiem nelasu Python kodu un nemācu skaitīt binārajā sistēmā. Lai gan binārā skaitīšanas sistēmā iemācīt skaitīt līdz 10 būtu tik viegli.
Pēc Banku augstskolas izlaiduma par šo tēmu varētu parunāt vēl: