[lldb-dev] [Bug 43918] New: Debugserver doesn't continue with specified signal in `vCont` packet
https://bugs.llvm.org/show_bug.cgi?id=43918 Bug ID: 43918 Summary: Debugserver doesn't continue with specified signal in `vCont` packet Product: lldb Version: unspecified Hardware: PC OS: Linux Status: NEW Severity: enhancement Priority: P Component: All Bugs Assignee: lldb-dev@lists.llvm.org Reporter: dmitry.neve...@gmail.com CC: jdevliegh...@apple.com, llvm-b...@lists.llvm.org Created attachment 22778 --> https://bugs.llvm.org/attachment.cgi?id=22778&action=edit delve.log I'm debugging the following go program on MacOS 10.14.6. package main import ( "fmt" "os" "os/signal" ) func main() { sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt) sig := <- sigs fmt.Printf("Got a signal '%v', start shutting down...\n", sig) } The program waits for the SIGINT and exits. I'm sending SIGINT via `kill -2 `. Attached logs show that debugserver notifies go debugger that the program got SIGINT (`$T02` package), go debugger responds with `vCont;C02`, debugserver receives the packet, but doesn't call `MachProcess::Signal` and the program doesn't get the SIGINT. -- You are receiving this mail because: You are the assignee for the bug.___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
[lldb-dev] Slow expression evaluation (ASTImporter is too eager?)
Hello, I noticed that the AST importer is very eager to import classes/structs that were already completed, even if they are not needed. This is best illustrated with an example. struct C0 { int x = 0; }; struct C1 { int x = 1; C0* c0 = 0; }; struct C2 { int x = 2; C1* c1 = 0; }; int main() { C0 c0; C1 c1; C2 c2; return 0; // break here } When we evaluate “c2.x” in LLDB, AST importer completes and imports only class C2. This is working as intended. Similarly, evaluating “c1.x” imports just C1 and “c0.x” imports C0. However, if we evaluate “c2.x” after evaluating “c1.x” and “c0.x”, the importer suddenly imports both C1 and C0 (in addition to C2). See a log from a lldb session at the end of this email for illustration. I believe the culprit here is the following code at the end of the ASTNodeImporter::VisitRecordDecl method: if (D->isCompleteDefinition()) if (Error Err = ImportDefinition(D, D2, IDK_Default)) return std::move(Err); This will import a definition of class from LLDB if LLDB already happens to have a complete definition from before. For large programs, this can lead to importing very large chunks of ASTs even if they are not needed. I have tried to remove the code above from clang and test performance on several expressions in an Unreal engine sample - preliminary results show this could cut down evaluation time by roughly 50%. My prototype patch is below; note that couple of lldb tests are failing with a wrong error message, this is a work in progress. What would the experts here think? Is this a plausible direction? Cheers, Jaro diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 54acca7dc62..ebbce5c66c7 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2799,7 +2799,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { if (D->isAnonymousStructOrUnion()) D2->setAnonymousStructOrUnion(true); - if (D->isCompleteDefinition()) + if (!Importer.isMinimalImport() && D->isCompleteDefinition()) if (Error Err = ImportDefinition(D, D2, IDK_Default)) return std::move(Err); @@ -3438,6 +3438,9 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { if (ToInitializer) ToField->setInClassInitializer(ToInitializer); ToField->setImplicit(D->isImplicit()); + if (CXXRecordDecl *FieldType = D->getType()->getAsCXXRecordDecl()) + if (Error Err = ImportDefinitionIfNeeded(FieldType)) + return std::move(Err); LexicalDC->addDeclInternal(ToField); return ToField; } @@ -5307,7 +5310,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind()); - if (D->isCompleteDefinition()) + if (!Importer.isMinimalImport() && D->isCompleteDefinition()) if (Error Err = ImportDefinition(D, D2)) return std::move(Err); —— lldb session illustrating the unnecessary imports —- This shows that evaluation of “c2.x” after evaluation “c1.x” and “c0.x” calls to LayoutRecordType for C2, C1 and C0. $ lldb a.out (lldb) b h.cc:10 Breakpoint 1: where = a.out`main + 44 at h.cc:10:3, address = ... (lldb) r ... Process stopped ... (lldb) log enable lldb expr (lldb) p c2.x ... LayoutRecordType[6] ... for (RecordDecl*)0x... [name = 'C2'] ... (lldb) p c1.x ... LayoutRecordType[7] ... for (RecordDecl*)0x... [name = 'C1'] ... (lldb) p c0.x ... LayoutRecordType[8] ... for (RecordDecl*)0x... [name = 'C0'] ... (lldb) p c2.x ... LayoutRecordType[9] ... for (RecordDecl*)0x... [name = 'C2'] LayoutRecordType[10] ... for (RecordDecl*)0x... [name = 'C1'] LayoutRecordType[11] ... for (RecordDecl*)0x... [name = 'C0'] ... ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] Slow expression evaluation (ASTImporter is too eager?)
Can you post that patch on Phabricator with an '[ASTImporter]’ as a name prefix? This way the ASTImporter folks will see your patch (The ASTImporter is more of a Clang thing, so they might not read lldb-dev). Also it makes it easier to see/test your patch :) (And +Gabor just in case) > On Nov 6, 2019, at 10:25 PM, Jaroslav Sevcik via lldb-dev > wrote: > > Hello, > > I noticed that the AST importer is very eager to import classes/structs that > were already completed, even if they are not needed. This is best illustrated > with an example. > > struct C0 { int x = 0; }; > struct C1 { int x = 1; C0* c0 = 0; }; > struct C2 { int x = 2; C1* c1 = 0; }; > > int main() { > C0 c0; > C1 c1; > C2 c2; > > return 0; // break here > } > > When we evaluate “c2.x” in LLDB, AST importer completes and imports only > class C2. This is working as intended. Similarly, evaluating “c1.x” imports > just C1 and “c0.x” imports C0. However, if we evaluate “c2.x” after > evaluating “c1.x” and “c0.x”, the importer suddenly imports both C1 and C0 > (in addition to C2). See a log from a lldb session at the end of this email > for illustration. > > I believe the culprit here is the following code at the end of the > ASTNodeImporter::VisitRecordDecl method: > > if (D->isCompleteDefinition()) > if (Error Err = ImportDefinition(D, D2, IDK_Default)) > return std::move(Err); > > This will import a definition of class from LLDB if LLDB already happens to > have a complete definition from before. For large programs, this can lead to > importing very large chunks of ASTs even if they are not needed. I have tried > to remove the code above from clang and test performance on several > expressions in an Unreal engine sample - preliminary results show this could > cut down evaluation time by roughly 50%. > > My prototype patch is below; note that couple of lldb tests are failing with > a wrong error message, this is a work in progress. What would the experts > here think? Is this a plausible direction? > > Cheers, Jaro > > diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp > index 54acca7dc62..ebbce5c66c7 100644 > --- a/clang/lib/AST/ASTImporter.cpp > +++ b/clang/lib/AST/ASTImporter.cpp > @@ -2799,7 +2799,7 @@ ExpectedDecl > ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { >if (D->isAnonymousStructOrUnion()) > D2->setAnonymousStructOrUnion(true); > > - if (D->isCompleteDefinition()) > + if (!Importer.isMinimalImport() && D->isCompleteDefinition()) > if (Error Err = ImportDefinition(D, D2, IDK_Default)) >return std::move(Err); > > @@ -3438,6 +3438,9 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl > *D) { >if (ToInitializer) > ToField->setInClassInitializer(ToInitializer); >ToField->setImplicit(D->isImplicit()); > + if (CXXRecordDecl *FieldType = D->getType()->getAsCXXRecordDecl()) > + if (Error Err = ImportDefinitionIfNeeded(FieldType)) > + return std::move(Err); >LexicalDC->addDeclInternal(ToField); >return ToField; > } > @@ -5307,7 +5310,7 @@ ExpectedDecl > ASTNodeImporter::VisitClassTemplateSpecializationDecl( > >D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind()); > > - if (D->isCompleteDefinition()) > + if (!Importer.isMinimalImport() && D->isCompleteDefinition()) > if (Error Err = ImportDefinition(D, D2)) >return std::move(Err); > > > > —— lldb session illustrating the unnecessary imports —- > This shows that evaluation of “c2.x” after evaluation “c1.x” and “c0.x” calls > to LayoutRecordType for C2, C1 and C0. > $ lldb a.out > (lldb) b h.cc:10 > Breakpoint 1: where = a.out`main + 44 at h.cc:10:3, address = ... > (lldb) r > ... Process stopped ... > (lldb) log enable lldb expr > (lldb) p c2.x > ... > LayoutRecordType[6] ... for (RecordDecl*)0x... [name = 'C2'] > ... > (lldb) p c1.x > ... > LayoutRecordType[7] ... for (RecordDecl*)0x... [name = 'C1'] > ... > (lldb) p c0.x > ... > LayoutRecordType[8] ... for (RecordDecl*)0x... [name = 'C0'] > ... > (lldb) p c2.x > ... > LayoutRecordType[9] ... for (RecordDecl*)0x... [name = 'C2'] > LayoutRecordType[10] ... for (RecordDecl*)0x... [name = 'C1'] > LayoutRecordType[11] ... for (RecordDecl*)0x... [name = 'C0'] > ... > > ___ > lldb-dev mailing list > lldb-dev@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev