Connect with us

FACEBOOK

Async stack traces in folly: Synchronous and asynchronous stack traces

Published

on

This article was written by Lee Howes and Lewis Baker from Facebook.

This is the second in a series of posts covering how we have used C++ coroutines at Facebook to regain stack traces for dependent chains of asynchronous waiting tasks. In the previous blog post we talked about the work we have done to implement stack traces for asynchronous coroutine code. Here we’ll go into more detail on the technical differences and challenges involved in implementing async stack traces on top of C++ coroutines, compared with traditional stack traces.

Normal synchronous stack traces

With normal stacks, when you call a function the compiler generates code that automatically maintains a linked list of stack frames and this list represents the call stack. At the start of each frame is a structure that (at least on Intel architectures) looks like this:

struct stack_frame { stack_frame* nextFrame; void* returnAddress;
}; 

This structure is usually filled out by specialised assembly instructions. e.g. in x86_64, a caller will execute a call instruction, which pushes the return address on the stack and jumps to the function entry point. Then the first instructions of the callee pushes the ebp register (which usually holds the pointer to the current stack_frame structure) onto the stack and then copies the esp register (which now contains the pointer to the stack_frame structure we just populated) into the ebp register.

For example:

Advertisement
free widgets for website
caller: ... call callee # Pushes address of next instruction onto stack, # populating 'returnAddress' member of 'stack_frame'. # Then jumps to 'callee' address. mov rsp[-16], rax # Save the result somewhere ... callee: push rbp # Push rbp (stack_frame ptr) onto stack (populates 'nextFrame' member) mov rbp, rsp # Update rbp to point to new stack_frame sub rsp, 16 # Reserve an additional 16 bytes of stack-space ... mov rax, 42 # Set return-value to 42 leave # Copy rbp -> rsp, pop rbp from stack ret # Pop return address from top of stack and jump to it 

When a debugger or profiler captures a stack trace for a given thread, it obtains a pointer to the first stack frame from the thread’s ebp register and then starts walking this linked list until it reaches the stack root, recording the return addresses it sees along the way in a buffer.

Subsequent profiling tools may then translate the addresses to function names and/or file+line numbers using a symbolizer that makes use of debug info for the binary, and this information may be logged or displayed as useful for the tool in question.

Usually these stack frames live in a single contiguous memory region and the data structure looks a bit like this:

If we want to walk the async-stack trace instead of the normal stack trace then we still want to first start walking normal stack frames just like we do for a normal stack trace. A coroutine may call normal functions and we want to include the frames for these normal function calls in the stack trace. However, when we get to the frame corresponding to the top-most coroutine (in this case coro_function_1) we do not want to follow the ‘nextFrame‘ link into the coroutine_handle::resume method as the normal stack walking would. Instead we need a link to the waiting coroutine. At this point in the trace the histories for the normal stack trace and the async-stack trace diverge. To walk an async-stack trace involves answering a few questions:

  • How do we identify which stack frames correspond to async frames?
  • How do we find the address of the next async frame?
  • How and where do we allocate storage for the async frame data?
See also  Amazon, Apple, Google, and Facebook sign public letter supporting voting rights

Before we can implement any of this, we need to understand a bit more about how coroutines are structured.

How do coroutine “stacks” differ from normal stacks?

When you call a coroutine in C++, this allocates storage for a coroutine frame. The allocation is usually obtained from the heap although the compiler is free to optimise out this allocation in some circumstances, for example by inlining the allocation into the frame of the caller.

Advertisement
free widgets for website

The compiler uses the coroutine frame storage to store all of the state that needs to be preserved when the coroutine is suspended so that it is available when the coroutine is later resumed. This usually includes storage for function parameters, local variables, temporaries and any other state the compiler deems necessary, such as at which suspend-point the coroutine is suspended.

The coroutine frame also includes storage of a special object, the coroutine promise, which controls the behaviour of the coroutine. The compiler lowers your coroutine function into a sequence of calls to methods on the coroutine promise object at certain key points within the coroutine body, in addition to the user-written code of the coroutine. The coroutine promise controls the behaviour of the coroutine by implementing the desired behaviour in these methods. For more details about the promise type see the blog-post Understanding the promise type.

