Firma X zaslala předžalobní výzvu vývojáři projektu Nitter (Wikipedia), open-source alternativního frontendu k sociální síti X (ex-Twitter), a provozovatelům instancí jako XCancel, které umožňovaly číst příspěvky bez přihlášení, reklam a javascriptu. Údajně se dopouštějí „sběru dat“. Zdrojový kód Nitteru vývojář archivoval. Vývoj již dříve přerušil v roce 2024 po tehdejším omezení API X. X je dceřiná společnost SpaceXAI Elona Muska, provozující mj. kontroverzního chatbota Grok.
Bylo vydáno Ubuntu 26.04.1 LTS, tj. první opravné vydání Ubuntu 26.04 LTS s kódovým názvem Resolute Raccoon. Přehled novinek a oprav na Discourse.
Národní úřad pro kybernetickou a informační bezpečnost (NÚKIB) vydal Zprávu o stavu kybernetické bezpečnosti ČR za rok 2025 (pdf). Incidentů ubylo, sofistikovanost útočníků roste.
Open source softwarový stack AMD ROCm (Wikipedie) pro vývoj AI a HPC na GPU od AMD byl vydán v nové major verzi 10.0. S ROCm.AI. Přehled novinek v aktualizované dokumentaci.
Finanční skupina Partners se stala minulou neděli obětí kybernetického útoku, při kterém se útočníci dostali k některým osobním údajům klientů. Společnost o tom informovala ve čtvrtek. Ujišťuje, že peníze klientů nejsou v ohrožení. „Kybernetický útok zasáhl část IT infrastruktury naší společnosti. Ihned po zjištění útoku jsme s pomocí externích bezpečnostních odborníků začali intenzivně pracovat na minimalizaci škod. Útočníci se
… více »Americká technologická společnost Meta Platforms se dohodla, že zaplatí až zhruba 18 miliard dolarů (asi 373 miliard Kč) za mimosoudní urovnání sporu o závislosti dětí na sociálních sítích a provede významné změny pro jejich používání mladistvými. Téměř tři desítky států USA firmu v roce 2023 obvinily z toho, že sítě Facebook a Instagram vědomě navrhla tak, aby u dětí vyvolávaly závislost, a zatajovala tyto dopady před veřejností. Firma se
… více »Byl publikován aktuální přehled dění a novinek z vývoje Asahi Linuxu, tj. Linuxu pro Apple Silicon. Blíží se vydání podporující čipy M3. Vývojáře lze podpořit na GitHub Sponsors a Open Collective.
Kancelářský balík LibreOffice byl vydán ve verzi 26.8. Mimo jiné vylepšuje typografii a kompatibilitu s formáty MS Office, více v poznámkách k vydání.
Armbian, tj. linuxová distribuce založená na Debianu a Ubuntu optimalizovaná pro jednodeskové počítače na platformě ARM a RISC-V, ke stažení ale také pro Intel a AMD, byl vydán ve verzi 26.8. Přehled novinek v poznámkách k vydání.
Byla vydána nová verze 23.1.0, tj. první stabilní verze z nové řady 23.1.x, překladačové infrastruktury LLVM (Wikipedie). Přehled novinek v poznámkách k vydání: LLVM, Clang, LLD, Extra Clang Tools, Libc++, Polly a Flang.
getaddrinfo(), getnameinfo(), res_query() a res_search() za pomoci standardních libc funkcí a vláken. Pokud jsou moje informace správné, tak by měla být dnes pohlcena systemd. Sám jsem se zatím dostal k prozkoumání té originální.
Dostal jsem se k tomu v rámci dolaďování knihovny netresolve, která vedle základní funkcionality umožňuje využívat různé speciální backendy a stejnětak poskytuje vedle vlastného API i frontendy implementující jiná známá API. V rámci knihovny netresolve lze použít asyncns API jako backend i jako frontend. Frontend vypadá tak, že netresolve-asyncns.so implementuje celé API a jde buď linkovat namísto libasyncns a nebo podsunout hotovému programu pomocí utility wrapresolve, která nedělá nic jiného než že nastaví LD_PRELOAD na seznam podobných frontendů, které netresolve poskytuje.
Nedávno z googlu záhadně zmizela dokumentace k asyncns a generovaná dokumentace v rámci zdrojáků nevypadá moc funkční, takže se řídím převážně obsahem hlavičkového souboru, kde jsou funkce přecijen nějak okomentované. Osobně celé API chápu tak, že si pomocí asyncns_new() vytvořím asyncns_t, který na pozadí vytvoří pool vláken, a přes tento objekt pak posílám dotazy (například pomocí asyncns_getaddrinfo()) s možností ponechat si asyncns_query_t, přes který se můžu ptát na stav dotazů v případě potřeby. Dále od asyncns_t získám souborový deskriptor, který zapojím do svého event loopu a pokaždé, když je připravený, zavolám asyncns_wait() s volbou block = 0 a pomocí asyncns_getnext() vyzvednu první odpověď.
V případě více dotazů předpokládám, že se API bude používat tak, že po každém neblokujícím volání asyncns_wait() bude následovat asyncns_getnext() a zpracování příchozí odpovědi. Na to už pokud vím žádná dokumentace není, příklady použití taky ne a test ve zdrojovém stromu libasyncns je nedostačující, takže můžu jenom hádat. Osobně bych si představoval, že budu asyncns_getnext() volat tak dlouho, dokud nevrátí NULL a po každém volání výsledek celý zpracuju a zruším. No a pak je tu možnost zrušení dotazu asyncns_cancel(). To všechno je obsahem násoedujícího testu (jehož průběžně aktualizovanou verzi najdete v gitu).
#include <asyncns.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
asyncns_t *asyncns;
asyncns_query_t *query;
struct addrinfo *result;
struct pollfd pollfd = { .events = POLLIN };
int status;
asyncns = asyncns_new(10);
assert(asyncns);
assert(asyncns_getnqueries(asyncns) == 0);
assert(asyncns_getnext(asyncns) == NULL);
pollfd.fd = asyncns_fd(asyncns);
assert(pollfd.fd > 2);
query = asyncns_getaddrinfo(asyncns, "127.0.0.1", NULL, NULL);
assert(query);
assert(asyncns_getnqueries(asyncns) == 1);
assert(asyncns_getnext(asyncns) == NULL);
asyncns_cancel(asyncns, query);
query = NULL;
assert(asyncns_getnqueries(asyncns) == 0);
assert(asyncns_getnext(asyncns) == NULL);
query = asyncns_getaddrinfo(asyncns, "127.0.0.1", NULL, NULL);
assert(query);
assert(asyncns_getnqueries(asyncns) == 1);
assert(asyncns_getnext(asyncns) == NULL);
usleep(100000);
status = poll(&pollfd, 1, 0);
assert(status == 1);
status = asyncns_wait(asyncns, 0);
assert(status == 0);
assert(asyncns_isdone(asyncns, query));
assert(asyncns_getnqueries(asyncns) == 1);
assert(asyncns_getnext(asyncns) == query);
status = poll(&pollfd, 1, 100);
assert(status == 0);
status = asyncns_getaddrinfo_done(asyncns, query, &result);
assert(asyncns_getnqueries(asyncns) == 0);
/* Intuitively, this should not be needed but the docs state that
* a call to `asyncns_wait()` is necessary so that `asyncns_getnext()`
* provides meaningful results.
*/
status = asyncns_wait(asyncns, 0);
assert(status == 0);
/* There were two queries issued, one of which has been cancelled
* and the other has been freed afterwards. As none of them can be
* returned, the only meaningful result of `asyncns_getnext()` is
* NULL.
*/
assert(asyncns_getnext(asyncns) == NULL);
asyncns_free(asyncns);
asyncns_freeaddrinfo(result);
return EXIT_SUCCESS;
}
Výsledek je ten, že test náhodně padá na druhém nebo třetím testu výsledku asyncns_getnext() nebo projde, vyzkoušet můžete sami. Prvně tedy asyncns_getnext() správně vrací jeden nebo druhý dotaz, další volání někdy fungují a někdy ne. Opakovaná volání asyncns_wait() v testu původně nebyla, ale na základě nejednoznačné dokumentace v hlavičkovém souboru jsem je pro jistotu přidal. Můžete si všimnout možnosti předat na příkazové řádce volbu --skip-cancel, která způsobí vynechání testu vytvoření a zrušení dotazu. Zajímavé je, že s touto volbou test prochází i při mnohočetném opakování. Asi není náhodou, že se volání asyncns_cancel() v upstreamovém testu vůbec nevyskytuje.
Abych autorovi nekřivdil, dřívější API getaddrinfo_a od Ulricha Dreppera zahrnuté do glibc pro jistotu u gai_cancel() v dokumentaci vtipně uvádí, že dotaz nelze zrušit, pokud je zpracováván, což značně kazí iluzi možnosti dotaz kdykoli ukončit. Na druhou stranu libasyncns nedokumentuje, co se stane s již běžícím obslužným vláknem, takže těžko říct, co je horší. V netresolve se tomu vyhýbám tím, že vlákna vůbec nepoužívám a toto privilegium volitelně přenechávám aplikaci a backendům (žádný z mých backendů toho v tuto chvíli naštěstí nevyužívá).
Pořád si říkám, jestli jsem něco nepřehlédl. Navíc ani nevím, jestli a kam má smysl hlásit chybu, vzhledem k tomu, že libasyncns je mrtvý projekt. Nejspíš budu muset reimplementovat to samé pro jeho současnou alternativu v rámci systemd stromu.
UPDATE 2014-11-05: Na základě feedbacku od Hans1024 zápisek nyní obsahuje test, který lépe vystihuje problém s asyncns_cancel() a odkaz na odpovídající soubor v gitu.
Tiskni
Sdílej:
Failoval mi asyncns_isdone(asyncns, q0), protoze pred nim se vola asyncns_cancel(asyncns, q0), ktera na q0 zavola free. Je to napsane i v tom headeru.
Pak pri asyncns_waitu failne !q->done v complete_query. Teprve po odstraneni toho assertu to failuje jak je popsano ve clanku.
Vypada to ze pri pouziti asyncns_cancel prijde nejaka odpoved (q1 nebo q2) dvakrat a proto failne ten assert !q->done. Mozna mam tuseni cim to je. asyncns_cancel asi zadnym zpusobem nerekne tomu threadu ktere vyrizuje q0, ze se na ten pozadavek ma vykaslat, akorat smaze veskere zaznamy o q0, takze ten thread pak posle odpoved na q0, asyncns_wait se ji snazi zpracovat a chybne urci, ze se jedna o odpoved na q1 nebo q2. Kdyz dam asyncns_wait(asyncns, 1); pred ten cancel, test funguje.
Failoval mi asyncns_isdone(asyncns, q0), protoze pred nim se vola asyncns_cancel(asyncns, q0), ktera na q0 zavola free.Tak na ten jsem se zatím nikdy nechytil, ale good catch, tahle kontrola tam nepatří.
Teprve po odstraneni toho assertu to failuje jak je popsano ve clanku.Takže teď jsme na stejné situaci.
Vypada to ze pri pouziti asyncns_cancel prijde nejaka odpoved (q1 nebo q2) dvakrat a proto failne ten assert !q->done.Ale mně failují až ty
getnext, ne done, a dokonce jako první odpověď vždy dostanu q1 nebo q2, až potom i to failuje. Trochu jsem to vylepšil.
diff --git a/tests/test-asyncns.c b/tests/test-asyncns.c index 80ed7b8..5194682 100644 --- a/tests/test-asyncns.c +++ b/tests/test-asyncns.c @@ -102,7 +102,6 @@ main(int argc, char **argv) asyncns_cancel(asyncns, q0); assert(asyncns_getnqueries(asyncns) == 0); assert(asyncns_getnext(asyncns) == NULL); - assert(!asyncns_isdone(asyncns, q0)); } /* Start first real query */ @@ -144,6 +143,9 @@ main(int argc, char **argv) status = asyncns_wait(asyncns, 0); assert(status == 0); + /* Check that the first query is no longer there */ + assert(asyncns_getnext(asyncns) != q1); + /* Now second query should be available via `asycns_getnext()` */ assert(asyncns_getnext(asyncns) == q2); @@ -157,6 +159,10 @@ main(int argc, char **argv) status = asyncns_wait(asyncns, 0); assert(status == 0); + /* Check that the old queries are no longer there */ + assert(asyncns_getnext(asyncns) != q1); + assert(asyncns_getnext(asyncns) != q2); + /* Now no more queries should be available via `asycns_getnext()` */ assert(asyncns_getnext(asyncns) == NULL);Zjistil jsem, že když to pustím v cyklu, tak se mi to náhodně zastaví na jedné z těch podmínek, kde to kontroluje, zda next není q1, což mi přijde dost divoké, zvlášť když je libasyncns schopná vrátit q1, po jeho zrušení q2 a po jeho zrušení zrušený q1.
diff --git a/tests/test-asyncns.c b/tests/test-asyncns.c index 5194682..099d78f 100644 --- a/tests/test-asyncns.c +++ b/tests/test-asyncns.c @@ -143,7 +143,8 @@ main(int argc, char **argv) status = asyncns_wait(asyncns, 0); assert(status == 0); - /* Check that the first query is no longer there */ + /* Check that the old queries are no longer there */ + assert(asyncns_getnext(asyncns) != q0); assert(asyncns_getnext(asyncns) != q1); /* Now second query should be available via `asycns_getnext()` */ @@ -160,6 +161,7 @@ main(int argc, char **argv) assert(status == 0); /* Check that the old queries are no longer there */ + assert(asyncns_getnext(asyncns) != q0); assert(asyncns_getnext(asyncns) != q1); assert(asyncns_getnext(asyncns) != q2);To je ale docela problém, protože libasyncns tak drží referenci na zrušená data, jestli to správně chápu, tu referenci dále používá a ještě navíc ji předává volajícímu. Ta funkce
asyncns_cancel() je tím pádem v podstatě nevolatelná, pokud si člověk nechce rozsypat stav knihovny a aplikace.
Nevidim zadny mechanismus, ktery by mohl zabranit probihajicimu threadu poslat odpovedTo zní jako bug.
takze to k tomu asi neni vubec urcene.Erm...
/** Cancel a currently running query. q is is destroyed by this call * and may not be used any futher. */ void asyncns_cancel(asyncns_t *asyncns, asyncns_query_t* q);Dle dokumentace je to k tomu jednoznačně určené, jen to není naimplementované. Ovšem nemůžu přijít na minimální test, protože pokud vyzvednu zavolám
poll(timeout=100) a asyncns_wait(block=1), tak asyncns_getnext() správně vrátí NULL a zdá se, že se to rozsype až s dalším dotazem a to ještě podle všeho nedeterministicky.
zavolám poll(timeout=100) a asyncns_wait(block=1), tak asyncns_getnext() správně vrátí NULL a zdá se, že se to rozsype až s dalším dotazemVe funkci handle_response (kterou vola wait na vsechny odpovedi) je:
if (!(q = lookup_query(asyncns, resp->id)))
return 0;
Pokud je jedinny query ten smazany, pak lookup_query nenajde zadny query odpovidajici id odpovedi a getnext vraci NULL. Pri vytvoreni noveho query se muze stat, ze se prideli stejne id jako q0. Nedeterministicke je to mozna proto, ze prideleni toho id je ovlivnene tim, jestli thread pro q0 uz skoncil.
MAX_QUERIES.
diff --git a/libasyncns/asyncns.c b/libasyncns/asyncns.c
index bc0b708..ada1d55 100644
--- a/libasyncns/asyncns.c
+++ b/libasyncns/asyncns.c
@@ -1474,6 +1474,10 @@ void asyncns_cancel(asyncns_t *asyncns, asyncns_query_t* q) {
asyncns->n_queries--;
free(q);
+ /* This is needed to avoid allocating the same id for the next query. */
+ asyncns->current_index++;
+ asyncns->current_id++;
+
errno = saved_errno;
}
S tímhle patchem mi test probíhá bez problémů.
1) Schopnost redakčního systému kurvit blogy po každém uložení tím, že vyrábí falešné prázdné odstavce mezi kusy textu, které mají být skutečnými odstavci.
To robí wysiwyg. Vypnúť a pôjde to (teda aspoň mne to ide)
3) Emulátor terminálu Terminology zdá se občas vynechá prázdnou řádku a občas ne, netuším proč.
Nie sú tie riadky vypísané nejakým exotickejším spôsobom než \n? Ak sú vypísané pomocou riadiacich sekvencií mohlo by to znamenať, že terminology kopíruje relatívne surové dáta z terminálu. Možno sa mýlim, neskúšal som.
To robí wysiwyg.Nikoliv, ten nepoužívám.
Nie sú tie riadky vypísané nejakým exotickejším spôsobom než \n?Jsou to úplně stejné nové řádky jako ty, které to vezme. Ale není se čemu divit, celý Enlightenment 0.19 je tak nějak po různu pojebaný, chtělo by to ještě trochu péče.