EOSIO / eos

An open source smart contract platform
https://developers.eos.io/manuals/eos
MIT License
11.27k stars 3.6k forks source link

Native Contract Debugging #1847

Closed PaulCalabrese closed 4 years ago

PaulCalabrese commented 6 years ago

This task is to allow contracts to be compiled natively and debugged with a C++ debugger in nodeos.

This was previously worked under the JIRA-551. The existing work was functional on the branch DAWN-551-Contract-Debugging-Merge, but needs to be refactored to allow for the redesigned wasm_interface class.

From Paul: Investigate using native C++ debuggers to debug EOS contracts in a controlled environment. Develop a debugging approach and define the necessary work tasks.

I created a PR (https://github.com/EOSIO/eos/pull/1482) for review of my approach. Below are my implementation notes


What you need to do to debug a contract:

Add your contract cpp file to the debug_plugin's CMakeLists.txt Register handlers in the debug_plugin for each action Modify eosiod CMakeLists.txt to include debug_plugin Add the debug_plugin to your config.ini Start the eosiod node (in the debugger - set breakpoints as necessary) Create the account and do a "set contract" like you normally would (the wasm code will not be called because the native registrations in debug_plugin take precedence, but we still need the to set the contract in order to unpack the actions) Issue actions like you normally would Changes I had to make

Created a debug_plugin that will coordinate native contract debugging Contract code is compiled into the debug plugin using a relative path and the EOSIO_NATIVE_CONTRACT_COMPILATION flag I had to rename the "time" type to eosio_time in contracts/eosiolib/types.h and other places in contracts/eosiolib/ I had to conditionally compile some things in and out in eosiolib chain_controller::_set_apply_handler() had to become public I had to add alternate constructors for some types used by intrinsics (array_ptr, null_terminated_ptr, context_aware_api, context_free_transaction_api) I had to add native registration macros for each intrinsic. These macros define an extern "C" function with the same name as the intrinsic that calls the appropriate member function in the _api classes. I am working towards merging the two intrinsic registration (wasm and native) macros. Questions/Issues:

Should all my changes in libraries/chain and eosiod be conditionally compiled (so you would have to do a #define to enable native debugging) or should it always be available (at least in debug builds)? I can only natively debug one contract at a time (because each defines a global function called apply(), only one can exist in a C++ program). Is this limitation acceptable? Do we want some sort of script that automates setting up your contract for debugging (I think this can handle steps 1-3 above)? There are a number of intrinsics with issues such as no declaration in eosiolib and different numbers of parameters. I tried to call these out in comments. There are conflicts with certain intrinsics that have compiler-defined implementations. For some of these intrinsics (for example memcpy), I simply let the compiler-defined version take over. For others, such as abort and __divti3) I have commented them out because I cannot define my own definitions without conflicting with the compiler's version. I would like to rename the intrinsic names in some of these cases. Is this something we can do? There are lots of inconsistencies and issues with the intrinsic parameter and return value types. It would be nice to normalize these especially to limit the use of platform-dependent types such as int, size_t, etc. A type like int may represent a lot of different things (including pointers). In addition, one parameter may be referred to by different types in the declaration (in eosiolib), the intrinsic definition (macro), and *_api implementation function. There is very sparse testing for the intrinsic functions and what there is is difficult to perform with the "native" versions. I would like to see a more comprehensive set of intrinsic tests that would hopefully cover both wasm and native contracts. I am convinced that some of them have problems even in the wasm version. Is there someone working on intrinsic/api testing?

coreylederer commented 6 years ago

I've added Paul's updated description from JIRA.

brianjohnson5972 commented 5 years ago

@wanderingbort @heifner If we want to be able to use any of @PaulCalabrese work we need to plan to do something with this soon, otherwise it will be easier to start again, especially with the CDT changes.

brianjohnson5972 commented 5 years ago

@larryk85 I think I saw a telegram from you that sounded like you were working on a test bed for contracts, am I remembering correctly? If so, would this continue to be desired?

jgiszczak commented 4 years ago

OBE.

See CDT -fnative, available since CDT v1.6.0.