The promise type is determined based on the signature of the coroutine function and for most coroutine types is based solely on the return-type of the coroutine. This allows coroutines that return a given return type (eg. folly::coro::Task<T>) to store additional per-coroutine-frame data within the coroutine frame by adding data members to the promise type.

For the clang implementation, the layout of a coroutine frame for a given coroutine function looks a bit like this:

struct __foo_frame { using promise_type = typename std::coroutine_traits<Ret, Arg1, Arg2>::promise_type; void(*resumeFn)(void*); // coroutine_handle::resume() function-pointer void(*destroyFn)(void*); // coroutine_handle::destroy() function-pointer promise_type promise; // coroutine promise object int suspendPoint; // keeps track of which suspend-point coroutine is suspended at char extra[458]; // extra storage space for local variables, parameters, // temporaries, spilled registers, etc.
}; 

When a coroutine is suspended, all of the state for that coroutine invocation is stored in the coroutine frame and there is no corresponding stack frame. However, when a coroutine is resumed on a given thread, this activates a stack frame for that coroutine on that thread’s stack (like a normal function) and this stack frame is used for any temporary storage whose lifetime does not span a suspend point.

Advertisement
free widgets for website

When a coroutine body is currently executing, the pointer to the current coroutine frame is usually held in a register, which allows it to quickly reference state within the coroutine frame. However, this address may also be spilled into the stack frame in some cases, in particular when the coroutine is calling another function.

See also  Facebook Marketplace scam: Masterton woman charged after tool sold 47 times, never delivered

Thus, when a coroutine is active and has called another function, the memory layout will look something like this:

Note in particular that walking the asynchronous version of the stack means diverging into heap memory by following the framePointer in coro_function_1. Unlike the pointer to the current stack frame, which can generally be assumed to be stored in the rbp register, there is no standard location for the pointer to the coroutine frame. This has implications for how we are able to navigate from a stack-frame to its corresponding async-frame data.

Chaining asynchronous stack frames

To be able to produce a stack trace that represents the async-call chain instead of the normal synchronous call chain, we need to be able to walk the chain of coroutine frames, recording the return/continuation address of each coroutine as we walk the chain.

The first piece of the puzzle to be solved is storing the state needed to be able to walk the async stack-frames during an async stack trace. For each async-stack frame we need to be able to determine the address of the next async-stack frame and we need to be able to determine the return address of the current stack-frame.

Advertisement
free widgets for website

One of the constraints to be aware of here is that the code that is going to be walking the stack trace is not necessarily going to have access to debug information for the program. Profiling tooling, for example, may want to sample function offsets only and symbolize later, as it does for synchronous stack traces. We must be able to walk the async stack without needing additional complex data structures which could make the stack walk overly expensive. For example, profiling tools built on the Linux eBPF facility must be able to execute in a deterministic, finite amount of time.

There is technically enough information in the folly::coro::Task‘s promise type, folly::coro::TaskPromise, to be able to walk to the next frame, as it’s already storing the coroutine_handle for the continuation and the coroutine frame of that continuation already encodes information about which suspend point of which coroutine function is awaiting it in its resumeFn and suspendPoint members. However, there are some challenges with trying to use this information directly in walking an async-stack trace.

Representing a chain of async stack-frames

If we have a pointer to a coroutine-frame stored in a coroutine_handle then in theory, if we know the layout of the promise object, we can calculate the address of the ‘continuation‘ member of the promise which contains the address of the next coroutine-frame simply by adding a constant offset to the coroutine-frame pointer.

One approach is that we might require that all promise types store a coroutine_handle with the continuation as their first data-member:

template<typename T>
struct TaskPromise { std::coroutine_handle<void> continuation; Try<T> result; ...
}; struct __some_coroutine_frame { void(*resumeFn)(void*); void(*destroyFn)(void*); TaskPromise<int> promise; int suspendPoint;
}; 

Then, even if we do not know the concrete promise type, we know that its first member is a coroutine_handle and that the promise is placed immediately after the two function pointers. From the perspective of a debugger walking the async-stack trace it could assume that coroutine frames look like:

