www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Where is LDSA created?

reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
Hi!

Faced with wrong unwinding behaviour: if exception is occured 
_d_eh_personality can't find appropriate catcher because TType == 
0x00

Before debug this I consider to find where is LDSA is created. I 
see it in DMD sources (dmd/src/dmd/backend/dwarfeh.d) but this 
file is removed from LDC.

Where is LDSA created?

(--mtriple=thumbv7m-unknown-none-eabi is used)
Jul 02
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Thursday, 2 July 2020 at 10:13:38 UTC, Denis Feklushkin wrote:
 Hi!

 Faced with wrong unwinding behaviour: if exception is occured 
 _d_eh_personality can't find appropriate catcher because TType 
 == 0x00

 Before debug this I consider to find where is LDSA is created. 
 I see it in DMD sources (dmd/src/dmd/backend/dwarfeh.d) but 
 this file is removed from LDC.

 Where is LDSA created?
Typo: LSDA, of course!
Jul 02
parent reply Johan <j j.nl> writes:
On Thursday, 2 July 2020 at 10:14:34 UTC, Denis Feklushkin wrote:
 On Thursday, 2 July 2020 at 10:13:38 UTC, Denis Feklushkin 
 wrote:
 Hi!

 Faced with wrong unwinding behaviour: if exception is occured 
 _d_eh_personality can't find appropriate catcher because TType 
 == 0x00

 Before debug this I consider to find where is LDSA is created. 
 I see it in DMD sources (dmd/src/dmd/backend/dwarfeh.d) but 
 this file is removed from LDC.

 Where is LDSA created?
Typo: LSDA, of course!
The exception tables are generated by LLVM (it is safe to assume that everything that is done by `dmd/src/dmd/backend/...` is done by LLVM for LDC). -Johan
Jul 02
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Thursday, 2 July 2020 at 10:36:58 UTC, Johan wrote:

 The exception tables are generated by LLVM (it is safe to 
 assume that everything that is done by 
 `dmd/src/dmd/backend/...` is done by LLVM for LDC).
LSDA is about language-specific data. It is generated by LLVM too? You mean that LLVM calls some callback to druntime for LSDA creation? grep isn't displays anything related to LSDA creation in ldc sources. Only druntime's scanLSDA.
Jul 02
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Thursday, 2 July 2020 at 11:29:45 UTC, Denis Feklushkin wrote:
 On Thursday, 2 July 2020 at 10:36:58 UTC, Johan wrote:

 The exception tables are generated by LLVM (it is safe to 
 assume that everything that is done by 
 `dmd/src/dmd/backend/...` is done by LLVM for LDC).
LSDA is about language-specific data. It is generated by LLVM too? You mean that LLVM calls some callback to druntime for LSDA creation? grep isn't displays anything related to LSDA creation in ldc sources. Only druntime's scanLSDA.
LSDA is generated at compile-time, yes? Or I understand something wrong?
Jul 05
parent reply kinke <noone nowhere.com> writes:
On Sunday, 5 July 2020 at 09:31:25 UTC, Denis Feklushkin wrote:
 On Thursday, 2 July 2020 at 11:29:45 UTC, Denis Feklushkin 
 wrote:
 On Thursday, 2 July 2020 at 10:36:58 UTC, Johan wrote:

 The exception tables are generated by LLVM (it is safe to 
 assume that everything that is done by 
 `dmd/src/dmd/backend/...` is done by LLVM for LDC).
