New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eliminates run-time initialization of global variables (fixes race condition) #1171
Conversation
I think this PR is overkill, adding a dependency on |
Yes i think we can do better than introducing -pthread dependency. And we
should be threadsafe by default, not by choice.
|
I agree that the libpthread dependency is undesirable, but I'm not sure of an easy-to-maintain solution that will work on Unix-based platforms. Note: I am not a threading expert Safely doing a concurrent initialization is not actually simple. We could try to maintain our own " Using a mutex would also have the downsides described above. GNU libpthread Edit: GNU libpthread is LGPL, not GPL. There is no problem dynamic linking against LGPL code. |
In regards to being enabling If we end up dynamic linking against another library (such as pthread), then I do not think we should enable |
We could borrow code from FreeBSD's threading library: |
I got your point, but again, I think the philosophy is for capstone to work by default with thread. If including external library is what it takes, we may just do it; I don't think it is the case though. My take is that for generic stuff like Btw, this code is initially written using |
After thinking about this problem some more, I believe that we should dynamically link against libpthread: Note: I incorrectly stated above that GNU libpthread is GPL; it is actually LGPL licensed.
|
e5df533
to
e8941be
Compare
Instead of adding threading support, the latest update just declares the global variables with the correct values. No run-time initialization is required. |
Thanks! This new update is much nicer! I fully support it, @aquynh should take a look. Could you please add a note on how to regenerate the generated files using the python script ? Or maybe an option in makefile to re-generate them when needed. |
thank you for bringing back the sanity
… On 13 Jun 2018, at 19:03, Travis Finkenauer ***@***.***> wrote:
Instead of adding threading support, the latest update just declares the global variables with the correct values. No run-time initialization is required.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub <#1171 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AA3-lq6Fs8OaTdax1t2N7tQXbaYjcRbJks5t8UXTgaJpZM4UhKu9>.
|
generate_cs_arch_globals.py
Outdated
|
||
HEADER = """ | ||
/* Capstone Disassembly Engine */ | ||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, {year} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, this is for auto-generated file, not created by me ;-)
to credit, please add your name into this new file (generate_cs_arch_globals.py) if you want that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, done.
I don't trust myself to update the |
you should be using atomic bool compiler intrisics to just set the flag (or std::atomic if you want to go to c++ land |
@tmfink can we make this @stevemk14ebr well, |
every compiler has an intrinisic for a fetch, just named different. Why in the world would you prefer a whole script to run at compiler time when you can just use 4 or 5 ifdefs and a global. Use the simple tool for the simple problem |
It's not "a whole script to run at compiler time", the file is generated once not while compiling. It is also saving runtime cycles, and simple enough to understand, bullet-proof regarding thread-safe.
Why don't you submit a PR so we can judge ? It could be only my personal opinion without seeing the actual alternative. |
I'm here to suggest alternative and simpler designs, out of band source generation should be reserved for features that cannot be implemented in pure C, which it can be imho. I'm not writing any code for this project until previous time I invested is merged: #520 (just to explain why since you asked) |
@stevemk14ebr :) thanks for the contribution, though I don't understand why you bring that PR here, it has nothing to do with this, and I also didn't ask for it. To avoid dragging this off-topic, I'm done with my argument, should hear from others. |
@danghvu That would work but would be kinda ugly. Semantically, the We can let @aquynh decide how to proceed here. |
@stevemk14ebr I think that doing the compile-time initialization is preferable because:
An alternative (that I considered) was to not include the Python script. The |
i am travelling, sorry it will take a bit longer to review this. but personally i prefer compiler independent solution, so we dont need to update the code to support new compilers in the future. |
great work, @tmfink! the remaining work is to add cs_arch_globals.c msvc/ & xcode/, so they dont break. can you do that, or need helps? |
Thanks @aquynh. I think I need help with the xcode/msvc projects. Maintainers should be able to commit to |
looking again at this, here is my thoughts:
|
@aquynh I can do that. I originally decided not to paste the globals into |
I pushed the changes and updated the first comment. |
arch/AArch64/AArch64Module.h
Outdated
@@ -0,0 +1,13 @@ | |||
/* Capstone Disassembly Engine */ | |||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2018 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now could you put your name here (and all other .h files), instead of mine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented. I should really learn my name and email at this point...
|
||
unsigned int all_arch = 0; | ||
unsigned int all_arch = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will break if ARM is not enabled, because in that case we have all_arch = | ...
.
to fix this, we can put 0
in front of it (so all_arch = 0 | ...
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually works since the #else
case puts in a 0
.
The bitwise OR (|
) operators are not inside the #ifdef ... #endif
.
My build tests seem to confirm:
$ CAPSTONE_ARCHS=powerpc make -j
CC cs.o
CC utils.o
CC SStream.o
CC MCInstrDesc.o
CC MCRegisterInfo.o
CC arch/PowerPC/PPCInstPrinter.o
CC arch/PowerPC/PPCDisassembler.o
GEN capstone.pc
CC arch/PowerPC/PPCMapping.o
CC arch/PowerPC/PPCModule.o
CC MCInst.o
LINK libcapstone.so
AR libcapstone.a
ar: creating ./libcapstone.a
make[1]: Entering directory 'capstone/cstool'
CC cstool_x86.o
CC cstool_arm64.o
CC cstool_sparc.o
CC cstool_ppc.o
CC cstool_xcore.o
CC cstool_arm.o
CC cstool_systemz.o
CC cstool_mips.o
CC cstool.o
LINK cstool
make[1]: Leaving directory 'capstone/cstool'
make -C tests
make[1]: Entering directory 'capstone/tests'
CC test_basic.o
CC test_detail.o
CC test_iter.o
CC test_ppc.o
CC test_skipdata.o
LINK test_basic
LINK test_detail
LINK test_skipdata
LINK test_iter
LINK test_ppc
LINK test_detail.static
LINK test_iter.static
LINK test_basic.static
LINK test_skipdata.static
LINK test_ppc.static
make[1]: Leaving directory 'capstone/tests'
install -m0755 ./libcapstone.so ./tests/
cd ./tests/ && mv libcapstone.so libcapstone.so.3 && ln -s libcapstone.so.3 libcapstone.so
$ ./tests/test_ppc
****************
Platform: PPC-64
Code:0x43 0x20 0x0c 0x07 0x41 0x56 0xff 0x17 0x80 0x20 0x00 0x00 0x80 0x3f 0x00 0x00 0x10 0x43 0x23 0x0e 0xd0 0x44 0x00 0x80 0x4c 0x43 0x22 0x02 0x2d 0x03 0x00 0x80 0x7c 0x43 0x20 0x14 0x7c 0x43 0x20 0x93 0x4f 0x20 0x00 0x21 0x4c 0xc8 0x00 0x21 0x40 0x82 0x00 0x14
Disasm:
0x1000: bdnzla+ 0xc04
op_count: 1
operands[0].type: IMM = 0xc04
Branch hint: 1
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops you are right, i missed that 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or without the #else
all_arch = 0
#ifdef CAPSTONE_HAS_ARM
| (1 << CS_ARCH_ARM)
#endif
#ifdef CAPSTONE_HAS_ARM64
| (1 << CS_ARCH_ARM64)
#endif
...
which saves a bit of space, not a big deal though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes i would do that too, but this is also OK
cs.c
Outdated
#else | ||
0 | ||
#endif | ||
; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please fix this indentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I adjusted the ;
indent.
I purposely left the ;
indented before but I suppose that it is clear already.
This eliminates the need for archs_enable() and eliminates the racey initialization. This makes the architecture-specific init, option, and destroy functions non-static so that they may be called from a different file.
I considered doing that before but figured this would be easier to read.
I did not want to special case the first architecture (by not using the OR
operator) or use the '0' constant.
…On Thu, Jun 21, 2018, 00:28 danghvu ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In cs.c
<#1171 (comment)>:
>
-unsigned int all_arch = 0;
+unsigned int all_arch =
or without the #else
all_arch = 0
#ifdef CAPSTONE_HAS_ARM
| (1 << CS_ARCH_ARM)
#endif
#ifdef CAPSTONE_HAS_ARM64
| (1 << CS_ARCH_ARM64)
#endif
...
which saves a bit of space, not a big deal though.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1171 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AFBYuAJ1Ct9Td6t9K8ZZFyR-twSKk1Ykks5t-yDigaJpZM4UhKu9>
.
|
merged, thanks! now could you port this to the next branch, too? |
Sure. |
This eliminates the need for archs_enable() and eliminates the racey initialization. This makes the architecture-specific init and option functions non-static so that they may be called from a different file. Cherry-picked 853a287
* Declare global arch arrays with contents (#1171) This eliminates the need for archs_enable() and eliminates the racey initialization. This makes the architecture-specific init and option functions non-static so that they may be called from a different file. Cherry-picked 853a287 * Add cs_arch_disallowed_mode_mask global Cherry-pick 94bce43: mips: CS_MODE_MIPS32R6 implies CS_MODE_32 Cherry-pick 8998a3a: ppc: fix endian check (#1029) Fixes bug where endianness could not be set for ppc. Remove `big_endian` field of `cs_struct`. Added a helper macro `MODE_IS_BIG_ENDIAN()` to check if `CS_MODE_BIG_ENDIAN` is set. Refactored `cs_open()` check for valid mode out of arch-specific code into arch-independent code. Also added a valid mode check to `cs_option()`. The checks use a new global array `cs_arch_disallowed_mode_mask[]`. * Make global arrays static Make all_arch uint32_t to guarantee a certain number of bits (with adequate room for growth).
FYI, the scripts I used to generate code: |
Declare global arch arrays with contents.
This eliminates the need for archs_enable() and eliminates the racey
initialization.
Fixes #1168.
Progress: