在处理我的编译器时,我遇到了这个错误:
Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
Run Code Online (Sandbox Code Playgroud)
如何获取此处出现问题的详细信息?我从backtrace中知道它memcpy是导致它的一条线,但是我如何看待内存是如何对齐的?我怎么知道它应该如何对齐?
该项目是一个带有LLVM后端的编译器,使用Zend/PHP运行时和OCaml垃圾收集器,因此有很多问题可能出错.
我怀疑这一行是问题的一部分:
zend_string *str = (zend_string *)caml_alloc(ZEND_MM_ALIGNED_SIZE(_STR_HEADER_SIZE + len + 1), 0);
Run Code Online (Sandbox Code Playgroud)
其中caml_alloc分别pemalloc在Zend源代码.
在执行10,000个字符串连接时会发生段错误.这是valgrind的输出:
==7501== Invalid read of size 8
==7501== at 0x4C2F790: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7501== by 0x4D7E58: subsetphp_concat_function (bindings.c:160)
==7501== by 0x4D7F52: foo (llvm_test.s:21)
==7501== by 0x4D7FA9: main (llvm_test.s:60)
==7501== Address 0x61db938 is 2,660,600 bytes inside a block of size 3,936,288 free'd
==7501== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) …Run Code Online (Sandbox Code Playgroud) test.php为纯文本:
<?php
$x = "a";
echo $x;
Run Code Online (Sandbox Code Playgroud)
test.php作为操作码:
debian:~ php -d vld.active=1 -d vld.execute=0 -f test.php
Finding entry points
Branch analysis from position: 0
Return found
filename: /root/test.php
function name: (null)
number of ops: 5
compiled vars: !0 = $x
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 'a'
3 2 EXT_STMT
3 ECHO !0
4 4 > RETURN 1
branch: # 0; line: 2- 4; sop: 0; eop: 4
path #1: …Run Code Online (Sandbox Code Playgroud) 我正在尝试为个人项目创建PHP扩展.除了上面文章中的内容之外,我对zend_engine一无所知,而且我的C技能已经过时了10年,并且只是学术性的.所有这些都是说"如果我好像在问一个愚蠢的问题,我可能就是".
是否可以在我自己的扩展中调用其他PHP扩展中的函数,或者每个PHP扩展都被认为是孤岛,而没有深入了解系统的其他部分?如果这是可能的,这是常见做法还是坏主意™?
也就是说,我知道我可以用这样的东西返回一个字符串.
PHP_FUNCTION(hello_world)
{
char *str;
str = estrdup("Hello World");
RETURN_STRING(str, 0);
}
Run Code Online (Sandbox Code Playgroud)
我希望能够返回一个SimpleXML元素或一个DomDocument元素.谷歌搜索已经证明是困难的,因为扩展开发并没有那么多,并且有很多标准的PHP使用.
这是我用来绘制下面推断的代码及其输出:
class a {
public $var1;
public $var2;
}
$obj0 = new a;
var_dump($obj0);
class b {
public $var1;
public $var2;
public $var3;
}
$obj1 = new b;
var_dump($obj1);
$obj2 = new stdClass;
var_dump($obj2);
$obj3 = new stdClass;
var_dump($obj3);
$obj4 = new stdClass;
var_dump($obj4);
$obj5 = new stdClass;
var_dump($obj5);
var_dump(new stdClass);
$obj6 = new stdClass;
var_dump($obj6);
Run Code Online (Sandbox Code Playgroud)
输出:
object(a)#1 (2) {
["var1"]=> NULL
["var2"]=> NULL
}
object(b)#2 (3) {
["var1"]=> NULL
["var2"]=> NULL
["var3"]=> NULL
}
object(stdClass)#3 (0) {
}
object(stdClass)#4 …Run Code Online (Sandbox Code Playgroud) PHP文档不是很明确,只说明:
SplObjectStorage :: offsetExists 检查存储中是否存在对象.(PHP> = 5.3.0)
SplObjectStorage :: contains 检查存储是否包含提供的对象.(PHP> = 5.1.0)
这对我来说几乎是一回事.
问题:除了offsetExists仅在5.3.0中可用之外,2之间有什么区别?
我进行的小测试......
$s = new SplObjectStorage();
$o1 = new StdClass();
$o2 = new StdClass();
$o3 = "I'm not an object!";
$s->attach($o1);
var_dump($s->contains($o1));
var_dump($s->offsetExists($o1));
echo '<br>';
var_dump($s->contains($o2));
var_dump($s->offsetExists($o2));
echo '<br>';
var_dump($s->contains($o3));
var_dump($s->offsetExists($o3));
Run Code Online (Sandbox Code Playgroud)
输出:
boolean true
boolean true
boolean false
boolean false
Warning: SplObjectStorage::contains() expects parameter 1 to be object, string given in index.php on line 15
null
Warning: SplObjectStorage::offsetExists() expects parameter 1 to be …Run Code Online (Sandbox Code Playgroud) 在博客文章"PHP Internals:什么时候复制foreach"中,NikiC表示在这样的代码中:
片段1
$array = range(0, 100000);
foreach ($array as $key => $value) {
xdebug_debug_zval('array'); // array is not copied, only refcount is increased
}
Run Code Online (Sandbox Code Playgroud)
foreach不会复制数组,因为唯一foreach修改的$array是它的内部数组指针.
他还说在这样的代码中:
片段2
$array = range(0, 100000); // line 1
test($array);
function test($array) {
foreach ($array as $key => $value) { // line 4
xdebug_debug_zval('array'); // array is copied, refcount not increased
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
foreach将复制数组,因为如果没有,第$array1行中的变量将被更改.
然而,唯一foreach修改的$array是它的内部数组指针.那么为什么$array …
我想知道我班级中未使用的使用语句是否会影响我的php网站的性能?
php是否包括开始时或需要时的所有类?如果第二选择那么我认为它不会影响我的系统的性能.
例如:不使用使用语句'DbConnector'
use model\adapter\DbConnector;
Run Code Online (Sandbox Code Playgroud) PHP 5.6引入了hash_equals()用于安全比较密码哈希和防止定时攻击的功能.它的签名是:
bool hash_equals(string $known_string, string $user_string)
Run Code Online (Sandbox Code Playgroud)
如文档中所述,$known_string并且$user_string必须具有相同长度的函数才能有效防止定时攻击(否则,false立即返回,泄漏已知字符串的长度).
此外,文档说:
提供用户提供的字符串作为第二个参数而不是第一个参数非常重要.
我认为函数在其参数中不是对称的,这似乎不直观.
问题是:
这是函数源代码的摘录:
PHP_FUNCTION(hash_equals)
{
/* ... */
if (Z_STRLEN_P(known_zval) != Z_STRLEN_P(user_zval)) {
RETURN_FALSE;
}
/* ... */
/* This is security sensitive code. Do not optimize this for speed. */
for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
result |= known_str[j] ^ user_str[j];
}
RETURN_BOOL(0 == result);
}
Run Code Online (Sandbox Code Playgroud)
至于我,这两个论点的实现是完全对称的.可能产生任何影响的唯一操作是XOR运算符.
XOR运算符是否可能在非常量时间内执行,具体取决于参数值?可能它的执行时间取决于参数的顺序(例如,如果第一个参数为零)?
或者,PHP的文档中的这个注释是对未来版本中实现更改的"保留"吗?
PHP_FUNCTION(hash_compare) …Run Code Online (Sandbox Code Playgroud) php-internals ×10
php ×9
c ×4
apc ×1
arrays ×1
foreach ×1
ocaml ×1
performance ×1
php-opcode ×1
security ×1
spl ×1