Advertisement
free widgets for website
struct coroutine_frame { void(*resumeFn)(void*); void(*destroyFn)(void*); coroutine_frame* nextFrame;
}; 

Unfortunately, this approach breaks down when the promise-type is overaligned (that is, it has an alignment larger than 2 pointers: 32 bytes or larger on 64-bit platforms). This can happen if the folly::coro::Task<T> type is instantiated for an overaligned type, T, for example, a matrix type optimised for use with SIMD instructions.

See also  A Facebook food group comes together to make a cookbook

In such cases the compiler inserts padding between the function pointers and the promise object in the structure to ensure that the promise is correctly aligned. This variation in layout makes it much more difficult to determine what offset to look at for the next coroutine-frame address because it is type dependent; the debugger needs to know something about the layout of the promise type to be able to calculate the offset.

In theory we could look at the value of the resumeFn/destroyFn pointers to lookup the promise type that corresponds to the coroutine body in a translation table, but this would either require debug information or by modifying the compiler to encode this information in the binary. We cannot assume the availability of debug info, and modifying the compiler is a much larger project. Other approaches are possible, such as changing the ABI of coroutine-frames to eliminate the padding, but these also require compiler changes, and would make the implementation compiler dependent.

The approach we took instead is to insert a new `folly::AsyncStackFrame` data-structure as a member of the coroutine promise and use these to form an intrusive linked list of async frames. That is, a structure that looks something like this:

namespace folly { struct AsyncStackFrame { AsyncStackFrame* parentFrame; // other members... };
} 

that can then be added as a member to the coroutine promise objects:

Advertisement
free widgets for website
namespace folly::coro { class TaskPromiseBase { ... private: std::coroutine_handle<> continuation_; AsyncStackFrame asyncFrame_; ... }; 

Whenever we launch a child coroutine by co_awaiting it we can hook up that child coroutine’s AsyncStackFrame so that its parentFrame member points to the parent coroutine’s AsyncStackFrame object.

Using a separate data structure gives us a lot of flexibility in how we represent async-stack traces. It insulates the data structures from any dependence on compiler internals, and will allow us to reuse AsyncStackFrame objects for non-coroutine async operations in future. It comes at a small memory and run time cost as we now effectively have two pointers to the parent coroutine to store and maintain. This decision can be revisited in future if we later want to squeeze some more performance by making some of the previously mentioned compiler changes.

Now we have a way to represent a chain of async-frames that can be walked by a debugger without needing to know anything about the concrete promise type. In the next post in the series we will look at how to determine the return-address of a coroutine and how to use these data structures to hook coroutine frames into a chain at runtime.

To learn more about Facebook Open Source, visit our open source site, subscribe to our YouTube channel, or follow us on Twitter and Facebook.

Interested in working with open source technologies at Facebook? Check out our open source-related job postings on our career page.

Advertisement
free widgets for website

Facebook Developers

Continue Reading
Advertisement free widgets for website

FACEBOOK

Understanding Authorization Tokens and Access for the WhatsApp Business Platform

Published

on

By

understanding-authorization-tokens-and-access-for-the-whatsapp-business-platform

The WhatsApp Business Platform makes it easy to send WhatsApp messages to your customers and automate replies. Here, we’ll explore authentication using the Cloud API, hosted by Meta.

We’ll start with generating and using a temporary access token and then replace it with a permanent access token. This tutorial assumes you’re building a server-side application and won’t need additional steps to keep your WhatsApp application secrets securely stored.

Managing Access and Authorization Tokens

First, let’s review how to manage authorization tokens and safely access the API.

Prerequisites

Start by making sure you have a developer account on Meta for Developers. You’ll also need WhatsApp installed on a mobile device to send test messages to.

Creating an App

Before you can authenticate, you’ll need an application to authenticate you.

Advertisement
free widgets for website

Once you’re signed in, you see the Meta for Developers App Dashboard. Click Create App to get started.

Next, you’ll need to choose an app type. Choose Business.

After that, enter a display name for your application. If you have a business account to link to your app, select it. If not, don’t worry. The Meta for Developers platform creates a test business account you can use to experiment with the API. When done, click Create App.

Then, you’ll need to add products to your app. Scroll down until you see WhatsApp and click the Set up button:

Finally, choose an existing Meta Business Account or ask the platform to create a new one and click Continue:

Advertisement
free widgets for website

And with that, your app is created and ready to use. You’re automatically directed to the app’s dashboard.

Note that you have a temporary access token. For security reasons, the token expires in less than 24 hours. However, you can use it for now to test accessing the API. Later, we’ll cover how to generate a permanent access token that your server applications can use. Also, note your app’s phone number ID because you’ll need it soon.

See also  A Facebook food group comes together to make a cookbook

Click the dropdown under the To field, and then click Manage phone number list.

In the popup that appears, enter the phone number of a WhatsApp account to send test messages to.

Then, scroll further down the dashboard page and you’ll see an example curl call that looks similar to this:

Advertisement
free widgets for website
curl -i -X POST https://graph.facebook.com/v13.0//messages -H 'Authorization: Bearer ' -H 'Content-Type: application/json' -d '{ "messaging_product": "whatsapp", "to": "", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }'

Note that the Meta for Developers platform inserts your app’s phone number ID and access token instead of the and placeholders shown above. If you have curl installed, paste the command into your terminal and run it. You should receive a “hello world” message in WhatsApp on your test device.

If you’d prefer, you can convert the curl request into an HTTP request in your programming language by simply creating a POST request that sets the Authorization and Content-Type headers as shown above, including the JSON payload in the request body.

Since this post is about authentication, let’s focus on that. Notice that you’ve included your app’s access token in the Authorization header. For any request to the API, you must set the Authorization header to Bearer .

Remember that you must use your token instead of the placeholder. Using bearer tokens will be familiar if you’ve worked with JWT or OAuth2 tokens before. If you’ve never seen one before, a bearer token is essentially a random secret string that you, as the bearer of the token, can present to an API to prove you’re allowed to access it.

Failure to include this header causes the API to return a 401 Unauthorized response code.

Advertisement
free widgets for website

Creating a Permanent Access Token

Knowing that you need to use a bearer token in the Authorization header of an HTTP request is helpful, but it’s not enough. The only access token you’ve seen so far is temporary. Chances are that you want your app to access the API for more than 24 hours, so you need to generate a longer-lasting access token.

Fortunately, the Meta for Developers platform makes this easy. All you need to do is add a System User to your business account to obtain an access token you can use to continue accessing the API. To create a system user, do the following:

  • Go to Business Settings.

  • Select the business account your app is associated with.
  • Below Users, click System Users.
  • Click Add.
  • Name the system user, choose Admin as the user role, and click Create System User.
  • Select the whatsapp_business_messaging permission.
  • Click Generate New Token.
  • Copy and save your token.

Your access token is a random string of letters and numbers. Now, try re-running the earlier request using the token you just created instead of the temporary one:

curl -i -X POST https://graph.facebook.com/v13.0//messages -H 'Authorization: Bearer ' -H 'Content-Type: application/json' -d '{ "messaging_product": "whatsapp", "to": "", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }'

Your test device should receive a second hello message sent via the API.

Best Practices for Managing Access Tokens

It’s important to remember that you should never embed an App Access Token in a mobile or desktop application. These tokens are only for use in server-side applications that communicate with the API. Safeguard them the same way you would any other application secrets, like your database credentials, as anyone with your token has access to the API as your business.

If your application runs on a cloud services provider like AWS, Azure, GCP, or others, those platforms have tools to securely store app secrets. Alternatively there are freely-available secret stores like Vault or Conjur. While any of these options may work for you, it’s important to evaluate your options and choose what works best for your setup. At the very least, consider storing access tokens in environment variables and not in a database or a file where they’re easy to find during a data breach.

Advertisement
free widgets for website

Conclusion

In this post, you learned how to create a Meta for Developers app that leverages the WhatsApp Business Platform. You now know how the Cloud API’s bearer access tokens work, how to send an access token using an HTTP authorization header, and what happens if you send an invalid access token. You also understand the importance of keeping your access tokens safe since an access token allows an application to access a business’ WhatsApp messaging capabilities.

Why not try using the Cloud API, hosted by Meta if you’re considering building an app for your business to manage WhatsApp messaging? Now that you know how to obtain and use access tokens, you can use them to access any endpoint in the API.

First seen at developers.facebook.com

Continue Reading

FACEBOOK

Now people can share directly to Instagram Reels from some of their favorite apps

Published

on

By

now-people-can-share-directly-to-instagram-reels-from-some-of-their-favorite-apps

More people are creating, sharing and watching Reels than ever before. We’ve seen the creator community dive deeply into video content – and use it to connect with their communities. We’re running a limited alpha test that lets creators share video content directly from select integrated apps to Instagram Reels. Now, creators won’t be interrupted in their workflow, making it easier for them share share and express themselves on Reels.

“With the shift to video happening across almost all online platforms, our innovative tools and services empower creativity and fuel the creator economy and we are proud to be able to offer a powerful editing tool like Videoleap that allows seamless content creation, while partnering with companies like Meta to make sharing content that much easier.”- Zeev Farbman, CEO and co-founder of Lightricks.

Starting this month, creators can share short videos directly to Instagram Reels from some of their favorite apps, including Videoleap, Reface, Smule, VivaVideo, SNOW, B612, VITA and Zoomerang, with more coming soon. These apps and others also allow direct sharing to Facebook , which is available for any business with a registered Facebook App to use.

We hope to expand this test to more partners in 2023. If you’re interested in being a part of that beta program, please fill out this form and we will keep track of your submission. We do not currently have information to share about general availability of this integration.

Learn more here about sharing Stories and Reels to Facebook and Instagram and start building today.

Advertisement
free widgets for website

FAQs

Q. What is the difference between the Instagram Content Publishing API and Instagram Sharing to Reels?

See also  Facebook launches new Sensitive Content Control for Instagram

A: Sharing to Reels is different from the Instagram Content Publishing API, which allows Instagram Business accounts to schedule and publish posts to Instagram from third-party platforms. Sharing to Reels is specifically for mobile apps to display a ‘Share to Reels’ widget. The target audience for the Share to Reels widget is consumers, whereas the Content Publishing API is targeted towards businesses, including third-party publishing platforms such as Hootsuite and Sprout Social that consolidate sharing to social media platforms within their third-party app.

Q: Why is Instagram partnering with other apps?

A: Creators already use a variety of apps to create and edit videos before uploading them to Instagram Reels – now we’re making that experience faster and easier. We are currently doing a small test of an integration with mobile apps that creators know and love, with more coming soon.

Q: How can I share my video from another app to Reels on Instagram?

Advertisement
free widgets for website

A: How it works (Make sure to update the mobile app you’re using to see the new Share to Reels option):

