Re: [lldb-dev] Source-level stepping with emulated instructions
Thank you Pavel and Jim for very helpful answers. > Note, the “no debug info" part is not a strict requirement, > since lldb also has controls for “shared libraries we never > stop in when stepping” and “name regular expressions > for functions we don’t stop in”. At present, those controls > are just for user-specification. But if you find you need to > do something more programmatic, you can easily add > another “don’t stop in me” check specific to your > architecture. I have done some quick experiments with "target.process.thread.step-avoid-regexp" and it seems like I can use it to get the behavior we want so adding a “don’t stop in me” check specific to our architecture seems like a good solution for us. Best regards, Kjell On Tue, 18 Jan 2022 at 19:42, Jim Ingham via lldb-dev wrote: > > I think that description was a bit too much inside baseball…. > > Every time lldb stops outside a stepping range while stepping, it invokes a > set of “should stop here” agents to determine what to do next. If any of > those agents think we should NOT stop here, they are expected to produce a > set of instructions (i.e. a ThreadPlan) that drive the thread back to the > original code. > > The “we stopped in a function with no debug information, step back out” > behavior of lldb is implemented this way. So if you can make your emulated > instruction regions look like function calls w/o debug info, you would get > this behavior for free. But the mechanism is pretty flexible, and you just > need to leave yourself enough information to (a) know you are in one of your > regions and (b) how to drive the debugger to get back to the code that > invoked this emulated instruction, in order to get lldb’s “should stop here” > machinery to do what you want. > > Jim > > > On Jan 18, 2022, at 10:28 AM, Jim Ingham via lldb-dev > wrote: > > > > On Jan 16, 2022, at 11:23 PM, Pavel Labath wrote: > > Hi Kjell, > > if you say these instructions are similar to function calls, then it sounds > to me like the best option would be to get lldb to treat them like function > calls. I think (Jim can correct me if I'm wrong) this consists of two things: > - make sure lldb recognizes that these instructions can alter control flow > (Disassembler::GetIndexOfNextBranchInstruction). You may have done this > already. > - make sure lldb can unwind out of these "functions" when it winds up inside > them. This will ensure the user does not stop in these functions when he does > a "step over". This means providing it the correct unwind info so it knows > where the functions will return. (As the functions know how to return to the > original instructions, this information has to be somewhere, and is hopefully > accessible to the debugger.) Probably the cleanest way to do that would be to > create a new Module object, which would contain the implementations of all > these functions, and all of their debug info. Then you could provide the > unwind info through the usual channels (e.g. .debug_frame), and it has the > advantage that you can also include any other information about these > functions (names, line numbers, whatever...) > > > Pavel is right, if these blobs look like function calls with no debug > information, then lldb won’t stop in them by default. Note, the “no debug > info" part is not a strict requirement, since lldb also has controls for > “shared libraries we never stop in when stepping” and “name regular > expressions for functions we don’t stop in”. At present, those controls are > just for user-specification. But if you find you need to do something more > programmatic, you can easily add another “don’t stop in me” check specific to > your architecture. > > All this will work pretty transparently if the unwinder is able to tell us > how to get out of the function and back to it’s caller. But even if that’s > not the case, the “should stop here” mechanism in lldb works by at a lower > level by having the agent saying we should NOT stop here return a ThreadPlan > telling us how to get to the caller frame. For a function call, you get the > step out plan for free. But that’s not a requirement, your emulated > instruction region doesn’t strictly need to be a function call, provided you > know how to produce a thread plan that will step out of it. > > Jim > > > > pl > > On 15/01/2022 07:49, Kjell Winblad via lldb-dev wrote: > > Hi! > I'm implementing LLDB support for a new processor architecture that > the company I'm working for has created. The processor architecture > has a few emulated instructions. An emulated instruction works by > jumping to a specific address that contains the start of a block of > instructions that emulates the emulated instructions. The emulated > instructions execute with interrupts turned off to be treated as > atomic by the programmer. So an emulated instruction is similar to a > function call. However, the address that the instruction jumps to is > implicit and not
Re: [lldb-dev] Multiple platforms with the same name
On 19/01/2022 00:38, Greg Clayton wrote: Platforms can contain connection specific setting and data. You might want to create two different "remote-linux" platforms and connect each one to a different remote linux machine. Each target which uses this platform would each be able to fetch files, resolve symbol files, get OS version/build string/kernel info, get set working directory from the remote server they are attached. Since each platform tends to belong to a target and since you might want to create two different targets and have each one connected to a different remote machine, I believe it is fine to have multiple instances. I would vote to almost always create a new instance unless it is the host platform. Though it should be possible to create to targets and possibly set the platform on one target using the platform from another that might already be connected. I am open to suggestions if anyone has any objections. Greg I agree that permitting multiple platforms would be a more principled position, but it was not clear to me if that was ever planned to be the case. If it was (or if we want it to be), then I think we need to start making bigger distinctions between the platform plugins (classes), and the actual instantiations of those classes. Currently there is no way to refer to "older" instances of the platforms as they all share the same name (the name of the plugin). Like, you can enumerate them through SBDebugger.GetPlatformAtIndex(), but that's about the only thing you can do as all the interfaces (including the SB ones) take a platform _name_ as an argument. This gets particularly confusing as in some circumstances we end up choosing the newer one (e.g. if its the "current" platform) and sometimes the older. If we want to do that, then this is what I'd propose: a) Each platform plugin and each platform instance gets a name. We enforce the uniqueness of these names (within their category). b) "platform list" outputs two block -- the list of available plugins and the list of plugin instances c) a new "platform create" command to create a platform - e.g. "platform create my-arm-test-machine --plugin remote-linux" d) "platform select" selects the platform with the given /instance/ name - for convenience and compatibility if the name does not refer to any existing platform instance, but it *does* refer to a platform plugin, it would create a platform instance with the same name as the class. (So the first "platform select remote-linux" would create a new instance (also called remote-linux) and all subsequent selects would switch to that one -- a change to existing behavior) e) SBPlatform gets a static factory function taking two string arguments f) existing SBPlatform constructor (taking one string) creates a new platform instance with a name selected by us (remote-linux, remote-linux-2, etc.), but its use is discouraged/deprecated. g) all other existing APIs (command line and SB) remain unchanged but any "platform name" argument is taken to mean the platform instance name, and it has the "platform select" semantics (select if it exists, create if it doesn't) I think this would strike a good balance between a consistent interface and preserving existing semantics. The open questions are: - is it worth it? While nice in theory, personally I have never actually needed to connect to more than one machine at the same time. - what to do about platform-specific settings. The functionality has existed for a long time, but there was only one plugin (PlatformDarwinKernel) using it. I've now added a bunch of settings to the qemu-user platform on the assumption that there will only be one instance of the class. These are global, but they would really make more sense on a per-instance basis. We could either leave it be (I don't need multiple instances now), or come up with a way to have per-platform settings, similar like we do for targets. We could also do something with the "platform settings" command, which currently only sets the working directory. Let me know what you think, Pavel ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
[lldb-dev] Is GetLogIf**All**CategoriesSet useful?
Hi all, In case you haven't noticed, I'd like to draw your attention to the in-flight patches (https://reviews.llvm.org/D117382, https://reviews.llvm.org/D117490) whose goal clean up/improve/streamline the logging infrastructure. I'm don't want go into technical details here (they're on the patch), but the general idea is to replace statements like GetLogIf(Any/All)CategoriesSet(LIBLLDB_LOG_CAT1 | LIBLLDB_LOG_CAT2) with GetLogIf(Any/All)(LLDBLog::Cat1 | LLDBLog::Cat2) i.e., drop macros and make use of templates to make the function calls shorter and safer. The reason I'm writing this email is to ask about the "All" versions of these logging functions. Do you find them useful in practice? I'm asking that because I've never used this functionality. While I can't find anything wrong with the concept in theory, practically I think it's just confusing to have some log message appear only for some combination of enabled channels. It might have made some sense when we had a "verbose" logging channel, but that one is long gone (we still have a verbose logging *flag*). In fact, out of all our GetLogIf calls (1203), less than 1% (11*) uses the GetLogIfAll form with more than one category. Of those, three are in tests, one is definitely a bug (it combines the category with LLDB_LOG_OPTION_VERBOSE), and the others (7) are of questionable usefulness (to me anyway). If we got rid of this, we could simplify the logging calls even further and have something like: Log *log = GetLog(LLDBLog::Process); everywhere. cheers, pl (*) I used this command to count: $ git grep -e LogIfAll -A 1 | fgrep -e '|' | wc -l ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] Multiple platforms with the same name
> On Jan 19, 2022, at 4:28 AM, Pavel Labath wrote: > > On 19/01/2022 00:38, Greg Clayton wrote: >> Platforms can contain connection specific setting and data. You might want >> to create two different "remote-linux" platforms and connect each one to a >> different remote linux machine. Each target which uses this platform would >> each be able to fetch files, resolve symbol files, get OS version/build >> string/kernel info, get set working directory from the remote server they >> are attached. Since each platform tends to belong to a target and since you >> might want to create two different targets and have each one connected to a >> different remote machine, I believe it is fine to have multiple instances. >> I would vote to almost always create a new instance unless it is the host >> platform. Though it should be possible to create to targets and possibly set >> the platform on one target using the platform from another that might >> already be connected. >> I am open to suggestions if anyone has any objections. >> Greg > > I agree that permitting multiple platforms would be a more principled > position, but it was not clear to me if that was ever planned to be the case. We made a choice early on in lldb that it would be a one-to-many debugger (as opposed to gdb where you use one gdb process to debug one inferior). The idea was to allow people who have more complex inter-app communications to use the scripting features of lldb to make the process of debugging IPC and such-like more natural (like a “step-in” that steps across process boundaries when you step into a message dispatch). Or to run two instances that are slightly different and compare the paths through some bit of code. Or other cool uses we hadn’t thought of. I don’t do this kind of debugging much either, but then I just debug lldb all the time which is a fairly simple process, and it’s communication with the stub is pretty simple. So I don’t think that’s dispositive for how useful this design actually is... Since the Platform class holds details about the current debug sessions on that platform, it has to take part in this design, which means either allowing one Platform to connect to all instances of it’s kind that lldb might want to debug, or making one Platform per instance. The latter design was what we had always intended, it is certainly how we’ve talked about it for as long as I can remember. OTOH, the whole Platform class is a bit of a mashup, since it holds both “things you need to know about a class of systems in order to debug on them” and “the connection you make to a particular instance”. I think the intention would be clearer if we separated the “PlatformExpert” part of Platform and the “the Remote machine I’m talking to” part of Platform. > > If it was (or if we want it to be), then I think we need to start making > bigger distinctions between the platform plugins (classes), and the actual > instantiations of those classes. Currently there is no way to refer to > "older" instances of the platforms as they all share the same name (the name > of the plugin). Like, you can enumerate them through > SBDebugger.GetPlatformAtIndex(), but that's about the only thing you can do > as all the interfaces (including the SB ones) take a platform _name_ as an > argument. This gets particularly confusing as in some circumstances we end up > choosing the newer one (e.g. if its the "current" platform) and sometimes the > older. > > If we want to do that, then this is what I'd propose: > a) Each platform plugin and each platform instance gets a name. We enforce > the uniqueness of these names (within their category). > b) "platform list" outputs two block -- the list of available plugins and the > list of plugin instances > c) a new "platform create" command to create a platform > - e.g. "platform create my-arm-test-machine --plugin remote-linux" > d) "platform select" selects the platform with the given /instance/ name > - for convenience and compatibility if the name does not refer to any > existing platform instance, but it *does* refer to a platform plugin, it > would create a platform instance with the same name as the class. (So the > first "platform select remote-linux" would create a new instance (also called > remote-linux) and all subsequent selects would switch to that one -- a change > to existing behavior) > e) SBPlatform gets a static factory function taking two string arguments > f) existing SBPlatform constructor (taking one string) creates a new platform > instance with a name selected by us (remote-linux, remote-linux-2, etc.), but > its use is discouraged/deprecated. > g) all other existing APIs (command line and SB) remain unchanged but any > "platform name" argument is taken to mean the platform instance name, and it > has the "platform select" semantics (select if it exists, create if it > doesn't) > > I think this would strike a good balance between a
Re: [lldb-dev] Is GetLogIf**All**CategoriesSet useful?
> On Jan 19, 2022, at 6:40 AM, Pavel Labath wrote: > > Hi all, > > In case you haven't noticed, I'd like to draw your attention to the in-flight > patches (https://reviews.llvm.org/D117382, https://reviews.llvm.org/D117490) > whose goal clean up/improve/streamline the logging infrastructure. > > I'm don't want go into technical details here (they're on the patch), but the > general idea is to replace statements like > GetLogIf(Any/All)CategoriesSet(LIBLLDB_LOG_CAT1 | LIBLLDB_LOG_CAT2) > with > GetLogIf(Any/All)(LLDBLog::Cat1 | LLDBLog::Cat2) > i.e., drop macros and make use of templates to make the function calls > shorter and safer. > > The reason I'm writing this email is to ask about the "All" versions of these > logging functions. Do you find them useful in practice? > > I'm asking that because I've never used this functionality. While I can't > find anything wrong with the concept in theory, practically I think it's just > confusing to have some log message appear only for some combination of > enabled channels. It might have made some sense when we had a "verbose" > logging channel, but that one is long gone (we still have a verbose logging > *flag*). > > In fact, out of all our GetLogIf calls (1203), less than 1% (11*) uses the > GetLogIfAll form with more than one category. Of those, three are in tests, > one is definitely a bug (it combines the category with > LLDB_LOG_OPTION_VERBOSE), and the others (7) are of questionable usefulness > (to me anyway). > > If we got rid of this, we could simplify the logging calls even further and > have something like: > Log *log = GetLog(LLDBLog::Process); > everywhere. The only time I’ve ever “used” GetLogIfAll was when I added another LOG option to a log call, not noticing it was “All”, finding the new log didn’t work, and going back to switch “All” to “Any”. I vote for removing it. Jim > > cheers, > pl > > (*) I used this command to count: > $ git grep -e LogIfAll -A 1 | fgrep -e '|' | wc -l ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] Is GetLogIf**All**CategoriesSet useful?
> On Jan 19, 2022, at 10:25 AM, Jim Ingham wrote: > > > >> On Jan 19, 2022, at 6:40 AM, Pavel Labath wrote: >> >> Hi all, >> >> In case you haven't noticed, I'd like to draw your attention to the >> in-flight patches (https://reviews.llvm.org/D117382, >> https://reviews.llvm.org/D117490) whose goal clean up/improve/streamline the >> logging infrastructure. >> >> I'm don't want go into technical details here (they're on the patch), but >> the general idea is to replace statements like >> GetLogIf(Any/All)CategoriesSet(LIBLLDB_LOG_CAT1 | LIBLLDB_LOG_CAT2) >> with >> GetLogIf(Any/All)(LLDBLog::Cat1 | LLDBLog::Cat2) >> i.e., drop macros and make use of templates to make the function calls >> shorter and safer. >> >> The reason I'm writing this email is to ask about the "All" versions of >> these logging functions. Do you find them useful in practice? >> >> I'm asking that because I've never used this functionality. While I can't >> find anything wrong with the concept in theory, practically I think it's >> just confusing to have some log message appear only for some combination of >> enabled channels. It might have made some sense when we had a "verbose" >> logging channel, but that one is long gone (we still have a verbose logging >> *flag*). >> >> In fact, out of all our GetLogIf calls (1203), less than 1% (11*) uses the >> GetLogIfAll form with more than one category. Of those, three are in tests, >> one is definitely a bug (it combines the category with >> LLDB_LOG_OPTION_VERBOSE), and the others (7) are of questionable usefulness >> (to me anyway). >> >> If we got rid of this, we could simplify the logging calls even further and >> have something like: >> Log *log = GetLog(LLDBLog::Process); >> everywhere. > > The only time I’ve ever “used” GetLogIfAll was when I added another LOG > option to a log call, not noticing it was “All”, finding the new log didn’t > work, and going back to switch “All” to “Any”. > > I vote for removing it. +1 > > Jim > > >> >> cheers, >> pl >> >> (*) I used this command to count: >> $ git grep -e LogIfAll -A 1 | fgrep -e '|' | wc -l ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] Is GetLogIf**All**CategoriesSet useful?
I also vote to remove and simplify. > On Jan 19, 2022, at 6:40 AM, Pavel Labath wrote: > > Hi all, > > In case you haven't noticed, I'd like to draw your attention to the in-flight > patches (https://reviews.llvm.org/D117382, https://reviews.llvm.org/D117490) > whose goal clean up/improve/streamline the logging infrastructure. > > I'm don't want go into technical details here (they're on the patch), but the > general idea is to replace statements like > GetLogIf(Any/All)CategoriesSet(LIBLLDB_LOG_CAT1 | LIBLLDB_LOG_CAT2) > with > GetLogIf(Any/All)(LLDBLog::Cat1 | LLDBLog::Cat2) > i.e., drop macros and make use of templates to make the function calls > shorter and safer. > > The reason I'm writing this email is to ask about the "All" versions of these > logging functions. Do you find them useful in practice? > > I'm asking that because I've never used this functionality. While I can't > find anything wrong with the concept in theory, practically I think it's just > confusing to have some log message appear only for some combination of > enabled channels. It might have made some sense when we had a "verbose" > logging channel, but that one is long gone (we still have a verbose logging > *flag*). > > In fact, out of all our GetLogIf calls (1203), less than 1% (11*) uses the > GetLogIfAll form with more than one category. Of those, three are in tests, > one is definitely a bug (it combines the category with > LLDB_LOG_OPTION_VERBOSE), and the others (7) are of questionable usefulness > (to me anyway). > > If we got rid of this, we could simplify the logging calls even further and > have something like: > Log *log = GetLog(LLDBLog::Process); > everywhere. > > cheers, > pl > > (*) I used this command to count: > $ git grep -e LogIfAll -A 1 | fgrep -e '|' | wc -l ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] Multiple platforms with the same name
> On Jan 19, 2022, at 4:28 AM, Pavel Labath wrote: > > On 19/01/2022 00:38, Greg Clayton wrote: >> Platforms can contain connection specific setting and data. You might want >> to create two different "remote-linux" platforms and connect each one to a >> different remote linux machine. Each target which uses this platform would >> each be able to fetch files, resolve symbol files, get OS version/build >> string/kernel info, get set working directory from the remote server they >> are attached. Since each platform tends to belong to a target and since you >> might want to create two different targets and have each one connected to a >> different remote machine, I believe it is fine to have multiple instances. >> I would vote to almost always create a new instance unless it is the host >> platform. Though it should be possible to create to targets and possibly set >> the platform on one target using the platform from another that might >> already be connected. >> I am open to suggestions if anyone has any objections. >> Greg > > I agree that permitting multiple platforms would be a more principled > position, but it was not clear to me if that was ever planned to be the case. This code definitely evolved as time went on. Then we added the remote capabilities. As Jim said, there are two parts for the platform that _could_ be separated: PlatformLocal and PlatformRemote. Horrible names that can be improved upon, I am sure, but just names I quickly came up with. PlatformLocal would be "what can I do for a platform that only involves finding things on this machine for supporting debugging on a remote platform". This would involve things like: - where are remote files cached on the local machine for easy access - where can I locate SDK/NDK stuff that might help me for this platform - what architectures/triples are supported by this platform so it can be selected - how to start a debug session for a given binary (which might use parts of PlatformRemote) as platforms like "iOS-simulator" do not require any remote connections to be able to start a process. Same could happen for VM based debugging on a local machine. PlatformRemote - get/put files - get/set working directory - install executable so OS can see/launch it - create/delete directories So as things evolved, everything got thrown into the Platform case and we just made things work as we went. I am sure this can be improved. > > If it was (or if we want it to be), then I think we need to start making > bigger distinctions between the platform plugins (classes), and the actual > instantiations of those classes. Currently there is no way to refer to > "older" instances of the platforms as they all share the same name (the name > of the plugin). Like, you can enumerate them through > SBDebugger.GetPlatformAtIndex(), but that's about the only thing you can do > as all the interfaces (including the SB ones) take a platform _name_ as an > argument. This gets particularly confusing as in some circumstances we end up > choosing the newer one (e.g. if its the "current" platform) and sometimes the > older. > > If we want to do that, then this is what I'd propose: > a) Each platform plugin and each platform instance gets a name. We enforce > the uniqueness of these names (within their category). Maybe it would be better to maintain the name, but implement an instance identifier for each platform instance? > b) "platform list" outputs two block -- the list of available plugins and the > list of plugin instances If we added a instance identifier, then we could just show the available plug-in names followed by their instances? > c) a new "platform create" command to create a platform > - e.g. "platform create my-arm-test-machine --plugin remote-linux" Now we are assuming you want to connect to a remote machine when we create platform? "platform connect" can be used currently if we want to actually connect to a remote platform, but there is a lot of stuff in the iOS platforms that really only deals with finding stuff on the local machine. Each platform plugin in "platform connect" has the ability to create its own unique connection arguments and options which is nice for different platforms. The creation and connecting should still be done separately. Seeing the arguments you added above leads me to believe this is like a "select" and a "connect" all in one. And each "platform connect" has unique and different arguments and options that are tailored to each plug-in currently. > d) "platform select" selects the platform with the given /instance/ name > - for convenience and compatibility if the name does not refer to any > existing platform instance, but it *does* refer to a platform plugin, it > would create a platform instance with the same name as the class. (So the > first "platform select remote-linux" would create a new instance (also called > remote-linux) and all subsequent selects would switch to tha
Re: [lldb-dev] Is GetLogIf**All**CategoriesSet useful?
> On Jan 19, 2022, at 6:40 AM, Pavel Labath wrote: > > Hi all, > > In case you haven't noticed, I'd like to draw your attention to the in-flight > patches (https://reviews.llvm.org/D117382, https://reviews.llvm.org/D117490) > whose goal clean up/improve/streamline the logging infrastructure. > > I'm don't want go into technical details here (they're on the patch), but the > general idea is to replace statements like > GetLogIf(Any/All)CategoriesSet(LIBLLDB_LOG_CAT1 | LIBLLDB_LOG_CAT2) > with > GetLogIf(Any/All)(LLDBLog::Cat1 | LLDBLog::Cat2) > i.e., drop macros and make use of templates to make the function calls > shorter and safer. > > The reason I'm writing this email is to ask about the "All" versions of these > logging functions. Do you find them useful in practice? > > I'm asking that because I've never used this functionality. While I can't > find anything wrong with the concept in theory, practically I think it's just > confusing to have some log message appear only for some combination of > enabled channels. It might have made some sense when we had a "verbose" > logging channel, but that one is long gone (we still have a verbose logging > *flag*). > > In fact, out of all our GetLogIf calls (1203), less than 1% (11*) uses the > GetLogIfAll form with more than one category. Of those, three are in tests, > one is definitely a bug (it combines the category with > LLDB_LOG_OPTION_VERBOSE), and the others (7) are of questionable usefulness > (to me anyway). > > If we got rid of this, we could simplify the logging calls even further and > have something like: > Log *log = GetLog(LLDBLog::Process); Can a template function deduce the log type from an argument? Wouldn't this have to be: Log *log = GetLog(LLDBLog::Process); That is why I was hinting if we want to just use the enum class itself: Log *log = LLDBLog::GetLog(LLDBLog::Process); The template class in your second patch seems cool, but I don't understand how it worked without going and reading up on templates in C++ and spending 20 minutes trying to wrap my brain around it. Or do we just switch to a dedicated log class with unique methods: class LLDBLog: public Log { Log *Process() { return GetLog(1u << 0); } Log *Thread() { return GetLog(1u << 1); } }; and avoid all the enums? Then we can't ever feed a bad enum or #define into the wrong log class. ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
[lldb-dev] LLVM 14.0.0 Release Schedule
Hi, I've posted the proposed 14.0.0 Release Schedule here: https://llvm.discourse.group/t/llvm-14-0-0-release-schedule/5846 -Tom ___ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev