IFields::Read aborts on truncated data instead of returning pos == 0
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 1/5
- Geschätzter Aufwand
- Unter einer Stunde
- Anfängerfreundlichkeit
- 25/100
Rechercherichtung
The unbalanced push/pop is in ReadVisitor::operator()(IFields&) in io/fields.cc, where the truncation branch returns before ~ReadVisitor's HWY_ASSERT(end_.empty()) runs; the SkipField branch shows the pop that is missing. ReadResult's contract in io/fields.h documents pos == 0 for a short span, and gemma/model_store.cc's config and MatPtr checks are the affected callers. Add the TestTruncatedData case to io/fields_test.cc, build the fields_test target, and confirm the test plus the existing cases pass. Note the reporters state they already have the fix and test on a branch and will open the PR themselves.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
What happens
ReadVisitor::operator()(IFields&) in io/fields.cc (on dev, 8073ef9) begins by pushing onto end_. Then:
- The
SkipField()branch returns early and pops first ("undopush_backto keep the stack balanced"). - The truncation branch does not pop:
if (HWY_UNLIKELY(result_.pos + num_u32 > span_.size())) {
NotifyInvalid("Invalid IFields: pos %zu + num_u32 %u > size %zu\n",
result_.pos, num_u32, span_.size());
return; // end_ is still non-empty
}
So when the stored size of an IFields is larger than the span, ~ReadVisitor fails HWY_ASSERT(end_.empty()); // Bug if push/pop are not balanced. and the process aborts. Read() never returns.
ReadResult in io/fields.h documents that pos is 0 "if there was an unrecoverable error: any field has an invalid value, or the span is shorter than the data says it should be". Other invalid inputs, such as an out-of-range enum, bool or float, already return pos == 0, so only this path is inconsistent. main (3ed403e) has the same code.
This affects gemma/model_store.cc, which checks result.pos after reading the config ("Error deserializing config") and each MatPtr ("Deserializing MatPtr %s failed (pos %zu of %zu)."). When an .sbs file is truncated or corrupt, users get the internal Assert end_.empty() in fields.cc instead of those messages. Both callers abort on pos == 0 anyway, so the main effect is the misleading diagnostic. Any other caller that wants to handle pos == 0 cannot do so.
Minimal repro
Add this test to io/fields_test.cc:
// If the stored size exceeds the span, Read must report the error via
// `pos == 0` (see `ReadResult`) instead of aborting.
TEST(FieldsTest, TestTruncatedData) {
const NewFields new_fields = ModifiedNewFields();
const std::vector<uint32_t> storage = new_fields.Write();
ASSERT_GT(storage.size(), 2u);
NewFields copy;
const ReadResult result = copy.Read(Span(storage.data(), 2), 0);
EXPECT_EQ(0, result.pos);
}
cmake -B build -DGEMMA_ENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build -j4 --target fields_test
./build/fields_test --gtest_filter='*Truncated*'
Expected vs actual
Expected: Read returns a ReadResult with pos == 0, as documented in fields.h, and the test passes.
Actual: the process aborts (SIGABRT, exit code 134):
[ RUN ] FieldsTest.TestTruncatedData
Invalid IFields: pos 1 + num_u32 112 > size 2
Abort at fields.cc:110: Assert end_.empty():
Environment
- gemma.cpp
dev@ 8073ef9 (also present onmain@ 3ed403e) - macOS 26.5, Apple M4, Apple clang 17.0.0, CMake Release build
Suggested fix
Pop end_ before returning, the same way the SkipField() branch does:
if (HWY_UNLIKELY(result_.pos + num_u32 > span_.size())) {
NotifyInvalid("Invalid IFields: pos %zu + num_u32 %u > size %zu\n",
result_.pos, num_u32, span_.size());
+ end_.pop_back(); // keep the stack balanced, see `~ReadVisitor`
return;
}
With this change, the test above and the existing fields_test cases pass (10/10). configs_test (9/9) and blob_store_test (2/2) also pass.
We have this fix and the regression test ready on a branch and will open the PR against dev ourselves.
- Vorherrschende Sprache
- C++
- Sterne
- 7.1k
- Forks
- 668
- Ø Merge
- 19 Std. 56 Min.
- Gemergte PRs (30 T.)
- 17
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus google/gemma.cpp
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
google/gemma.cpp#1036 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 68/100
Maintainer antworten meist innerhalb von 1 Tag
-
Reduce KV memory for local-attention layersEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
google/gemma.cpp#1016 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Add experimental W8A8 MatMul with optional QuaRot-style rotationEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
google/gemma.cpp#1002 · 8 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in google/gemma.cpp
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 9 Tagen
-
自定义颜色添加为常用颜色Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
mg-chao/snow-apps#2227 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug introduced: 5.0 cycle P3 XS
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
open-astro/AlpacaBridge#1722 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
returnoftheshadow/RotS_Live#521 ·
Maintainer antworten meist innerhalb von 1 Tag
-
crash lld:COFF
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 77/100
llvm/llvm-project#235970 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag