json-tutorial icon indicating copy to clipboard operation
json-tutorial copied to clipboard

tutorial07, ubuntu下,c->top溢出,导致程序死循环

Open Neal-Yi opened this issue 8 years ago • 4 comments

语句: c->top -= 32 - sprintf(lept_context_push(c, 32), "%.17g", v->u.n);

执行前c->top=0; 执行后c->top=18xxxxxxxxx(一个很大的值);该值为2^64左右,判断其是以0 - 1 所得,c->top提前压入栈,而非执行lept_context_push后的值。 改为冗长的写法后正常工作,sprintf返回值为1。gcc版本为4.8.4,猜测与编译器有很大关系

Neal-Yi avatar Feb 21 '17 15:02 Neal-Yi

同样问题同样现象,那个很大的值应该是64位系统中size_t的0减去31的结果:18446744073709551585. 可能处理过程是这样的: c->top -= 32 - func() ;此时c-> top == 0 c->top = c->top - (32 - func()) ;此时c->top被某寄存器(say A)缓存值为0,func执行中c->top值改变为32 c->top = A - (32 - 1) ;寄存器A值未更新(bug),func返回1 c->top = 0 - 31 ;结果

lengzizgnel avatar Mar 16 '17 08:03 lengzizgnel

一点疑问,如果是因为编译器优化把 c->top 缓存到寄存器了,那我将 c->top 修饰为 volatile 应该是可以解决这个问题的。但经过验证,仍然出现这个问题。gcc版本为4.8.4

zyc737347123 avatar Nov 13 '17 01:11 zyc737347123

这种写法依赖求值次序吧

Syopain avatar Jun 23 '18 08:06 Syopain

同样的问题,但不清楚为何编译作者的程序是可以通过的。当改了作者tutorial07_answer/CMakeLists.txt中的编译选项后,也能够复现了。 修改情况如下:

@@ -2,7 +2,8 @@ cmake_minimum_required (VERSION 2.6)
 project (leptjson_test C)
 
 if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi -pedantic -Wall")
+    # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi -pedantic -Wall")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
 endif()
 
 add_library(leptjson leptjson.c)

robin-vip avatar Dec 04 '21 12:12 robin-vip