  • Create and edit your video in one of our partner apps
  • Once your video is ready, tap share and then tap the Instagram Reels icon
  • You will enter the Instagram Camera, where you can customize your reel with audio, effects, Voiceover and stickers. Record any additional clips or swipe up to add an additional clip from your camera roll.
  • Tap ‘Next’ to add a caption, hashtag, location, tag others or use the paid partnerships label.
  • Tap ‘Share’. Your reel will be visible where you share reels today, depending on your privacy settings.
See also  A Facebook food group comes together to make a cookbook

Q: How were partners selected?

A. We are currently working with a small group of developers that focus on video creation and editing as early partners. We’ll continue to expand to apps with other types of creation experiences.

Q: When will other developers be able to access Sharing to Reels on Instagram?

A: We do not currently have a date for general availability, but are planning to expand further in 2023.

Q: Can you share to Facebook Reels from other apps?

Advertisement
free widgets for website

A: Yes, Facebook offers the ability for developers to integrate with Sharing to Reels. For more information on third-party sharing opportunities, check out our entire suite of sharing offerings .

First seen at developers.facebook.com

Continue Reading

FACEBOOK

What to know about Presto SQL query engine and PrestoCon

Published

on

By

what-to-know-about-presto-sql-query-engine-and-prestocon

The open source Presto SQL query engine is used by a diverse set of companies to navigate increasingly large data workflows. These companies are using Presto in support of e-commerce, cloud, security and other areas. Not only do many companies use Presto, but individuals from those companies are also active contributors to the Presto open source community.

In support of that community, Presto holds meetups around the world and has an annual conference, PrestoCon, where experts and contributors gather to exchange knowledge. This year’s PrestoCon, hosted by the Linux Foundation, takes place December 7-8 in Mountain View, CA. This blog post will explore some foundational elements of Presto and what to expect at this year’s PrestoCon.

What is Presto?

Presto is a distributed SQL query engine for data platform teams. Presto users can perform interactive queries on data where it lives using ANSI SQL across federated and diverse sources. Query engines allow data scientists and analysts to focus on building dashboards and utilizing BI tools so that data engineers can focus on storage and management, all while communicating through a unified connection layer.

In short, the scientist does not have to consider how or where data is stored, and the engineer does not have to optimize for every use case for the data sources they manage. You can learn more about Presto in a recent ELI5 video below.

Caption: Watch the video by clicking on the image above.

Advertisement
free widgets for website

Presto was developed to solve the problem of petabyte-scale, multi-source data queries taking hours or days to return. These resources and time constraints make real-time analysis impossible. Presto can return results from those same queries in less than a second in most cases, allowing for interactive data exploration.

See also  Amazon, Apple, Google, and Facebook sign public letter supporting voting rights

Not only is it highly scalable, but it’s also extensible, allowing you to build your own connector for any data source Presto does not already support. At a low level, Presto also supports a wide range of file types for query processing. Presto was open sourced by Meta and later donated to the Linux Foundation in September of 2019.

Here are some Presto resources for those who are new to the community:

What is PrestoCon?

PrestoCon is held annually in the Bay Area and hosted by the Linux Foundation. This year, the event takes place December 7-8 at the Computer History Museum. You can register here. Each year at PrestoCon, you can hear about the latest major evolutions of the platform, how different organizations use Presto and what plans the Technical Steering Committee has for Presto in the coming year.

Presto’s scalability is especially apparent as every year we hear from small startups, as well as industry leaders like Meta and Uber, who are using the Presto platform for different use cases, whether those are small or large. If you’re looking to contribute to open source, PrestoCon is a great opportunity for networking as well as hearing the vision that the Technical Steering Committee has for the project in the coming year.

Advertisement
free widgets for website

Explore what’s happening at PrestoCon 2022:

Where is Presto used?

Since its release in November of 2013, Presto has been used as an integral part of big data pipelines within Meta and other massive-scale companies, including Uber and Twitter.

The most common use case is connecting business intelligence tools to vast data sets within an organization. This enables crucial questions to be answered faster and data-driven decision-making can be more efficient.

How does Presto work?

First, a coordinator takes your statement and parses it into a query. The internal planner generates an optimized plan as a series of stages, which are further separated into tasks. Tasks are then assigned to workers to process in parallel.

Workers then use the relevant connector to pull data from the source.

Advertisement
free widgets for website

The output of each task is returned by the workers, until the stage is complete. The stage’s output is returned by the final worker towards the next stage, where another series of tasks must be executed.

The results of stages are combined, eventually returning the final result of the original statement to the coordinator, which then returns to the client.

How do I get involved?

To start using Presto, go to prestodb.io and click Get Started.

We would love for you to join the Presto Slack channel if you have any questions or need help. Visit the community page on the Presto website to see all the ways you can get involved and find other users and developers interested in Presto.

If you would like to contribute, go to the GitHub repository and read over the Contributors’ Guide.

Advertisement
free widgets for website

Where can I learn more?

To learn more about Presto, check out its website for installation guides, user guides, conference talks and samples.

Make sure you check out previous Presto talks, and attend the annual PrestoCon event if you are able to do so.

To learn more about Meta Open Source, visit our open source site, subscribe to our YouTube channel, or follow us on Twitter, Facebook and LinkedIn.

First seen at developers.facebook.com

Advertisement
free widgets for website
Continue Reading

Trending