小编Chr*_*ris的帖子

Makefile`echo -n'不起作用

我试图让我的Makefile回显文本没有尾随的新行,但我无法.我正在体验OS X上的行为(在Linux上,一切都按预期工作).

Makefile文件

a:
    @echo -n "hello"

b:
    @echo -n hello

c:
    @/bin/echo -n "hello"
Run Code Online (Sandbox Code Playgroud)

输出:

$make a
-n hello
$make b
hello$make c
hello$
Run Code Online (Sandbox Code Playgroud)

换句话说,它make a被打破了.究竟发生了什么?是使用内置回声吗?很明显,双引号的存在改变了行为,但为什么呢?

更新

正如@chepner所发现的那样,使用/bin/echomakefile中的完整路径正确理解-n标志.

bash makefile echo

27
推荐指数
2
解决办法
2万
查看次数

使用自修改代码观察在x86上获取过时的指令

我被告知并且从英特尔的手册中读到可以将指令写入内存,但是指令预取队列已经获取了陈旧的指令并将执行那些旧的指令.我没有成功观察到这种行为.我的方法如下.

英特尔软件开发手册从第11.6节开始说明

对当前在处理器中高速缓存的代码段中的存储器位置的写入导致相关联的高速缓存行(或多个行)无效.此检查基于指令的物理地址.此外,P6系列和奔腾处理器检查对代码段的写入是否可以修改已经预取执行的指令.如果写入影响预取指令,则预取队列无效.后一种检查基于指令的线性地址.

所以,看起来如果我希望执行陈旧的指令,我需要有两个不同的线性地址引用相同的物理页面.所以,我将内存映射到两个不同的地址.

int fd = open("code_area", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
assert(fd>=0);
write(fd, zeros, 0x1000);
uint8_t *a1 = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_FILE | MAP_SHARED, fd, 0);
uint8_t *a2 = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_FILE | MAP_SHARED, fd, 0);
assert(a1 != a2);
Run Code Online (Sandbox Code Playgroud)

我有一个汇编函数,它接受一个参数,一个指向我想要更改的指令的指针.

fun:
    push %rbp
    mov %rsp, %rbp

    xorq %rax, %rax # Return value 0

# A far jump simulated with a far return
# Push the …
Run Code Online (Sandbox Code Playgroud)

c x86 caching self-modifying

23
推荐指数
3
解决办法
2563
查看次数

模板化C++对象文件

假设我有两个.cpp文件,file1.cpp和file2.cpp,它们都使用std::vector<int>.假设file1.cpp有一个int main(void).如果我将两者编译成file1.o和file2.o,并将两个目标文件链接到我可以执行的elf二进制文件中.我正在编译32位Ubuntu Linux机器.

我的问题是关于编译器和链接器如何将std :: vector的符号放在一起:

  • 当链接器生成我的最终二进制文件时,是否存在代码重复?链接器是否有一组"模板化"代码用于f1.o中使用std::vectorstd::vector代码和另一组代码用于包含f2.o的代码?

我为自己尝试了这个(我用过g++ -g),然后我查看了我的最终可执行文件反汇编,我发现为向量构造函数和其他方法生成的标签显然是随机的,尽管来自f1.o的代码似乎调用了相同的构造函数.来自f2.o的代码.但是,我无法确定.

如果链接器确实阻止了代码重复,它是如何做到的?它必须"知道"什么模板?它是否始终阻止关于跨多个目标文件多次使用相同模板化代码的代码重复?

c++ templates g++ ld

9
推荐指数
1
解决办法
1453
查看次数

Javascript自动释放资源(如RAII)

我的一般问题是我可以使用哪些技术来确保在Javascript中清理/释放资源?目前,我正在采用C(不使用goto)方法来查找函数中返回或异常的每个执行路径,并确保进行清理.

我的具体示例如下:在Node.js中我在对象成员函数中使用互斥(通过文件锁)(我需要互斥,因为我运行Node.js应用程序的多个实例,并且当不同实例与之交互时具有竞争条件文件系统).

例如,在C++中,我会做类似以下的事情:

void MyClass::dangerous(void) {
     MyLock lock(&this->mutex);
     ...
     // at the end of this function, lock will be destructed and release this->mutex.
}
Run Code Online (Sandbox Code Playgroud)

据我所知,JavaScript不提供任何RAII功能.在C中,我会使用gotos在发生错误时展开我的资源分配,这样我只有一个函数的返回路径.

在Javascript中实现类似效果的一些技巧是什么?

javascript raii

9
推荐指数
1
解决办法
1308
查看次数

autoreconf清理

我用来autoreconf --install为我的项目生成配置脚本等.是否有"清理"选项,或其他一些简单的方法来清理autoreconf生成的文件?使用生成的Makefile configure,我可以做一个make distclean,但我想通过删除Makefile.in等文件来进一步清理我的目录.

autotools

8
推荐指数
1
解决办法
5927
查看次数

Linux内核使TLB条目无效

在linux内核中,我编写了类似于copy_page_range(mm/memory.c)的代码,因此通过COW优化将内存从一个进程复制到另一个进程.目标和源地址可以抵消PAGE_SIZE,COW仍然有效.但是,我注意到,在用户程序中,当我从相同的源地址复制到不同的目标地址时,TLB似乎没有被正确刷新.在高级别,我的用户级代码执行以下操作(我一次只复制一页,我的机器上的0x1000字节):

SRC = 0x20000000

  1. 写入SRC(调用关联页面page1).
  2. Syscall将SRC复制到目标进程中的0x30000000.现在,src进程地址0x20000000和目标进程地址0x30000000指向同一页面(page1).
  3. 写一些与SRC不同的东西(这应该触发页面错误来处理COW).假设源地址现在指向page2.
  4. Syscall将SRC复制到目标进程中的0x30001000.

此时,应存在两个单独的页面:SRC 0x20000000 page2 DST 0x30000000 page1 DST 0x30001000page2

我发现在第3步,当我在src 0x20000000中写入不同的内容时,不会生成页面错误.检查时,实际页面映射为:SRC 0x20000000 page1 DST 0x30000000 page1 DST 0x30001000page1

在我的代码中,如果我调用flush_tlb_page并传递源地址,则用户代码将按预期使用正确的页面映射.所以我确信我没有正确维护TLB.在copy_page_range,内核调用mmu_notifier_invalidate_range_start/end之前和之后它改变页表.我正在做完全相同的事情,并进行了双重检查我确实传递了正确的struct_mm和地址mmu_notifier_invalidate_range_start/end.这个功能不能处理冲洗tlb吗?

好了,从字面上我打完这个,我查了一下dup_mmap,意识到的主要调用者copy_page_range,dup_mmap(核心/ fork.c),调用flush_tlb_mm.我猜我应该打电话flush_cache_rangeflush_tlb_range之前和之后我的内核代码.它是否正确?到底是mmu_notifier_invalidate_range_start/end做什么的?

c caching linux-kernel tlb

7
推荐指数
1
解决办法
2153
查看次数

返回函数指针返回相同类型的函数

在C中,我如何声明一个返回函数返回函数等的函数.即,我想要这样的东西

typedef A (*A)();
A a = ...
a()()()()();
Run Code Online (Sandbox Code Playgroud)

我想实现以下C++行为:

struct A { A operator()() { return A(); } };
A a;
a()()()()();
Run Code Online (Sandbox Code Playgroud)

c function-pointers

6
推荐指数
1
解决办法
1102
查看次数

vm_flags vs vm_page_prot

我与Linux内核2.6.38工作,有一个关于的两个领域的问题vm_area_struct,vm_flagsvm_page_prot.如果我将私有匿名内存vm_flags映射为可读写,然后打印出创建的vm_area_struct的两个字段,我看到低8位是0x73,低8位vm_page_prot是0x25.我正在运行x86 32位,我的常量是

VM_READ=0x01
VM_WRITE=0x02
VM_EXEC=0x04
Run Code Online (Sandbox Code Playgroud)

因此,看来我的vm_flags说内存是读/写但vm_page_prot说它只是可读的(可执行标志在x86上没有意义).我的理解是vm_page_prot应该反映对VM区域中页面的页表条目的保护.当我进入用户空间的mmaped区域中的读/写内存时,页面错误机制正常工作,设置适当页面的PTE.某些页面(如果我只读取它们)被映射到特殊的零页面框架,PTE设置为只读,而其他页面被写入以将PTE设置为读/写.这是预期的行为......事实上,从mm/memory.c:

static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
    unsigned long address, pte_t *page_table, pmd_t *pmd,
    unsigned int flags)
{
    ...
    entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), vma->vm_page_prot));
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是什么决定vm_page_prot.我的猜测是,vm_page_prot某种程度上是VM区域内所有页面权限的最严格的组合(交集),而vm_flags实际上描述了内存应该如何行动的真实意图.

有没有人对这两个领域的确切目的/差异有什么好的文章?

linux linux-kernel

4
推荐指数
1
解决办法
4799
查看次数

Maven从最终WAR中排除文件

我正在使用Maven 3打包WAR文件,我无法弄清楚如何src/main/webapp从生成的最终WAR中排除文件.其中一个目录src/main/webapp是一个git子模块,我想在那个git子模块表单中排除像README,docs /等文件到我的最终WAR.

我最初的尝试是使用maven-antrun-plugin删除文件.我在prepare-package和中尝试了删除操作package,但都没有奏效.执行删除package操作从我的文件中删除了文件target/<projname>/...,但最终的WAR仍然包含文件.运行maven并-debug显示生成WAR文件删除文件.这是几乎一样,如果我想要做的删除之间prepare-packagepackage.

我的下一次尝试是尝试指定要从WAR中排除的文件(下面链接的一些解决方案),但似乎没有任何效果.我可能没有正确指定不需要的文件的路径,我想知道它是否与我的不需要的文件不在src/main/resources,但在src/main/webapp.

我尝试了很多解决方案,但似乎没有任何效果.每次我尝试新的东西,我都会mvn clean删除target目录.最终生成的WAR文件始终包含不需要的文件.

我觉得我的问题的答案存在于我遇到的SO和谷歌搜索中,但我尝试过的任何东西都完全按照我的需要工作.以下是我尝试过的一些解决方案.

war maven

3
推荐指数
1
解决办法
3039
查看次数

x86_64程序集约定保存参数寄存器

我正在编写一些x86_64程序集来调用C函数.我的C函数接受1个参数,因此程序集将参数放入%rdi.ABI pdf(下面链接)表示其他6个参数寄存器(rsi,rdx,rcx,r8,r9)不会在函数调用中保留.但是,由于我的C函数只接受一个long参数,我是否可以保证C函数是否会破坏其他5个寄存器?我的假设是,如果参数的值发生了变化,那么参数寄存器只会被破坏:

void foo(int a, int b) {
    a++; /* %rdi will be changed, but %rsi won't be changed when control returns. */
}
Run Code Online (Sandbox Code Playgroud)

我问,因为我想在我的C函数调用中保留其他5个参数寄存器的值(无需手动显式地从堆栈中推送/弹出它们).

x86_64 ABI - http://www.x86-64.org/documentation/abi-0.99.pdf

c assembly x86-64

2
推荐指数
2
解决办法
3788
查看次数