LSDA is about language-specific data. It is generated by LLVM too? You mean that LLVM calls some callback to druntime for LSDA creation? grep isn't displays anything related to LSDA creation in ldc sources. Only druntime's scanLSDA.
LSDA is generated at compile-time, yes? Or I understand something wrong?
The EH tables (yes, that's what LSDA is, don't be fooled by its name) are static and generated by LLVM as Johan already mentioned, quite obviously without any druntime involvement. [The -exception-model you've been playing with probably affect their format.] Traversing these EH tables during stack unwinding (at runtime) is the job of the EH personality function associated with a function.
Jul 05
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 5 July 2020 at 11:19:44 UTC, kinke wrote:

 The EH tables (yes, that's what LSDA is, don't be fooled by its 
 name) are static and generated by LLVM as Johan already 
 mentioned, quite obviously without any druntime involvement. 
 [The -exception-model you've been playing with probably affect 
 their format.]
Yes I think D personality data for EH ABI can be corrupt.
 Traversing these EH tables during stack unwinding (at runtime) 
 is the job of the EH personality function associated with a 
 function.
Oh thanks!
Jul 06
parent reply kinke <noone nowhere.com> writes:
On Monday, 6 July 2020 at 20:43:33 UTC, Denis Feklushkin wrote:
 I think D personality data for EH ABI can be corrupt.
LLVM generating wrong tables is *extremely* unlikely. The D (and LDC) specific EH personality function (and catch hooks) in druntime seems to be quite okay too, because as I've already told you, we haven't seen any big issues for 32-bit ARM's EHABI a few years back, with both armv6-linux-gnueabihf and armv7a-linux-android. I don't know of any more recent test results, but I also don't remember any recent relevant changes in this part of druntime.
Jul 06
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Monday, 6 July 2020 at 20:57:51 UTC, kinke wrote:
 On Monday, 6 July 2020 at 20:43:33 UTC, Denis Feklushkin wrote:
 I think D personality data for EH ABI can be corrupt.
LLVM generating wrong tables is *extremely* unlikely.
Not wrong, but maybe language-specific part is not included into it for some target triplets? I cant check this because I still not found where is it shoud begenerated for ARM EHABI. I mean this D-specific information, what, for example, DMD generates here: https://github.com/dlang/dmd/blob/d17d08100203c24091f00f489a1d37a2d99b28ea/src/dmd/backend/dwarfeh.d#L299 And than druntime scans it by scanLSDA
 The D (and LDC) specific EH personality function (and catch 
 hooks) in druntime seems to be quite okay too, because as I've 
 already told you, we haven't seen any big issues for 32-bit 
 ARM's EHABI a few years back, with both armv6-linux-gnueabihf 
 and armv7a-linux-android. I don't know of any more recent test 
 results, but I also don't remember any recent relevant changes 
 in this part of druntime.
Latest ldc2 still produces code with TType = 0x00 Sample code: void main() { import std.exception; try { auto e = new Exception("sdf"); throw e; } catch(Exception e) { while(true){} } } With logUnwinding enabled for libunwind produces: (qemu) libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8039dad, start_ip=0x8039d6c, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8039d6c ehtp 0x8059134 additional 1 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x802783f, start_ip=0x80277ec, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 80277ec ehtp 0x805748c additional 1 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8000207, start_ip=0x8000190, func=.anonymous., lsda=0x8052240, personality=0x8027911 libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8027911 libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8000190 ehtp 0x8052238 additional 0 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8027269, start_ip=0x8027250, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8027250 ehtp 0x80573e4 additional 1 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8027107, start_ip=0x80270e6, func=.anonymous., lsda=0x8053378, personality=0x8027911 libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8027911 libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 80270e6 ehtp 0x8053370 additional 0 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x80271cb, start_ip=0x8027144, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8027144 ehtp 0x80573dc additional 1 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8027107, start_ip=0x80270e6, func=.anonymous., lsda=0x8053378, personality=0x8027911 libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8027911 libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 80270e6 ehtp 0x8053370 additional 0 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8026f83, start_ip=0x8026d5c, func=.anonymous., lsda=0x8053360, personality=0x8039d39 libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039d39 libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8026d5c ehtp 0x8053358 additional 0 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x8026d59, start_ip=0x8026d1c, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 8 start_ip 8026d1c ehtp 0x80573b4 additional 1 libunwind: unwind_phase1(ex_ojb=0x20008a68): _URC_CONTINUE_UNWIND libunwind: unwind_phase1(ex_ojb=0x20008a68): pc=0x80002b5, start_ip=0x800029a, func=.anonymous., lsda=0x0, personality=0x8039c6d libunwind: unwind_phase1(ex_ojb=0x20008a68): calling personality function 0x8039c6d libunwind: findUnwindSections: section 0x8053a48 length 0x5a90 libunwind: unwind_phase1(ex_ojb=0x20008a68): personality result 9 start_ip 800029a ehtp 0x8053a74 additional 1 dwarfeh(375) fatal error gdb shows what unwinding goes into appropriate handler, but LSDA contains TType of exception == 0x0, and this mismaching leads to unwind to next table and all goes wrong.
Jul 18
parent reply "David Nadlinger" <code klickverbot.at> writes:
On 18 Jul 2020, at 22:17, Denis Feklushkin via digitalmars-d-ldc wrote:
 I cant check this because I still not found where is it shoud 
 begenerated for ARM EHABI.
 I mean this D-specific information
It's generated by LLVM, and not really language-specific. LDSA contains the information about the different catch/cleanup clauses. — David
Jul 18
next sibling parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Saturday, 18 July 2020 at 21:27:42 UTC, David Nadlinger wrote:
 On 18 Jul 2020, at 22:17, Denis Feklushkin via 
 digitalmars-d-ldc wrote:
 I cant check this because I still not found where is it shoud 
 begenerated for ARM EHABI.
 I mean this D-specific information
It's generated by LLVM, and not really language-specific.
scanLSDA description contains this text: * The dmd Call Site Table is structurally different from other implementations. It * is organized as nested ranges, and one ip can map to multiple ranges. The most * nested candidate is selected when searched. Other implementations have one candidate * per ip. Is this erroneous comment?
 LDSA contains the information about the different catch/cleanup 
 clauses.
Yes, but for unknown reason not in my case.
Jul 18
parent Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Saturday, 18 July 2020 at 21:37:00 UTC, Denis Feklushkin wrote:
 On Saturday, 18 July 2020 at 21:27:42 UTC, David Nadlinger 
 wrote:
 On 18 Jul 2020, at 22:17, Denis Feklushkin via 
 digitalmars-d-ldc wrote:
 I cant check this because I still not found where is it shoud 
 begenerated for ARM EHABI.
 I mean this D-specific information
It's generated by LLVM, and not really language-specific.
In other words, it seems strange to me that the LLVM knows such details about Dlang.
 scanLSDA description contains this text:

  * The dmd Call Site Table is structurally different from other 
 implementations. It
  * is organized as nested ranges, and one ip can map to 
 multiple ranges. The most
  * nested candidate is selected when searched. Other 
 implementations have one candidate
  * per ip.

 Is this erroneous comment?
Jul 18
prev sibling parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Saturday, 18 July 2020 at 21:27:42 UTC, David Nadlinger wrote:
 On 18 Jul 2020, at 22:17, Denis Feklushkin via 
 digitalmars-d-ldc wrote:
 I cant check this because I still not found where is it shoud 
 begenerated for ARM EHABI.
 I mean this D-specific information
It's generated by LLVM, and not really language-specific. LDSA contains the information about the different catch/cleanup clauses. — David
Ah, probably, understand: LSDA is just bad name for this thing Please tell me ways to debug lsda generation in ldc/llvm? How to understand why zero is wrotten into TType?
Jul 18
next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On 18 Jul 2020, at 22:49, Denis Feklushkin via digitalmars-d-ldc wrote:
 Ah, probably, understand: LSDA is just bad name for this thing

 Please tell me ways to debug lsda generation in ldc/llvm?
 How to understand why zero is wrotten into TType?
Either llvm-readelf or llvm-objdump decodes the LSDA, I think. I'd really suggest compiling your application for ARM/Linux first and verifying whether things work there, though. They likely will, and you'll at least have a basis for comparison. — David
Jul 18
prev sibling parent reply kinke <noone nowhere.com> writes:
On Saturday, 18 July 2020 at 21:49:43 UTC, Denis Feklushkin wrote:
 How to understand why zero is wrotten into TType?
I've already pointed you to a Linux specificum: https://github.com/ldc-developers/druntime/blob/19731a92a97dbe4d7f7a4e15ceaff8444a1f879a/src/rt/dwarfeh.d#L926-L930 where TType is overridden for 32-bit ARM. Try getting rid of `version (linux)` there.
Jul 19
parent Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 19 July 2020 at 08:56:59 UTC, kinke wrote:
 On Saturday, 18 July 2020 at 21:49:43 UTC, Denis Feklushkin 
 wrote:
 How to understand why zero is wrotten into TType?
I've already pointed you to a Linux specificum: https://github.com/ldc-developers/druntime/blob/19731a92a97dbe4d7f7a4e15ceaff8444a1f879a/src/rt/dwarfeh.d#L926-L930 where TType is overridden for 32-bit ARM. Try getting rid of `version (linux)` there.
Hoho! It works! Great! I seen your proposal about `version (linux)` there weeks ago, probably tried and it isn't helped. Most likely, I just confused different source trees on my side. Thanks, Martin and David!
Jul 19