Recent

Author Topic: [SOLVED] Synapse Twitter application: access violation?  (Read 5429 times)

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
[SOLVED] Synapse Twitter application: access violation?
« on: June 14, 2012, 04:50:50 pm »
Hi all,

I've been working on my Twitter/oauth library and get it to retrieve tweets and display them.

Not being much of a JSON guru, I took the copy/paste approach... which seems to work.

However, running with debugging turned on gives an access violation at the end of the program.(as well as a memory leak)... probably something stupid wrt my JSON parsing - I'm not entirely clear on what objects I should free and when...

Here's a snippet to whet your appetite:
Code: [Select]
  Twitter:=OAuth1.Create;
  try
    // todo: use fcl-json or xml to parse these results...
    try
      Twitter.GetPINFunction:=@GetPIN; //Register PIN callback with object
      Twitter.ConsumerKey:=ConsumerKey;
      Twitter.ConsumerSecret:=ConsumerSecret;
      // Next two will be empty if not preauthorized and using PIN auth
      Twitter.AuthToken:=AccessToken;
      Twitter.AuthSecret:=AccessTokenSecret;
      Twitter.CallBackURL:='oob';
      Twitter.Protocol:='1.1';
      //Deprecated:
      //http://twitter.com/statuses/public_timeline.json
      Success:=Twitter.OAuthHTTPMethod('GET', 'https://api.twitter.com/1/statuses/home_timeline.json');
      // Returns json array with objects that represent tweets. A tweet object's user is itself an object
    except
      on E: Exception do
      begin
        writeln('Exception: '+E.ClassName+'/'+E.Message);
        Success:=false;
      end;
    end;

    if Success then
    begin
      write('Welcome');
      if Twitter.ScreenName<>'' then
        writeln(', '+Twitter.ScreenName)
      else
        if Twitter.UserID<>'' then writeln(', user '+Twitter.UserID) else writeln('');

      if (AccessToken='') and (AccessTokenSecret='') then
      begin
        //AccessToken:=Twitter.AuthToken;
        //AccessTokenSecret:=Twitter.AuthSecret;
        writeln('Your appliction is authenticated; you can try to use these codes next time:');
        writeln('Access token:');
        writeln(Twitter.AuthToken);
        writeln('Access secret:');
        writeln(Twitter.AuthSecret);
      end;

      ReturnBody:=TStringList.Create;
      try
        ReturnBody.LoadFromStream(Twitter.Document);
        writeln('Tweets:');
        Parser:=TJSONParser.Create(Returnbody.Text);
      finally
        ReturnBody.Free;
      end;
      try
        Tweets:=Parser.Parse;
        if not(Assigned(Tweets)) then
        begin
          writeln('No tweets found or other failure.');
        end
        else
        begin
          for TweetCounter:=0 to Tweets.Count-1 do
          begin
            Tweet:=TJSONObject(Tweets.Items[TweetCounter]);
            //created_at (date): in this format Thu Jun 14 11:21:51 +0000 2012
            //id (integer/long int?
            //text
            //then user is an array of is, name, screen_name etc
            writeln(DateTimeToStr(ParseTwitterTimestamp(Tweet.Strings['created_at']))+
              #9+Tweet.Strings['text']);
          end;
        end;
      finally
        FreeAndNil(Parser);
      end;
    end
    else
    begin
      // No success
      writeln('Could not get status.');
      writeln('Result code: '+inttostr(Twitter.ResultCode));
    end;
  finally
    Twitter.Free;
  end;

Full source code at
https://bitbucket.org/reiniero/fpctwit/downloads
Lazarus 1.1 (SVN 37399), FPC 2.6.1 x86, Windows, dwarf with sets debugging+heaptrc

Anybody knows what I'm doing wrong? Thanks.
« Last Edit: June 14, 2012, 06:05:52 pm by BigChimp »
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Synapse Twitter application: access violation?
« Reply #1 on: June 14, 2012, 04:58:55 pm »
Quote
dwarf with sets debugging+heaptrc
Use stabs: http://bugs.freepascal.org/view.php?id=20296  ;)

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Synapse Twitter application: access violation?
« Reply #2 on: June 14, 2012, 05:12:25 pm »
Ok, that doesn't give an AV anymore, just a number of leaks (a lot of them on the last line below:
Code: [Select]
var
  Application: Tfpctwit;
begin
  Application:=Tfpctwit.Create(nil);
  Application.Run;
  Application.Free;   
So does this mean that there is a mem leak outside my program, somewhere in the LCL or RTL/FCL?

Tried to free the Tweet and Tweets JSON object/data but got an AV again - they're probably deleted when the parser object that created them is freed.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Synapse Twitter application: access violation?
« Reply #3 on: June 14, 2012, 05:53:00 pm »
Code: [Select]
      finally
        Tweets.Free;
        FreeAndNil(Parser);
      end;
works for me.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Synapse Twitter application: access violation?
« Reply #4 on: June 14, 2012, 06:05:37 pm »
Thanks, does for me too. Still get confused when to free objects - whenever you create them yourself... or when you have a procedure create them for you...

It probably went wrong when I tried to free Tweet, which just was:
Code: [Select]
Tweet:=TJSONObject(Tweets.Items[TweetCounter]);
... in other words a reference to an existing object. IIUC, once the Tweets object goes out of scope/is freed, Tweet gets invalidated, so freeing it yourself will cause a problem as it you're trying to free something that's already been freed.
Or something.

Seems like my .Net past is coming back to haunt me now and again... there we created objects with gay abandon and let the garbage collection sort it out ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: [SOLVED] Synapse Twitter application: access violation?
« Reply #5 on: June 14, 2012, 06:28:34 pm »
Don't know why TJSONParser was written that way but Parse is a function that returns an object. If the result of the parsing was accessible as a property TJSONParser could have destroyed it automatically. Because it is a function, it hands over the object to the caller and it is up to the caller to destroy it.
It is a subtlety that is error prone.

Freeing a Tweets.Items[] directly leaves still the entry in Tweets that now points to nil. To remove an item do something like TJSONObject(Tweets).Delete(TweetCounter);

 

TinyPortal © 2005-2018