我所做的就是在脚本下运行:D:\ Tools\MongoDb\bin\mongod.exe --dbpath D:\ MongoDb\data\
然后我得到异常:连接到服务控制管理器时出错:访问被拒绝.(5)
我使用管理员帐户来操作它,我已经创建了与脚本相关的文件夹.
当我在32位Windows Server 2003中安装32位mongodb时,我没有遇到这样的问题.
我很感激任何帮助!
我正在研究应用程序(用C++编写),它在运行时生成一些机器代码(现在是Linux,x86-64,但我计划在ARM上进行迁移).接下来,它将生成的代码存储在内存中并通过跳转到内存位置来执行它.很长一段时间我都遇到了分配可执行内存的问题,但我终于解决了它:
uint8_t *memory = mmap (NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Run Code Online (Sandbox Code Playgroud)
到目前为止它的确有效,但我不确定它是否是做这些事情的优雅方式.我想知道可执行加载器是如何做到的
我试图理解GCC(4.4.3)为在Ubuntu Linux下运行的x86_64机器生成的可执行代码.特别是,我不明白代码如何跟踪堆栈帧.在过去,在32位代码中,我习惯于在几乎每个函数中看到这个"序幕":
push %ebp
movl %esp, %ebp
Run Code Online (Sandbox Code Playgroud)
然后,在功能结束时,也会出现"结局"
sub $xx, %esp # Where xx is a number based on GCC's accounting.
pop %ebp
ret
Run Code Online (Sandbox Code Playgroud)
或者干脆
leave
ret
Run Code Online (Sandbox Code Playgroud)
这完成了同样的事情:
在64位代码中,正如我通过objdump反汇编看到的那样,许多函数不遵循这个约定 - 它们不会推送%rbp然后将%rsp保存到%rbp,像GDB这样的调试器如何构建回溯?
我的真正目标是尝试找出一个合理的地址,当执行到达程序中的任意函数的开始时,可以将堆栈指针向下移动时作为用户堆栈的顶部(最高地址).例如,对于"top",argv的原始地址是理想的 - 但是我无法从主要调用的任意函数访问它.我一开始以为我可以使用旧的回溯方法:追踪保存的帧指针值,直到保存的值为0 - 然后,下一个可以算作最高实际值.(这与获取argv的地址不同,但它会 - 比如说,找出_start或任何_start调用的堆栈指针值[例如__libc_start_main].)现在,我不知道如何获得64位代码中的等效地址.
谢谢.
我使用gcc -S作为hello world程序.什么是5 .seh_命令?当我搜索时,我似乎无法找到关于它们的更多信息.
.file "hi.c"
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "Hello World\0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
leaq .LC0(%rip), %rcx
call puts
movl $0, %eax
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (rubenvb-4.8.0) 4.8.0"
.def puts; .scl 2; .type 32; .endef
Run Code Online (Sandbox Code Playgroud) 对于可能在x86或x86-x64系统上触发意外行为的交叉修改代码有哪些想法,其中一切都在交叉修改代码中正确完成,除了在执行处理器之前在执行处理器上执行序列化指令之外修改过代码?
如下所述,我有一个Core 2 Duo E6600处理器进行测试,明确提到它是一个容易出现问题的处理器.我会在这台机器上测试与我分享的任何想法并提供更新.
在x86和x64系统上,编写交叉修改代码的官方指南是执行以下操作:
; Action of Modifying Processor
Store modified code (as data) into code segment;
Memory_Flag ? 1;
; Action of Executing Processor
WHILE (Memory_Flag ? 1)
Wait for code to update;
ELIHW;
Execute serializing instruction; (* For example, CPUID instruction *)
Begin executing modified code;
Run Code Online (Sandbox Code Playgroud)
某些处理器的勘误表中明确提到了序列化指令.例如,Intel Core 2 Duo E6000系列有以下错误:(来自http://www.mathemainzel.info/files/intelX6800andintelE6000.pdf)
一个处理器或系统总线主控器将数据写入第二处理器的当前执行的代码段以使第二处理器将该数据作为代码执行的动作称为交叉修改代码(XMC).在执行新代码之前不强制第二处理器执行同步指令的XMC称为非同步XMC.
使用非同步XMC修改处理器的指令字节流的软件可以从执行修改代码的处理器看到意外或不可预测的执行行为.
如果在http://linux.kernel.narkive.com/FDc9TB0d/patch-linux-kernel-markers上没有使用序列化指令,可能会出现意外执行行为的原因:
当完成i-fetch并且微操作在跟踪高速缓存中时,原始机器指令边界和微操作之间不再存在直接关联.这是由于优化.例如(用于说明目的的人工):
mov eax,ebx
mov memory,eax
mov eax,1
(使用英特尔符号而不是ATT - 习惯的力量)
在跟踪缓存中,没有微操作可以使用ebx更新eax.
动态地将"mov eax,ebx"改为"mov ecx,ebx"会使优化的跟踪缓存无效,因此onlhy求助是一个GPF.如果修改不会使跟踪缓存无效,则不会使用GPF.问题是:"我们可以预测跟踪缓存未被无效的情况",并且由于微架构不公开,因此答案通常是否定的.但可以猜测,在中断指令(int3)中修改单字节操作码不会导致无法处理的不一致.这就是英特尔证实的.继续存储int3而不需要同步(即强制刷新跟踪缓存).
https://sourceware.org/ml/systemtap/2005-q3/msg00208.html上还有更多信息: …
我正在研究两个代码的输出,使用-fomit-frame-pointer和without(gcc at"-O3"默认启用该选项).
pushq %rbp
movq %rsp, %rbp
...
popq %rbp
Run Code Online (Sandbox Code Playgroud)
如果我全局禁用该选项,即使是在极端情况下编译操作系统,是否有一个问题?
我知道中断使用该信息,那么该选项仅适用于用户空间吗?
我尝试了解System V AMD64 的含义-ABI的调用约定并查看以下示例:
struct Vec3{
double x, y, z;
};
struct Vec3 do_something(void);
void use(struct Vec3 * out){
*out = do_something();
}
Run Code Online (Sandbox Code Playgroud)
甲Vec3-variable是型存储器的,因此调用者(use)必须返回的变量分配空间并把它传递为隐藏指针到被叫方(即,do_something)。这是我们在生成的汇编器中看到的(在godbolt上,使用编译-O2):
use:
pushq %rbx
movq %rdi, %rbx ;remember out
subq $32, %rsp ;memory for returned object
movq %rsp, %rdi ;hidden pointer to %rdi
call do_something
movdqu (%rsp), %xmm0 ;copy memory to out
movq 16(%rsp), %rax
movups %xmm0, (%rbx)
movq %rax, 16(%rbx)
addq $32, …Run Code Online (Sandbox Code Playgroud) 在玩 C# 时,我发现了以下代码段:
public int F()
{
try
{
return 0;
}
catch (Exception)
{
return -1;
}
}
Run Code Online (Sandbox Code Playgroud)
这将生成以下asm:
Program.F()
L0000: push ebp
L0001: mov ebp, esp
L0003: push esi
L0004: sub esp, 0x14
L0007: xor eax, eax
L0009: mov [ebp-0x18], eax
L000c: mov [ebp-0x14], eax
L000f: mov [ebp-0x10], eax
L0012: mov [ebp-0xc], eax
L0015: xor esi, esi
L0017: jmp short L0023
L0019: mov esi, 0xffffffff
L001e: call 0x6fb2d4d3
L0023: mov eax, esi
L0025: lea esp, [ebp-4] …Run Code Online (Sandbox Code Playgroud) 我有一个巨大的内存块(位向量),在一个内存页中大小为N位,考虑N平均为 5000,即 5k 位来存储一些标志信息。
在某个时间点(超级频繁 - 关键),我需要在整个大位向量中找到第一个位集。现在我每 64 个字都这样做,即在 ) 的帮助下__builtin_ctzll。但是当N增长并且搜索算法无法改进时,可以通过扩展内存访问宽度来扩展此搜索。这是几句话的主要问题
有一条被调用的汇编指令BSF 给出了最高设置位(GCC's __builtin_ctzll())的位置。因此,在x86-64 arch 中,我可以在 64 位字中廉价地找到最高位。
但是通过内存宽度进行缩放呢?
例如,有没有办法用 128 / 256 / 512 位寄存器有效地做到这一点?
基本上我对一些 C API 函数来实现这个感兴趣,但也想知道这个方法是基于什么的。
UPD:至于 CPU,我对这种优化感兴趣,以支持以下 CPU 阵容:
英特尔至强 E3-12XX、英特尔至强 E5-22XX/26XX/E56XX、英特尔酷睿 i3-5XX/4XXX/8XXX、英特尔酷睿 i5- 7XX、英特尔赛扬 G18XX/G49XX(英特尔凌动 N2600、英特尔赛扬 N2807、Cortex-A53/72 可选)
PS在最终位扫描之前提到的算法中,我需要将k(平均 20-40)个N位向量与 CPU AND相加(AND 结果只是位扫描的准备阶段)。这也适用于内存宽度缩放(即比每 64 位字 AND 更有效)
另请阅读:查找第一组
当我打破主要时,它看起来像粗线是我正在创建和初始化的地方.我想我错了,我正试图从一本解释x86的书中检查x86_64程序集.这看起来很奇怪,我很确定我只是不明白,因为在本书中他说他会将单词和双字称为4字节.如果我能得到一个解释来帮助我的认知,我将不胜感激.
__CODE__方法:http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-inject