The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,708 other followers

Archive for the ‘Event’ Category

Delphi: when calling TThread.Synchronize, ensure the synchronised method handles exceptions

Posted by jpluimers on 2019/09/17

Since about a decade, TThread has a few overloaded [WayBack] Synchronize methods which all allow some specified synchronised method to run in the context of the main thread:

Any exceptions raised in that methods are caught using [WayBackSystem.AcquireExceptionObject and re-raised in the calling thread.

If that happens, you loose a piece of the stack information. I knew that, but found out the hard way that it does because I had to hunt for bugs through inherited code written by people that did not know.

This was part of the stack trace that code would show during an exception:

Exception EAccessViolation at $004D732F: Access violation at address $00409174 in module ''.....exe''.
Read of address 80808080
StackTrace:
(000D632F){.....exe} [004D732F] System.Classes.TThread.Synchronize$qqrp41System.Classes.TThread.TSynchronizeRecordo (Line 14975, "System.Classes.pas" + 40) + $0
(000D6430){.....exe} [004D7430] System.Classes.TThread.Synchronize$qqrxp22System.Classes.TThreadynpqqrv$v (Line 15007, "System.Classes.pas" + 9) + $A
(005D6E61){.....exe} [009D7E61] IdSync.DoThreadSync$qqrp18Idthread.TIdThreadynpqqrv$v (Line 281, "IdSync.pas" + 21) + $6
(005D6E87){.....exe} [009D7E87] IdSync.TIdSync.SynchronizeMethod$qqrynpqqrv$v (Line 326, "IdSync.pas" + 2) + $8

Exception EAccessViolation at $00409174: Access violation at address $00409174 in module ''.....exe''. Read of address $80808080 with StackTrace
(00008174){.....exe} [00409174] System.@IsClass$qqrxp14System.TObjectp17System.TMetaClass + $C

The first exception has a different address than the one in the exception message.

Which means that you miss the whole stack path to the _IsClass call (the underlying method implementing the as keyword) that the actual exception was initiated at.

And yes: the $80808080 is the FastMM4 marker for freed memory, so this was a use-after-free scenario.

A simple wrapper like this using a central logging facility gave much more insight in the actual cause:

procedure RunLoggedMethod(AMethod: TMethod);
begin
  try
    AMethod();
  except
    on E: Exception do
    begin
      Logger.LogExceptionDuringMethod(E, AMethod);
      raise; // mandatory to stay compatible with the old un-logged code
    end;
  end;
end;

Then call it like this inside a thread descendant:

Synchronize(RunLoggedMethod(MethodToRunInMainThread));

The old code was like this:

Synchronize(MethodToRunInMainThread);

This was quite easy to change, as I already had boiler code around exported DLL functions that had a similar construct (without the raise; as exceptions cannot pass DLL boundaries unless very specific circumstances hold).

Similar methods are needed to encapsulate procedure TIdSync.Synchronize(), procedure TIdSync.SynchronizeMethodprocedure TIdThread.Synchronize(Method: TThreadMethod) and [WayBack] Queue overloads:

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 1 Comment »

delphi: you can only access protected identifiers from parent classes in your own “Self” scope, or when you are “friends” with your parent (so you are in the same unit)

Posted by jpluimers on 2019/09/11

An interesting question from a while back: [WayBack] delphi – Should a descendant class’ method’s variable that is identical to Self, have access to its ancestor’s protected methods? – Stack Overflow

In unit A:

TParent = class
protected
  function DoSomething: TParent;
end;

In unit B:

TChild = class(TParent)
public
  procedure DoAnotherThing;
end;

implementation

procedure TChild.DoAnotherThing;
begin
  DoSomething.DoSomething
end;

This won’t compile, throwing a

cannot access protected symbol TParent.DoSomething

The kicker here is that the error message makes you think you are operating in Self context, but you are not as you are calling DoSomething.DoSomething where only the first DoSomething is in your Self context, but the second .DoSomethingis in the context of any TParent instance trying to access a public identifier.

Stefan Glienke posted [WayBack] a more elaborate answer explaining some workarounds.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Structure and Interpretation of Test Cases : Kevlin Henney on Vimeo

Posted by jpluimers on 2019/08/28

Must watch when you do unit testing (no matter the environment): [WayBackStructure and Interpretation of Test Cases : Kevlin Henney on Vimeo which he presented at Javazone 2018 [Archive.is]

via [WayBack] Kevlin Henney – Google+

–jeroen

Posted in Agile, Conference Topics, Conferences, Development, Event, Software Development, Unit Testing | Leave a Comment »

TestInsight provides a local JSON web-server from the IDE for the test-runner to communicate from

Posted by jpluimers on 2019/08/15

Stefan Glienke shared the TestInsight default JSON web-server location with me through chat; I like it!

Some endpoints:

The mechanism for accessing this JSON server are implemented in the TestInsight.Client.pas

You can find the endpoint base URL in TestInsightSettings.ini which by default looks like this:

[Config]
BaseUrl=http://WIN10-DELPHI:8102

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Please web-site owners (including memori.nl, sandsmedia.com, and many others): allow plus signs in email addresses when registering/contacting

Posted by jpluimers on 2019/08/05

I am quite amazed that many web-sites fail to allow email addresses of the form x+y@z.domain.

This is called subaddressing and has been in the email addressing specs since ages.

Do not validate, but send

Basically the only way to verify the validity of an email address is to send an email to it, and wait for it to be accepted or rejected.

Even the best regex will “have almost no false negatives”, which means they will reject valid email addresses.

Further reading

Please read and implement these specs before rejecting email addresses you think might be invalid:

  • [WayBack] RFC 5233 – Sieve Email Filtering: Subaddress Extension
  • [WayBack] RFC 3696 – Application Techniques for Checking and Transformation of Names
  • [WayBack] Mail::RFC822::Address

    The RFC allows comments to be arbitrarily nested. A single regular expression cannot cope with this.

  • [WayBack] Gmail address with “+” within the recipient name – Web Applications Stack Exchange

    any ASCII graphic (printing) character other than the at-sign (“@”), backslash, double quote, comma, or square brackets may appear without quoting.

  • [WayBack] [3527] Email addresses with plus sign (+)

    Sub-addressing

    Some mail services allow a user to append a +tag qualifier to their e-mail address (e.g., joeuser+tag@example.com). The text of tag can be used to apply filtering. The text of the tag can also be used to help a user figure out which organization “leaked” the user’s email address to a spammer. However, some mail servers violate RFC 5322, and the recommendations in RFC 3696, by refusing to send mail addressed to a user on another system merely because the local-part of the address contains the plus sign (+). Users of these systems cannot use plus addressing. On the other hand, most installations of the qmail and Courier Mail Server products support the use of a dash ‘-‘ as a separator within the local-part, such as joeuser-tag@example.com or joeuser-tag-sub-anything-else@example.com. This allows qmail through .qmail-default or .qmail-tag-sub-anything-else files to sort, filter, forward, or run an application based on the tagging system established. Disposable e-mail addresses of this form, using various separators between the base name and the tag are supported by several email services, including Runbox (plus and minus), Google Mail (plus), Yahoo! Mail Plus (minus), and FastMail (plus). The name sub-addressing is the generic term (used for plus-addressing and minus-addressing) found in some IETF standards-track documents, such as RFC 5233.

  • [WayBack] How to Find or Validate an Email Address

    Regexes Don’t Send Email

    Don’t go overboard in trying to eliminate invalid email addresses with your regular expression. The reason is that you don’t really know whether an address is valid until you try to send an email to it. And even that might not be enough. Even if the email arrives in a mailbox, that doesn’t mean somebody still reads that mailbox. If you really need to be sure an email address is valid, you’ll need to send an email to it that contains a code or link for the recipient to perform a second authentication step. And if you’re doing that, then there is little point in using a regex that may reject valid email addresses.

A nice overview of people trying to answer with a regular expression, and comments indicating all those attempts fail in one way or the other is at [WayBack] regex – How to validate an email address in JavaScript? – Stack Overflow

–jeroen

Posted in Conference Topics, Conferences, Event, Internet, Power User | Leave a Comment »

 
%d bloggers like this: